From 8f3d611a4c56f43be7d76ff65e8d7b82d8fe5e98 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 28 Feb 2026 22:56:55 +0800 Subject: [PATCH] refactor(wecom): replace generateSignature with computeSignature and update related tests --- pkg/channels/wecom/aibot.go | 25 +++++-------------------- pkg/channels/wecom/aibot_test.go | 14 +++----------- pkg/channels/wecom/common.go | 24 +++++++++++------------- 3 files changed, 19 insertions(+), 44 deletions(-) diff --git a/pkg/channels/wecom/aibot.go b/pkg/channels/wecom/aibot.go index 2962623e1..788305e36 100644 --- a/pkg/channels/wecom/aibot.go +++ b/pkg/channels/wecom/aibot.go @@ -6,7 +6,6 @@ import ( "crypto/aes" "crypto/cipher" "crypto/rand" - "crypto/sha1" "encoding/base64" "encoding/binary" "encoding/json" @@ -14,7 +13,6 @@ import ( "io" "math/big" "net/http" - "sort" "strings" "sync" "time" @@ -291,13 +289,14 @@ func (c *WeComAIBotChannel) handleWebhook(w http.ResponseWriter, r *http.Request "query": r.URL.RawQuery, }) - if r.Method == http.MethodGet { + switch r.Method { + case http.MethodGet: // URL verification c.handleVerification(ctx, w, r) - } else if r.Method == http.MethodPost { + case http.MethodPost: // Message callback c.handleMessageCallback(ctx, w, r) - } else { + default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } @@ -909,7 +908,7 @@ func (c *WeComAIBotChannel) encryptResponse( } // Generate signature - signature := c.generateSignature(timestamp, nonce, encrypted) + signature := computeSignature(c.config.Token, timestamp, nonce, encrypted) // Build encrypted response encryptedResp := WeComAIBotEncryptedResponse{ @@ -1010,20 +1009,6 @@ func pkcs7Pad(data []byte, blockSize int) []byte { return append(data, padText...) } -// generateSignature generates message signature using common function -func (c *WeComAIBotChannel) generateSignature(timestamp, nonce, encrypt string) string { - // Sort parameters - params := []string{c.config.Token, timestamp, nonce, encrypt} - sort.Strings(params) - - // Concatenate - str := strings.Join(params, "") - - // SHA1 hash - hash := sha1.Sum([]byte(str)) - return fmt.Sprintf("%x", hash) -} - // generateStreamID generates a random stream ID func (c *WeComAIBotChannel) generateStreamID() string { const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" diff --git a/pkg/channels/wecom/aibot_test.go b/pkg/channels/wecom/aibot_test.go index 7fb90f22e..6f0664187 100644 --- a/pkg/channels/wecom/aibot_test.go +++ b/pkg/channels/wecom/aibot_test.go @@ -192,27 +192,19 @@ func TestEncryptDecrypt(t *testing.T) { } func TestGenerateSignature(t *testing.T) { - cfg := config.WeComAIBotConfig{ - Enabled: true, - Token: "test_token", - EncodingAESKey: "testkey1234567890123456789012345678901234567", - } - - messageBus := bus.NewMessageBus() - ch, _ := NewWeComAIBotChannel(cfg, messageBus) - + token := "test_token" timestamp := "1234567890" nonce := "test_nonce" encrypt := "encrypted_msg" - signature := ch.generateSignature(timestamp, nonce, encrypt) + signature := computeSignature(token, timestamp, nonce, encrypt) if signature == "" { t.Error("Generated signature is empty") } // Verify signature using verifySignature function - if !verifySignature(cfg.Token, signature, timestamp, nonce, encrypt) { + if !verifySignature(token, signature, timestamp, nonce, encrypt) { t.Error("Generated signature does not verify correctly") } } diff --git a/pkg/channels/wecom/common.go b/pkg/channels/wecom/common.go index 39a27d04c..b1b5399f4 100644 --- a/pkg/channels/wecom/common.go +++ b/pkg/channels/wecom/common.go @@ -14,25 +14,23 @@ import ( // blockSize is the PKCS7 block size used by WeCom (32) const blockSize = 32 +// computeSignature computes the WeCom message signature from the given parameters. +// It sorts [token, timestamp, nonce, encrypt], concatenates them and returns the SHA1 hex digest. +func computeSignature(token, timestamp, nonce, encrypt string) string { + params := []string{token, timestamp, nonce, encrypt} + sort.Strings(params) + str := strings.Join(params, "") + hash := sha1.Sum([]byte(str)) + return fmt.Sprintf("%x", hash) +} + // verifySignature verifies the message signature for WeCom // This is a common function used by both WeCom Bot and WeCom App func verifySignature(token, msgSignature, timestamp, nonce, msgEncrypt string) bool { if token == "" { return true // Skip verification if token is not set } - - // Sort parameters - params := []string{token, timestamp, nonce, msgEncrypt} - sort.Strings(params) - - // Concatenate - str := strings.Join(params, "") - - // SHA1 hash - hash := sha1.Sum([]byte(str)) - expectedSignature := fmt.Sprintf("%x", hash) - - return expectedSignature == msgSignature + return computeSignature(token, timestamp, nonce, msgEncrypt) == msgSignature } // decryptMessage decrypts the encrypted message using AES