From 2ff4c4eb7b04e37074164063fdd9f78ae8f93467 Mon Sep 17 00:00:00 2001 From: gazebo Date: Sat, 9 Mar 2019 12:51:33 +0800 Subject: [PATCH] - dingding callback func --- platformapi/dingdingapi/callback.go | 85 ++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/platformapi/dingdingapi/callback.go b/platformapi/dingdingapi/callback.go index c8161854..1805cd88 100644 --- a/platformapi/dingdingapi/callback.go +++ b/platformapi/dingdingapi/callback.go @@ -3,12 +3,15 @@ package dingdingapi import ( "crypto/sha1" "encoding/base64" + "errors" "fmt" "sort" "strings" "time" + "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/utils" + "github.com/fatih/structs" ) const ( @@ -21,8 +24,23 @@ const ( const ( KeyMsgSignature = "msg_signature" + SuccessResponse = "success" ) +type CallbackResponse struct { + MsgSignature string `json:"msg_signature"` + Timestamp string `json:"timeStamp"` + Nonce string `json:"nonce"` + Encrypt string `json:"encrypt"` +} + +func (a *API) Err2CallbackResponse(err error) *CallbackResponse { + if err == nil { + return a.PackCallbackResult(SuccessResponse) + } + return a.PackCallbackResult(err.Error()) +} + func (a *API) GetCallbackToken() string { a.locker.RLock() defer a.locker.RUnlock() @@ -35,17 +53,17 @@ func (a *API) GetCallbackAESKey() []byte { return a.callbackAESKey } -func (a *API) PackCallbackResult(result string) (resultMap map[string]interface{}) { +func (a *API) PackCallbackResult(result string) (response *CallbackResponse) { encryptedResult, err := a.Encrypt(result) if err == nil { - resultMap = map[string]interface{}{ - "encrypt": encryptedResult, - "timeStamp": utils.Int64ToStr(time.Now().Unix()), - "nonce": utils.GetUUID(), + response = &CallbackResponse{ + Encrypt: encryptedResult, + Timestamp: utils.Int64ToStr(time.Now().Unix()), + Nonce: utils.GetUUID(), } - resultMap["msg_signature"] = a.calculateCallbackSign(resultMap) + response.MsgSignature = a.calculateCallbackSign(structs.Map(response)) } - return resultMap + return response } func (a *API) calculateCallbackSign(data map[string]interface{}) (sign string) { @@ -81,6 +99,13 @@ func (a *API) Decrypt(msg string) (decryptedMsg string, err error) { } func (a *API) RegisterCallback(callbackTagList []string, token, aesKey, urlStr string) (err error) { + a.locker.Lock() + oldCallbackToken := a.callbackToken + oldCallbackAESKey := a.callbackAESKey + a.callbackToken = token + a.callbackAESKey, _ = base64.StdEncoding.DecodeString(aesKey + "=") + a.locker.Unlock() + if len(callbackTagList) > 0 { // 为0做测试用 _, err = a.AccessAPI("call_back/register_call_back", nil, map[string]interface{}{ "call_back_tag": callbackTagList, @@ -89,11 +114,11 @@ func (a *API) RegisterCallback(callbackTagList []string, token, aesKey, urlStr s "url": urlStr, }) } - if err == nil { + if err != nil { a.locker.Lock() defer a.locker.Unlock() - a.callbackToken = token - a.callbackAESKey, _ = base64.StdEncoding.DecodeString(aesKey + "=") + a.callbackToken = oldCallbackToken + a.callbackAESKey = oldCallbackAESKey } return err } @@ -107,6 +132,13 @@ func (a *API) GetCallback() (callbackInfo map[string]interface{}, err error) { } func (a *API) UpdateCallback(callbackTagList []string, token, aesKey, urlStr string) (err error) { + a.locker.Lock() + oldCallbackToken := a.callbackToken + oldCallbackAESKey := a.callbackAESKey + a.callbackToken = token + a.callbackAESKey, _ = base64.StdEncoding.DecodeString(aesKey + "=") + a.locker.Unlock() + if len(callbackTagList) > 0 { // 为0做测试用 _, err = a.AccessAPI("call_back/update_call_back", nil, map[string]interface{}{ "call_back_tag": callbackTagList, @@ -115,11 +147,11 @@ func (a *API) UpdateCallback(callbackTagList []string, token, aesKey, urlStr str "url": urlStr, }) } - if err == nil { + if err != nil { a.locker.Lock() defer a.locker.Unlock() - a.callbackToken = token - a.callbackAESKey, _ = base64.StdEncoding.DecodeString(aesKey + "=") + a.callbackToken = oldCallbackToken + a.callbackAESKey = oldCallbackAESKey } return err } @@ -128,3 +160,30 @@ func (a *API) DeleteCallback() (err error) { _, err = a.AccessAPI("call_back/delete_call_back", nil, nil) return err } + +func (a *API) GetCallbackMsg(formMap map[string]interface{}, bodyData []byte) (msgMap map[string]interface{}, callbackResponse *CallbackResponse) { + var bodyMap map[string]interface{} + var err error + err = utils.UnmarshalUseNumber(bodyData, &bodyMap) + if err == nil { + encrypt := utils.Interface2String(bodyMap["encrypt"]) + dataMap := map[string]interface{}{ + // KeyMsgSignature: formMap["signature"], + "nonce": formMap["nonce"], + "timestamp": formMap["timestamp"], + "encrypt": encrypt, + } + signRemote := formMap["signature"].(string) + signMine := a.calculateCallbackSign(dataMap) + if signMine != signRemote { + baseapi.SugarLogger.Infof("signRemote:%s, signMine:%s, formMap:%s, bodyData:%s", signRemote, signMine, utils.Format4Output(formMap, true), string(bodyData)) + err = errors.New("sign not match") + } else { + var descryptMsg string + if descryptMsg, err = a.Decrypt(encrypt); err == nil { + err = utils.UnmarshalUseNumber([]byte(descryptMsg), &msgMap) + } + } + } + return nil, a.Err2CallbackResponse(err) +}