package service import ( "errors" "net" "regexp" "strings" ) // Validator Yggdrasil验证器 type Validator struct{} // NewValidator 创建验证器实例 func NewValidator() *Validator { return &Validator{} } var ( // emailRegex 邮箱正则表达式 emailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`) ) // ValidateServerID 验证服务器ID格式 func (v *Validator) ValidateServerID(serverID string) error { if serverID == "" { return errors.New("服务器ID不能为空") } if len(serverID) > 100 { return errors.New("服务器ID长度超过限制(最大100字符)") } // 防止注入攻击:检查危险字符 if strings.ContainsAny(serverID, "<>\"'&") { return errors.New("服务器ID包含非法字符") } return nil } // ValidateIP 验证IP地址格式 func (v *Validator) ValidateIP(ip string) error { if ip == "" { return nil // IP是可选的 } if net.ParseIP(ip) == nil { return errors.New("IP地址格式无效") } return nil } // ValidateEmail 验证邮箱格式 func (v *Validator) ValidateEmail(email string) error { if email == "" { return errors.New("邮箱不能为空") } if !emailRegex.MatchString(email) { return errors.New("邮箱格式不正确") } return nil } // ValidateUUID 验证UUID格式(支持32位无符号和36位带连字符格式) func (v *Validator) ValidateUUID(uuid string) error { if uuid == "" { return errors.New("UUID不能为空") } // 验证32位无符号UUID格式(纯十六进制字符串) if len(uuid) == 32 { // 检查是否为有效的十六进制字符串 for _, c := range uuid { if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { return errors.New("UUID格式无效:包含非十六进制字符") } } return nil } // 验证36位标准UUID格式(带连字符) if len(uuid) == 36 && uuid[8] == '-' && uuid[13] == '-' && uuid[18] == '-' && uuid[23] == '-' { // 检查除连字符外的字符是否为有效的十六进制 for i, c := range uuid { if i == 8 || i == 13 || i == 18 || i == 23 { continue // 跳过连字符位置 } if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { return errors.New("UUID格式无效:包含非十六进制字符") } } return nil } return errors.New("UUID格式无效:长度应为32位或36位") } // ValidateAccessToken 验证访问令牌 func (v *Validator) ValidateAccessToken(token string) error { if token == "" { return errors.New("访问令牌不能为空") } if len(token) < 10 { return errors.New("访问令牌格式无效") } return nil }