fix: load uid key from manager config

This commit is contained in:
richjohnrambo
2026-09-17 16:09:30 +08:00
parent 228e3a54fd
commit ba6fd7f1b6
11 changed files with 416 additions and 14 deletions
+54 -6
View File
@@ -7,10 +7,41 @@ import (
"fmt"
"strconv"
"strings"
"sync"
"golang.org/x/crypto/xtea"
)
type userID int64
const defaultUIDKey = "la6YsO+bNX/+XIkOqc5Svw=="
var (
uidCodecMu sync.RWMutex
uidCipher *xtea.Cipher
)
func init() {
if err := SetUIDKey(defaultUIDKey); err != nil {
panic(err)
}
}
func SetUIDKey(encoded string) error {
key, err := base64.StdEncoding.DecodeString(strings.TrimSpace(encoded))
if err != nil {
return fmt.Errorf("invalid uid key: %w", err)
}
cipher, err := xtea.NewCipher(key)
if err != nil {
return fmt.Errorf("invalid uid key: %w", err)
}
uidCodecMu.Lock()
uidCipher = cipher
uidCodecMu.Unlock()
return nil
}
func (id *userID) UnmarshalJSON(raw []byte) error {
value, err := parseUserIDJSON(raw)
if err != nil {
@@ -63,7 +94,7 @@ func parseUserID(value string) (int64, error) {
if err != nil || len(decoded) < 8 {
return 0, fmt.Errorf("invalid user id")
}
return int64(binary.LittleEndian.Uint64(decoded[:8])), nil
return decryptUID(decoded[:8]), nil
}
return strconv.ParseInt(value, 10, 64)
}
@@ -72,11 +103,8 @@ func formatUserID(id int64) string {
if id == 0 {
return ""
}
src := make([]byte, 8)
dst := make([]byte, base64.URLEncoding.WithPadding(base64.NoPadding).EncodedLen(8))
binary.LittleEndian.PutUint64(src, uint64(id))
base64.URLEncoding.WithPadding(base64.NoPadding).Encode(dst, src)
return "usr" + string(dst)
encoded := encryptUID(id)
return "usr" + base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(encoded)
}
func parseUserIDList(values []userID) []int64 {
@@ -92,3 +120,23 @@ func parseUserIDList(values []userID) []int64 {
}
return items
}
func decryptUID(encoded []byte) int64 {
dst := make([]byte, 8)
uidCodecMu.RLock()
cipher := uidCipher
uidCodecMu.RUnlock()
cipher.Decrypt(dst, encoded[:8])
return int64(binary.LittleEndian.Uint64(dst))
}
func encryptUID(id int64) []byte {
src := make([]byte, 8)
dst := make([]byte, 8)
binary.LittleEndian.PutUint64(src, uint64(id))
uidCodecMu.RLock()
cipher := uidCipher
uidCodecMu.RUnlock()
cipher.Encrypt(dst, src)
return dst
}