Files
xk-hy-transit-go/internal/logweb/fileauth_handlers.go
2026-05-28 17:03:08 +08:00

121 lines
4.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package logweb
import (
"net/http"
"strconv"
"strings"
"time"
"xk-hy-transit-go/internal/fileauth"
syncer "xk-hy-transit-go/internal/sync"
)
// FileAuthGenerateResponse Web 上传凭证调试 API。
type FileAuthGenerateResponse struct {
AccessKey string `json:"accessKey"`
SecretSet bool `json:"secretSet"`
Bucket string `json:"bucket"`
Scope string `json:"scope"`
B64Mode string `json:"b64Mode"`
PolicyJSON string `json:"policyJson"`
EncodedPutPolicy string `json:"encodedPutPolicy"`
SignInput string `json:"signInput"`
EncodedSign string `json:"encodedSign"`
SignHex string `json:"signHex,omitempty"`
UploadToken string `json:"uploadToken"`
UploadTokenMasked string `json:"uploadTokenMasked"`
DeadlineUnix int64 `json:"deadlineUnix"`
ExpiresSec int64 `json:"expiresSec"`
Algorithm string `json:"algorithm"`
FormatOK bool `json:"formatOk"`
FormatChecks []fileauth.FormatCheck `json:"formatChecks"`
RunnerTokenMatch bool `json:"runnerTokenMatch"`
RunnerTokenPreview string `json:"runnerTokenPreview"`
}
func (s *Server) handleAPIFileAuthGenerate(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet && r.Method != http.MethodPost {
writeErr(w, 405, "GET or POST only")
return
}
sr := asSyncRunner(s.deps.Runner)
if sr == nil {
writeErr(w, 503, "未配置 Runner请使用 transit serve")
return
}
refresh := r.URL.Query().Get("refresh") == "1" || r.URL.Query().Get("refresh") == "true"
if refresh {
if err := sr.RegenerateUploadToken(); err != nil {
writeErr(w, 502, "刷新 Runner uploadToken 失败: "+err.Error())
return
}
}
snap := sr.ConfigSnapshot()
accessKey := strings.TrimSpace(snap.EffectiveAppKey)
secret := strings.TrimSpace(snap.EffectiveSecret)
bucket := strings.TrimSpace(r.URL.Query().Get("bucket"))
if bucket == "" {
bucket = strings.TrimSpace(snap.EffectiveFileBucket)
}
if accessKey == "" || secret == "" {
writeErr(w, 400, "生效 appKey/appSecret 未配置,请在 /config 重新拉取或配置 HY_APP_KEY/HY_APP_SECRET")
return
}
if bucket == "" {
writeErr(w, 400, "fileBucket(scope) 为空,请配置 HY_FILE_BUCKET")
return
}
deadlineUnix := time.Now().Unix() + 3600
if ds := strings.TrimSpace(r.URL.Query().Get("deadline")); ds != "" {
n, err := strconv.ParseInt(ds, 10, 64)
if err != nil || n <= 0 {
writeErr(w, 400, "invalid deadline (unix seconds)")
return
}
deadlineUnix = n
}
parts, err := fileauth.BuildUploadTokenPartsForUpload(accessKey, secret, bucket, deadlineUnix)
if err != nil {
writeErr(w, 500, err.Error())
return
}
formatOK, checks := fileauth.ValidateUploadTokenFormat(parts.UploadToken, accessKey)
runnerTok := strings.TrimSpace(sr.UploadToken())
runnerMatch := runnerTok != "" && runnerTok == parts.UploadToken
writeJSON(w, FileAuthGenerateResponse{
AccessKey: parts.AccessKey,
SecretSet: secret != "",
Bucket: bucket,
Scope: bucket,
B64Mode: fileauth.B64Mode(),
PolicyJSON: parts.PolicyJSON,
EncodedPutPolicy: parts.EncodedPutPolicy,
SignInput: parts.SignInput,
EncodedSign: parts.EncodedSign,
SignHex: fileauth.HMACSignHex(secret, parts.SignInput),
UploadToken: parts.UploadToken,
UploadTokenMasked: maskPreview(parts.UploadToken),
DeadlineUnix: parts.DeadlineUnix,
ExpiresSec: parts.ExpiresSec,
Algorithm: parts.Algorithm,
FormatOK: formatOK,
FormatChecks: checks,
RunnerTokenMatch: runnerMatch,
RunnerTokenPreview: maskPreview(runnerTok),
})
}
// RunnerCredentialsForFileAuth 供测试或扩展:从快照读取凭证。
func RunnerCredentialsForFileAuth(snap syncer.ConfigSnapshot) (accessKey, secret, bucket string) {
return strings.TrimSpace(snap.EffectiveAppKey),
strings.TrimSpace(snap.EffectiveSecret),
strings.TrimSpace(snap.EffectiveFileBucket)
}