feat(yggdrasil): implement standard error responses and UUID format improvements
All checks were successful
Build / build (push) Successful in 2m17s
Build / build-docker (push) Successful in 57s

- Add YggdrasilErrorResponse struct and standard error codes for protocol compliance
- Change UUID storage from varchar(36) to varchar(32) for unsigned format
- Add utility functions: GenerateUUID, FormatUUIDToNoDash, RandomHex
- Support unsigned query parameter in GetProfileByUUID endpoint
- Improve refresh token response with available profiles list
- Fix key pair retrieval to use correct database column (rsa_private_key)
- Update UUID validator to accept both 32-char and 36-char formats
- Add SignStringWithProfileRSA method for profile-specific signing
- Fix profile assignment validation in refresh token flow
This commit is contained in:
2026-02-23 13:26:53 +08:00
parent 3e8b7d150d
commit 29f0bad2bc
16 changed files with 719 additions and 89 deletions

View File

@@ -1,8 +1,12 @@
package utils
import (
"go.uber.org/zap"
"crypto/rand"
"encoding/hex"
"strings"
"github.com/google/uuid"
"go.uber.org/zap"
)
// FormatUUID 将UUID格式化为带连字符的标准格式
@@ -45,3 +49,49 @@ func FormatUUID(uuid string) string {
logger.Warn("[WARN] UUID格式无效: ", zap.String("uuid:", uuid))
return uuid
}
// GenerateUUID 生成无符号UUID32位十六进制字符串不带连字符
// 使用github.com/google/uuid库生成标准UUID然后移除连字符
// 返回格式示例: "123e4567e89b12d3a456426614174000"
func GenerateUUID() string {
return strings.ReplaceAll(uuid.New().String(), "-", "")
}
// FormatUUIDToNoDash 将带连字符的UUID转换为无符号格式移除连字符
// 输入: "123e4567-e89b-12d3-a456-426614174000"
// 输出: "123e4567e89b12d3a456426614174000"
// 如果输入已经是32位格式直接返回
// 如果输入格式无效,返回原值并记录警告
func FormatUUIDToNoDash(uuid string) string {
// 如果为空,直接返回
if uuid == "" {
return uuid
}
// 如果已经是32位格式无连字符直接返回
if len(uuid) == 32 {
return uuid
}
// 如果是36位标准格式移除连字符
if len(uuid) == 36 && uuid[8] == '-' && uuid[13] == '-' && uuid[18] == '-' && uuid[23] == '-' {
return strings.ReplaceAll(uuid, "-", "")
}
// 如果格式无效,记录警告并返回原值
var logger *zap.Logger
logger.Warn("[WARN] UUID格式无效无法转换为无符号格式: ", zap.String("uuid:", uuid))
return uuid
}
// RandomHex 生成指定长度的随机十六进制字符串
// 参数 n: 需要生成的十六进制字符数量每个字节生成2个十六进制字符
// 返回: 长度为 2*n 的十六进制字符串
// 示例: RandomHex(16) 返回 "a1b2c3d4e5f67890abcdef1234567890" (32字符)
func RandomHex(n uint) (string, error) {
bytes := make([]byte, n)
if _, err := rand.Read(bytes); err != nil {
return "", err
}
return hex.EncodeToString(bytes), nil
}