package com.gustz.dove.cli.api.message.service.impl; import java.io.Serializable; import java.net.URLEncoder; import java.util.Date; import com.gustz.dove.cli.api.security.service.wxaes.WXBizMsgCrypt; import com.gustz.dove.cli.api.service.impl.AbstBaseService; import com.gustz.dove.cli.api.service.util.AESCodec; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.FastDateFormat; import org.dom4j.Document; import org.dom4j.Node; import org.springframework.beans.factory.annotation.Autowired; import com.gustz.dove.cli.api.app.vo.ClientAppVo; import com.sinovatech.rd.wcsb.cli.api.message.req.MsgBaseReq; import com.sinovatech.rd.wcsb.cli.api.message.service.MessageService; import com.sinovatech.rd.wcsb.cli.api.security.service.EncryptService; import com.sinovatech.rd.wcsb.cli.api.service.BaseWebsUrl; import com.gustz.dove.cli.api.service.util.AppLogStyle; import com.sinovatech.rd.wcsb.cli.api.service.util.CliAppHelper; import com.gustz.dove.cli.api.service.util.ClientConstants; /** * * TODO: 消息处理服务的接口实现 * * @author ZHENFENG ZHANG * @since [ Aug 3, 2015 ] */ public abstract class MessageServiceImpl extends AbstBaseService<Serializable> implements MessageService { @Autowired private EncryptService encryptService; /** * 解密消息 * * @param appVo * @param msgSignature * @param timestamp * @param nonce * @param doc * @return * @throws Exception */ protected String decryptMsg(ClientAppVo appVo, String msgSignature, String timestamp, String nonce, Document doc) throws Exception { try { final String cliAppCode = appVo.getCliAppCode(); final String devAcCode = appVo.getAccountCode(); final String wecAppId = appVo.getWecAppId(); // final String devToken = encryptService.getDevToken(devAcCode, wecAppId); final String devAesKey = encryptService.getDevAesKeyt(cliAppCode, devAcCode, wecAppId); // WXBizMsgCrypt msgCrypt = new WXBizMsgCrypt(devToken, devAesKey, appVo.getWecAppId()); // 执行解密 String postData = doc.selectSingleNode(MsgBaseReq.ENCRYPT_XPATH).getText(); return msgCrypt.decryptMsg(msgSignature, timestamp, nonce, postData); } catch (Exception e) { throw e; } } /** * 本地的加密消息 * * @param postData * @param oauthCbUrl * @return * @throws Exception */ protected String localEncryptMsg(String postData, String oauthCbUrl) throws Exception { // 执行本地加密 final String cbUrl = BaseWebsUrl.OAUTH_CBURL_KEY_EXT + oauthCbUrl; // final String today = FastDateFormat.getInstance(CliAppHelper.TODAY_PATT).format(new Date()); return URLEncoder.encode(AESCodec.encrypt(("$" + today + "¥"), postData + cbUrl), ClientConstants.CHARSET.name()); } @Override protected void setAccessTokenX(long sn, String cliAppCode, String devAcCode) { // ignored } /** * 校验消息发送/接收者 * * @param appLogs * @param prefixText * @param userName * @return */ protected boolean hasUserName(AppLogStyle appLogs, String prefixText, String userName) { // 账号 if (StringUtils.isBlank(userName)) { appLogs.runtimeWarn(String.format(prefixText + "[ %1$s ]不存在 ", userName)); return false; } return true; } /** * 校验客户端APP * * @param appLogs * @param prefixText * @param clientAppVo * @param toUserName * @return */ protected boolean hasClientApp(AppLogStyle appLogs, String prefixText, ClientAppVo clientAppVo, String toUserName) { // 客户端APP if (clientAppVo == null || StringUtils.isBlank(clientAppVo.getReceiveUrl())) { appLogs.runtimeWarn(String.format(prefixText + "[ %1$s ],接入的客户端不存在 ", toUserName)); return false; } return true; } /** * 校验客户端APP返回信息 * * @param appLogs * @param clientAppVo * @param fromUserName * @param newPostData * @return */ protected boolean hasSendToCliApp(AppLogStyle appLogs, ClientAppVo clientAppVo, String fromUserName, String newPostData) { // 执行发送 String _rspVal = this.httpPost(clientAppVo.getReceiveUrl(), System.currentTimeMillis(), clientAppVo.getCliAppCode(), newPostData); if (!fromUserName.equals(_rspVal)) { appLogs.runtimeWarn(String.format("接收客户端返回信息[ %1$s ]与原信息[ %2$s ]不匹配", _rspVal, fromUserName)); return false; } return true; } /** * 自动回复消息 * * @param clientAppVo * @param doc */ @Deprecated protected void doAutoReplyMsg(ClientAppVo clientAppVo, Document doc) { if (ClientConstants.YES.equals(clientAppVo.getIsReplyMsg())) { // 事件类型 Node _node = doc.selectSingleNode(MsgBaseReq.EVENT_TYPE_XPATH); if (_node != null) { // 消息来源 final String _fromUserName = doc.selectSingleNode(MsgBaseReq.FROM_USER_NAME_XPATH).getText(); // 接收者 final String _toUserName = doc.selectSingleNode(MsgBaseReq.TO_USER_NAME_XPATH).getText(); // TODO this.autoReplyMsg(_node.getText(), _fromUserName, _toUserName, clientAppVo.getCliAppCode(), "临时消息文本"); } } } }