package dingdingapi import ( "crypto/sha1" "encoding/base64" "fmt" "sort" "strings" "time" "git.rosy.net.cn/baseapi/utils" ) const ( CBTagCheckURL = "check_url" CBTagUserAddOrg = "user_add_org" CBTagUserModifyOrg = "user_modify_org" CBTagUserLeaveOrg = "user_leave_org" ) const ( KeyMsgSignature = "msg_signature" ) func (a *API) GetCallbackToken() string { a.locker.RLock() defer a.locker.RUnlock() return a.callbackToken } func (a *API) GetCallbackAESKey() []byte { a.locker.RLock() defer a.locker.RUnlock() return a.callbackAESKey } func (a *API) PackCallbackResult(result string) (resultMap map[string]interface{}) { encryptedResult, err := a.Encrypt(result) if err == nil { resultMap = map[string]interface{}{ "encrypt": encryptedResult, "timeStamp": utils.Int64ToStr(time.Now().Unix()), "nonce": utils.GetUUID(), } resultMap["msg_signature"] = a.calculateCallbackSign(resultMap) } return resultMap } func (a *API) calculateCallbackSign(data map[string]interface{}) (sign string) { strList := []string{ a.GetCallbackToken(), } for k, v := range data { if k != KeyMsgSignature { strList = append(strList, v.(string)) } } sort.Sort(sort.StringSlice(strList)) return fmt.Sprintf("%x", sha1.Sum([]byte(strings.Join(strList, "")))) } func (a *API) Encrypt(msg string) (encryptedMsg string, err error) { aesKey := a.GetCallbackAESKey() binResult, err := utils.AESCBCEncpryt([]byte(msg), aesKey, aesKey[:16]) encryptedMsg = base64.StdEncoding.EncodeToString(binResult) return encryptedMsg, err } func (a *API) Decrypt(msg string) (decryptedMsg string, err error) { binMsg, err := base64.StdEncoding.DecodeString(msg) if err == nil { aesKey := a.GetCallbackAESKey() binResult, err2 := utils.AESCBCDecpryt(binMsg, aesKey, aesKey[:16]) if err = err2; err == nil { decryptedMsg = string(binResult) } } return decryptedMsg, err } func (a *API) RegisterCallback(callbackTagList []string, token, aesKey, urlStr string) (err error) { if len(callbackTagList) > 0 { // 为0做测试用 _, err = a.AccessAPI("call_back/register_call_back", nil, map[string]interface{}{ "call_back_tag": callbackTagList, "token": token, "aes_key": aesKey, "url": urlStr, }) } if err == nil { a.locker.Lock() defer a.locker.Unlock() a.callbackToken = token a.callbackAESKey, _ = base64.StdEncoding.DecodeString(aesKey + "=") } return err } func (a *API) GetCallback() (callbackInfo map[string]interface{}, err error) { result, err := a.AccessAPI("call_back/get_call_back", nil, nil) if err == nil { return result, nil } return nil, err } func (a *API) UpdateCallback(callbackTagList []string, token, aesKey, urlStr string) (err error) { if len(callbackTagList) > 0 { // 为0做测试用 _, err = a.AccessAPI("call_back/update_call_back", nil, map[string]interface{}{ "call_back_tag": callbackTagList, "token": token, "aes_key": aesKey, "url": urlStr, }) } if err == nil { a.locker.Lock() defer a.locker.Unlock() a.callbackToken = token a.callbackAESKey, _ = base64.StdEncoding.DecodeString(aesKey + "=") } return err } func (a *API) DeleteCallback() (err error) { _, err = a.AccessAPI("call_back/delete_call_back", nil, nil) return err }