This commit is contained in:
2026-08-16 09:02:39 +08:00
parent c554152f4f
commit f7f6db8695
105 changed files with 2535 additions and 948 deletions
+17 -9
View File
@@ -11,6 +11,8 @@ import (
type SecurityConfig struct {
ID uint
CreatedAt time.Time
UpdatedAt time.Time
CaptchaOpen int
CaptchaTimeout int
KeyLong int
@@ -128,21 +130,21 @@ func (uc *SecurityUsecase) ValidateCurrentPassword(ctx context.Context, password
}
func (uc *SecurityUsecase) LoginLocked(ctx context.Context, username string) (bool, error) {
_, locked, err := uc.cache.Get(ctx, "login:lock:"+username)
_, locked, err := uc.cache.Get(ctx, loginLockKey(username))
return locked, err
}
func (uc *SecurityUsecase) IncrementLoginFailure(ctx context.Context, username string, expiration time.Duration) (int64, error) {
return uc.cache.Increment(ctx, "login:fail:"+username, expiration)
return uc.cache.Increment(ctx, loginFailureKey(username), expiration)
}
func (uc *SecurityUsecase) LockLogin(ctx context.Context, username string, expiration time.Duration) error {
return uc.cache.Set(ctx, "login:lock:"+username, "1", expiration)
return uc.cache.Set(ctx, loginLockKey(username), "1", expiration)
}
func (uc *SecurityUsecase) ClearLoginState(ctx context.Context, username string) {
_ = uc.cache.Delete(ctx, "login:fail:"+username)
_ = uc.cache.Delete(ctx, "login:lock:"+username)
_ = uc.cache.Delete(ctx, loginFailureKey(username))
_ = uc.cache.Delete(ctx, loginLockKey(username))
}
func (uc *SecurityUsecase) EnsureLoginIPCounter(ctx context.Context, ip string, expiration time.Duration) (int, error) {
@@ -171,15 +173,15 @@ func (uc *SecurityUsecase) IncrementRateLimit(ctx context.Context, key string, e
}
func (uc *SecurityUsecase) SetCaptcha(ctx context.Context, id, value string, expiration time.Duration) error {
return uc.cache.Set(ctx, "captcha:"+id, value, expiration)
return uc.cache.Set(ctx, "CAPTCHA_"+id, value, expiration)
}
func (uc *SecurityUsecase) GetCaptcha(ctx context.Context, id string) (string, bool, error) {
return uc.cache.Get(ctx, "captcha:"+id)
return uc.cache.Get(ctx, "CAPTCHA_"+id)
}
func (uc *SecurityUsecase) DeleteCaptcha(ctx context.Context, id string) error {
return uc.cache.Delete(ctx, "captcha:"+id)
return uc.cache.Delete(ctx, "CAPTCHA_"+id)
}
func (uc *SecurityUsecase) VerifyCaptcha(ctx context.Context, id, answer string, clear bool) bool {
@@ -196,7 +198,13 @@ func (uc *SecurityUsecase) VerifyCaptcha(ctx context.Context, id, answer string,
return strings.EqualFold(value, answer)
}
func activeTokenKey(username string) string { return "jwt:active:" + username }
// The currently active multipoint token is stored under the username itself.
// Keep the same key so a rolling deployment can revoke sessions issued by the
// other implementation instead of silently creating a second active session.
func activeTokenKey(username string) string { return username }
func loginFailureKey(username string) string { return "login_fail:" + username }
func loginLockKey(username string) string { return "login_lock:" + username }
func (uc *SecurityUsecase) ActiveToken(ctx context.Context, username string) (string, error) {
value, _, err := uc.cache.Get(ctx, activeTokenKey(username))