Sub2API v1.0 - AI API 网关(二开初始版本,基于上游 Wei-Shaw/sub2api)
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int64
|
||||
Email string
|
||||
Username string
|
||||
Notes string
|
||||
AvatarURL string
|
||||
AvatarSource string
|
||||
AvatarMIME string
|
||||
AvatarByteSize int
|
||||
AvatarSHA256 string
|
||||
PasswordHash string
|
||||
Role string
|
||||
Balance float64
|
||||
FrozenBalance float64
|
||||
Concurrency int
|
||||
Status string
|
||||
AllowedGroups []int64
|
||||
TokenVersion int64 // Incremented on password change to invalidate existing tokens
|
||||
// TokenVersionResolved indicates TokenVersion already contains the fingerprint-derived
|
||||
// value expected in JWT claims and refresh-token state.
|
||||
TokenVersionResolved bool
|
||||
SignupSource string
|
||||
LastLoginAt *time.Time
|
||||
LastActiveAt *time.Time
|
||||
LastUsedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt *time.Time // 非 nil 表示用户已软删除
|
||||
|
||||
// GroupRates 用户专属分组倍率配置
|
||||
// map[groupID]rateMultiplier
|
||||
GroupRates map[int64]float64
|
||||
|
||||
// TOTP 双因素认证字段
|
||||
TotpSecretEncrypted *string // AES-256-GCM 加密的 TOTP 密钥
|
||||
TotpEnabled bool // 是否启用 TOTP
|
||||
TotpEnabledAt *time.Time // TOTP 启用时间
|
||||
|
||||
// 余额不足通知
|
||||
BalanceNotifyEnabled bool
|
||||
BalanceNotifyThresholdType string // "fixed" (default) | "percentage"
|
||||
BalanceNotifyThreshold *float64
|
||||
BalanceNotifyExtraEmails []NotifyEmailEntry
|
||||
TotalRecharged float64
|
||||
|
||||
// RPMLimit 用户级每分钟请求数上限(0 = 不限制)。仅在所用分组未设置 rpm_limit
|
||||
// 且该 (用户, 分组) 无 rpm_override 时作为全局兜底生效,计数键 rpm:u:{userID}:{min}。
|
||||
RPMLimit int
|
||||
|
||||
// UserGroupRPMOverride 来自 auth cache snapshot 的 (user, group) RPM 覆盖值。
|
||||
// nil = 该 API Key 对应的 (user, group) 无 override;非 nil 时 checkRPM 直接使用,
|
||||
// 避免每请求查 DB。字段不持久化到数据库。
|
||||
UserGroupRPMOverride *int
|
||||
|
||||
APIKeys []APIKey
|
||||
Subscriptions []UserSubscription
|
||||
}
|
||||
|
||||
func (u *User) IsAdmin() bool {
|
||||
return u.Role == RoleAdmin
|
||||
}
|
||||
|
||||
func (u *User) IsActive() bool {
|
||||
return u.Status == StatusActive
|
||||
}
|
||||
|
||||
// CanBindGroup checks whether a user can bind to a given group.
|
||||
// For standard groups:
|
||||
// - Public groups (non-exclusive): all users can bind
|
||||
// - Exclusive groups: only users with the group in AllowedGroups can bind
|
||||
func (u *User) CanBindGroup(groupID int64, isExclusive bool) bool {
|
||||
// 公开分组(非专属):所有用户都可以绑定
|
||||
if !isExclusive {
|
||||
return true
|
||||
}
|
||||
// 专属分组:需要在 AllowedGroups 中
|
||||
for _, id := range u.AllowedGroups {
|
||||
if id == groupID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (u *User) SetPassword(password string) error {
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.PasswordHash = string(hash)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *User) CheckPassword(password string) bool {
|
||||
return bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(password)) == nil
|
||||
}
|
||||
Reference in New Issue
Block a user