refactor: clean code

This commit is contained in:
Fu Diwei
2026-06-22 16:32:18 +08:00
committed by RHQYZ
parent f7f0864e3b
commit ec6a4aea8c
16 changed files with 115 additions and 133 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ import (
func main() {
pb := app.GetApp().(*pocketbase.PocketBase)
if len(os.Args) < 2 {
slog.Error("[CERTIMATE] missing exec args, maybe you forget the 'serve' command?")
slog.Error("[CERTIMATE] missing exec args, maybe you forgot the 'serve' command?")
os.Exit(1)
return
}
@@ -11,6 +11,7 @@ import (
"encoding/hex"
"fmt"
"log/slog"
"net/http"
"regexp"
"strconv"
"time"
@@ -231,7 +232,7 @@ func createSDKClient(accessKeyId, accessKeySecret string) (*wangsucdnpro.Client,
func encryptPrivateKey(privkeyPEM string, apiKey string, timestamp int64) (string, error) {
date := time.Unix(timestamp, 0).UTC()
dateStr := date.Format("Mon, 02 Jan 2006 15:04:05 GMT")
dateStr := date.Format(http.TimeFormat)
h := hmac.New(sha256.New, []byte(apiKey))
h.Write([]byte(dateStr))
@@ -85,8 +85,8 @@ func (n *Notifier) Notify(ctx context.Context, subject string, message string) (
SetHeader("Authorization", "Bearer "+loginResp.Header().Get("Token")).
SetBody(map[string]any{
"channel_id": n.config.ChannelId,
"props": map[string]interface{}{
"attachments": []map[string]interface{}{
"props": map[string]any{
"attachments": []map[string]any{
{
"title": subject,
"text": message,
+1 -1
View File
@@ -85,7 +85,7 @@ func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) {
return resp, nil
}
func (c *Client) doRequestWithResult(req *resty.Request, res interface{}) (*resty.Response, error) {
func (c *Client) doRequestWithResult(req *resty.Request, res any) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
+30 -41
View File
@@ -1,6 +1,7 @@
package openapi
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
@@ -22,17 +23,17 @@ type Client struct {
rc *resty.Client
}
func NewClient(endpoint string, optFns ...OptionsFunc) (*Client, error) {
func NewClient(baseUrl string, optFns ...OptionsFunc) (*Client, error) {
opts := &Options{}
for _, fn := range optFns {
fn(opts)
}
if endpoint == "" {
return nil, fmt.Errorf("sdkerr: unset endpoint")
if baseUrl == "" {
return nil, fmt.Errorf("sdkerr: unset baseUrl")
}
if _, err := url.Parse(endpoint); err != nil {
return nil, fmt.Errorf("sdkerr: invalid endpoint: %w", err)
if _, err := url.Parse(baseUrl); err != nil {
return nil, fmt.Errorf("sdkerr: invalid baseUrl: %w", err)
}
if opts.AccessKeyId == "" {
return nil, fmt.Errorf("sdkerr: unset accessKeyId")
@@ -42,69 +43,57 @@ func NewClient(endpoint string, optFns ...OptionsFunc) (*Client, error) {
}
restyClient := resty.New().
SetBaseURL(endpoint).
SetBaseURL(baseUrl).
SetHeader("Accept", "application/json").
SetHeader("Content-Type", "application/json").
SetHeader("User-Agent", app.AppUserAgent).
SetPreRequestHook(func(c *resty.Client, req *http.Request) error {
// 生成时间戳及流水号
// API 签名机制:
// https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=77&api=%u6784%u9020%u8BF7%u6C42&data=114&vid=107
now := time.Now()
eopDate := now.Format("20060102T150405Z")
eopReqId := security.RandomString(32)
// 获取查询参数
queryStr := ""
if req.URL != nil {
queryStr = req.URL.Query().Encode()
}
// 获取请求正文
payloadStr := ""
if req.Body != nil {
reader, err := req.GetBody()
if req.Method != http.MethodGet && req.Body != nil {
payloadb, err := io.ReadAll(req.Body)
if err != nil {
return err
}
defer reader.Close()
payload, err := io.ReadAll(reader)
if err != nil {
return err
}
payloadStr = string(payload)
payloadStr = string(payloadb)
req.Body = io.NopCloser(bytes.NewReader(payloadb))
}
// 构造代签字符串
payloadHash := sha256.Sum256([]byte(payloadStr))
payloadHashHex := hex.EncodeToString(payloadHash[:])
dataToSign := fmt.Sprintf("ctyun-eop-request-id:%s\neop-date:%s\n\n%s\n%s", eopReqId, eopDate, queryStr, payloadHashHex)
// 生成 ktime
hasher := hmac.New(sha256.New, []byte(opts.SecretAccessKey))
hasher.Write([]byte(eopDate))
ktime := hasher.Sum(nil)
h := hmac.New(sha256.New, []byte(opts.SecretAccessKey))
h.Write([]byte(eopDate))
kTime := h.Sum(nil)
// 生成 kak
hasher = hmac.New(sha256.New, ktime)
hasher.Write([]byte(opts.AccessKeyId))
kak := hasher.Sum(nil)
h = hmac.New(sha256.New, kTime)
h.Write([]byte(opts.AccessKeyId))
kAk := h.Sum(nil)
// 生成 kdate
hasher = hmac.New(sha256.New, kak)
hasher.Write([]byte(now.Format("20060102")))
kdate := hasher.Sum(nil)
h = hmac.New(sha256.New, kAk)
h.Write([]byte(now.Format("20060102")))
kDate := h.Sum(nil)
// 构造签名
hasher = hmac.New(sha256.New, kdate)
hasher.Write([]byte(dataToSign))
sign := hasher.Sum(nil)
signStr := base64.StdEncoding.EncodeToString(sign)
stringToSign := fmt.Sprintf("ctyun-eop-request-id:%s\neop-date:%s\n\n%s\n%s", eopReqId, eopDate, queryStr, payloadHashHex)
h = hmac.New(sha256.New, kDate)
h.Write([]byte(stringToSign))
signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
// 设置请求头
req.Header.Set("ctyun-eop-request-id", eopReqId)
req.Header.Set("eop-date", eopDate)
req.Header.Set("eop-authorization", fmt.Sprintf("%s Headers=ctyun-eop-request-id;eop-date Signature=%s", opts.AccessKeyId, signStr))
req.Header.Set("eop-authorization", fmt.Sprintf("%s Headers=ctyun-eop-request-id;eop-date Signature=%s", opts.AccessKeyId, signature))
return nil
})
@@ -149,7 +138,7 @@ func (c *Client) DoRequest(req *resty.Request) (*resty.Response, error) {
return resp, nil
}
func (c *Client) DoRequestWithResult(req *resty.Request, res interface{}) (*resty.Response, error) {
func (c *Client) DoRequestWithResult(req *resty.Request, res any) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
+18 -19
View File
@@ -1,6 +1,7 @@
package dogecloud
import (
"bytes"
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
@@ -38,35 +39,33 @@ func NewClient(optFns ...OptionsFunc) (*Client, error) {
SetHeader("Content-Type", "application/json").
SetHeader("User-Agent", app.AppUserAgent).
SetPreRequestHook(func(ctx *resty.Client, req *http.Request) error {
requestUrl := req.URL.Path
requestQuery := req.URL.Query().Encode()
if requestQuery != "" {
requestUrl += "?" + requestQuery
// API 签名机制:
// https://docs.dogecloud.com/cdn/api-access-token
path := req.URL.Path
queryStr := req.URL.Query().Encode()
if queryStr != "" {
path += "?" + queryStr
}
payload := ""
payloadStr := ""
if req.Body != nil {
reader, err := req.GetBody()
payloadb, err := io.ReadAll(req.Body)
if err != nil {
return err
}
defer reader.Close()
payloadb, err := io.ReadAll(reader)
if err != nil {
return err
}
payload = string(payloadb)
payloadStr = string(payloadb)
req.Body = io.NopCloser(bytes.NewReader(payloadb))
}
stringToSign := fmt.Sprintf("%s\n%s", requestUrl, payload)
mac := hmac.New(sha1.New, []byte(opts.SecretKey))
mac.Write([]byte(stringToSign))
sign := hex.EncodeToString(mac.Sum(nil))
stringToSign := fmt.Sprintf("%s\n%s", path, payloadStr)
req.Header.Set("Authorization", fmt.Sprintf("TOKEN %s:%s", opts.AccessKey, sign))
h := hmac.New(sha1.New, []byte(opts.SecretKey))
h.Write([]byte(stringToSign))
signature := hex.EncodeToString(h.Sum(nil))
req.Header.Set("Authorization", fmt.Sprintf("TOKEN %s:%s", opts.AccessKey, signature))
return nil
})
+1 -1
View File
@@ -85,7 +85,7 @@ func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) {
return resp, nil
}
func (c *Client) doRequestWithResult(req *resty.Request, res interface{}) (*resty.Response, error) {
func (c *Client) doRequestWithResult(req *resty.Request, res any) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
+1 -1
View File
@@ -71,7 +71,7 @@ func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) {
return resp, nil
}
func (c *Client) doRequestWithResult(req *resty.Request, res interface{}) (*resty.Response, error) {
func (c *Client) doRequestWithResult(req *resty.Request, res any) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
+1 -1
View File
@@ -90,7 +90,7 @@ func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) {
return resp, nil
}
func (c *Client) doRequestWithResult(req *resty.Request, res interface{}) (*resty.Response, error) {
func (c *Client) doRequestWithResult(req *resty.Request, res any) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
+1 -1
View File
@@ -96,7 +96,7 @@ func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) {
return resp, nil
}
func (c *Client) doRequestWithResult(req *resty.Request, res interface{}) (*resty.Response, error) {
func (c *Client) doRequestWithResult(req *resty.Request, res any) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
+1 -1
View File
@@ -104,7 +104,7 @@ func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) {
return resp, nil
}
func (c *Client) doRequestWithResult(req *resty.Request, res interface{}) (*resty.Response, error) {
func (c *Client) doRequestWithResult(req *resty.Request, res any) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
+1 -1
View File
@@ -35,7 +35,7 @@ func (r *sdkResponseBase) GetError() string {
return errObj.Message
}
var errMap map[string]interface{}
var errMap map[string]any
if err := json.Unmarshal(r.Error, &errMap); err == nil {
if message, ok := errMap["message"].(string); ok {
return message
+1 -1
View File
@@ -88,7 +88,7 @@ func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) {
return resp, nil
}
func (c *Client) doRequestWithResult(req *resty.Request, res interface{}) (*resty.Response, error) {
func (c *Client) doRequestWithResult(req *resty.Request, res any) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
+6 -7
View File
@@ -39,13 +39,13 @@ func NewClient(optFns ...OptionsFunc) (*Client, error) {
SetHeader("Host", "api.routewize.com").
SetHeader("User-Agent", app.AppUserAgent).
SetPreRequestHook(func(c *resty.Client, req *http.Request) error {
// 生成时间
// 签名机制:
// https://docsv4.qingcloud.com/user_guide/development_docs/api/api_list/dns/calling_method/signature/
date := time.Now().UTC().Format(time.RFC1123)
// 获取请求谓词
verb := req.Method
// 获取访问资源
canonicalizedResource := "/"
if req.URL != nil {
canonicalizedResource = req.URL.Path
@@ -55,17 +55,16 @@ func NewClient(optFns ...OptionsFunc) (*Client, error) {
}
}
// 计算签名
stringToSign := verb + "\n" +
date + "\n" +
canonicalizedResource
h := hmac.New(sha256.New, []byte(options.SecretAccessKey))
h.Write([]byte(stringToSign))
sign := base64.StdEncoding.EncodeToString(h.Sum(nil))
signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
// 设置请求头
req.Header.Set("Date", date)
req.Header.Set("Authorization", fmt.Sprintf("QC-HMAC-SHA256 %s:%s", options.AccessKeyId, sign))
req.Header.Set("Authorization", fmt.Sprintf("QC-HMAC-SHA256 %s:%s", options.AccessKeyId, signature))
return nil
})
+14 -7
View File
@@ -48,15 +48,18 @@ func NewClient(serverUrl string, optFns ...OptionsFunc) (*Client, error) {
SetHeader("Content-Type", "application/json").
SetHeader("User-Agent", app.AppUserAgent).
SetPreRequestHook(func(c *resty.Client, req *http.Request) error {
var body []byte
var err error
// API 签名机制:
// https://ratpanel.github.io/advanced/api#authentication-mechanism
payloadStr := ""
if req.Body != nil {
body, err = io.ReadAll(req.Body)
payloadb, err := io.ReadAll(req.Body)
if err != nil {
return err
}
req.Body = io.NopCloser(bytes.NewReader(body))
payloadStr = string(payloadb)
req.Body = io.NopCloser(bytes.NewReader(payloadb))
}
canonicalPath := req.URL.Path
@@ -71,16 +74,20 @@ func NewClient(serverUrl string, optFns ...OptionsFunc) (*Client, error) {
req.Method,
canonicalPath,
req.URL.Query().Encode(),
sumSha256(string(body)))
sumSha256(payloadStr),
)
timestamp := time.Now().Unix()
req.Header.Set("X-Timestamp", fmt.Sprintf("%d", timestamp))
stringToSign := fmt.Sprintf("%s\n%d\n%s",
"HMAC-SHA256",
timestamp,
sumSha256(canonicalRequest))
sumSha256(canonicalRequest),
)
signature := sumHmacSha256(stringToSign, options.AccessToken)
req.Header.Set("X-Timestamp", fmt.Sprintf("%d", timestamp))
req.Header.Set("Authorization", fmt.Sprintf("HMAC-SHA256 Credential=%d, Signature=%s", options.AccessTokenId, signature))
return nil
+34 -47
View File
@@ -1,6 +1,7 @@
package openapi
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
@@ -42,88 +43,74 @@ func NewClient(optFns ...OptionsFunc) (*Client, error) {
SetHeader("Host", "open.chinanetcenter.com").
SetHeader("User-Agent", app.AppUserAgent).
SetPreRequestHook(func(c *resty.Client, req *http.Request) error {
// Step 1: Get request method
method := req.Method
method = strings.ToUpper(method)
// API 签名机制:
// https://www.wangsu.com/document/openapi/api-authentication
method := strings.ToUpper(req.Method)
// Step 2: Get request path
path := "/"
if req.URL != nil {
path = req.URL.Path
}
// Step 3: Get unencoded query string
queryString := ""
queryStr := ""
if method != http.MethodPost && req.URL != nil {
queryString = req.URL.RawQuery
queryStr = req.URL.RawQuery
s, err := url.QueryUnescape(queryString)
s, err := url.QueryUnescape(queryStr)
if err != nil {
return err
}
queryString = s
queryStr = s
}
// Step 4: Get canonical headers & signed headers
canonicalHeaders := "" +
"content-type:" + strings.TrimSpace(strings.ToLower(req.Header.Get("Content-Type"))) + "\n" +
"host:" + strings.TrimSpace(strings.ToLower(req.Header.Get("Host"))) + "\n"
signedHeaders := "content-type;host"
// Step 5: Get request payload
payload := ""
payloadStr := ""
if method != http.MethodGet && req.Body != nil {
reader, err := req.GetBody()
payloadb, err := io.ReadAll(req.Body)
if err != nil {
return err
}
defer reader.Close()
payloadb, err := io.ReadAll(reader)
if err != nil {
return err
}
payload = string(payloadb)
payloadStr = string(payloadb)
req.Body = io.NopCloser(bytes.NewReader(payloadb))
}
hashedPayload := sha256.Sum256([]byte(payload))
hashedPayloadHex := strings.ToLower(hex.EncodeToString(hashedPayload[:]))
payloadHash := sha256.Sum256([]byte(payloadStr))
payloadHashHex := strings.ToLower(hex.EncodeToString(payloadHash[:]))
// Step 6: Get timestamp
var reqtime time.Time
timestampString := req.Header.Get("X-CNC-Timestamp")
if timestampString == "" {
reqtime = time.Now().UTC()
timestampString = fmt.Sprintf("%d", reqtime.Unix())
nowUtc := time.Now().UTC()
timestampStr := req.Header.Get("X-CNC-Timestamp")
if timestampStr == "" {
timestampStr = fmt.Sprintf("%d", nowUtc.Unix())
} else {
timestamp, err := strconv.ParseInt(timestampString, 10, 64)
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
return err
}
reqtime = time.Unix(timestamp, 0).UTC()
nowUtc = time.Unix(timestamp, 0).UTC()
}
// Step 7: Get canonical request string
canonicalRequest := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", method, path, queryString, canonicalHeaders, signedHeaders, hashedPayloadHex)
hashedCanonicalRequest := sha256.Sum256([]byte(canonicalRequest))
hashedCanonicalRequestHex := strings.ToLower(hex.EncodeToString(hashedCanonicalRequest[:]))
canonicalRequest := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", method, path, queryStr, canonicalHeaders, signedHeaders, payloadHashHex)
canonicalRequestHash := sha256.Sum256([]byte(canonicalRequest))
canonicalRequestHashHex := strings.ToLower(hex.EncodeToString(canonicalRequestHash[:]))
// Step 8: String to sign
const SignAlgorithmHeader = "CNC-HMAC-SHA256"
stringToSign := fmt.Sprintf("%s\n%s\n%s", SignAlgorithmHeader, timestampString, hashedCanonicalRequestHex)
hmac := hmac.New(sha256.New, []byte(options.SecretKey))
hmac.Write([]byte(stringToSign))
sign := hmac.Sum(nil)
signHex := strings.ToLower(hex.EncodeToString(sign))
const signAlgorithmHeader = "CNC-HMAC-SHA256"
stringToSign := fmt.Sprintf("%s\n%s\n%s", signAlgorithmHeader, timestampStr, canonicalRequestHashHex)
h := hmac.New(sha256.New, []byte(options.SecretKey))
h.Write([]byte(stringToSign))
signature := strings.ToLower(hex.EncodeToString(h.Sum(nil)))
// Step 9: Add headers to request
req.Header.Set("X-CNC-AccessKey", options.AccessKey)
req.Header.Set("X-CNC-Timestamp", timestampString)
req.Header.Set("X-CNC-Timestamp", timestampStr)
req.Header.Set("X-CNC-Auth-Method", "AKSK")
req.Header.Set("Authorization", fmt.Sprintf("%s Credential=%s, SignedHeaders=%s, Signature=%s", SignAlgorithmHeader, options.AccessKey, signedHeaders, signHex))
req.Header.Set("Date", reqtime.Format("Mon, 02 Jan 2006 15:04:05 GMT"))
req.Header.Set("Authorization", fmt.Sprintf("%s Credential=%s, SignedHeaders=%s, Signature=%s", signAlgorithmHeader, options.AccessKey, signedHeaders, signature))
req.Header.Set("Date", nowUtc.Format(http.TimeFormat))
return nil
})
@@ -168,7 +155,7 @@ func (c *Client) DoRequest(req *resty.Request) (*resty.Response, error) {
return resp, nil
}
func (c *Client) DoRequestWithResult(req *resty.Request, res interface{}) (*resty.Response, error) {
func (c *Client) DoRequestWithResult(req *resty.Request, res any) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}