fix auth pending session hardening
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
@@ -105,6 +106,34 @@ func (h *AuthHandler) respondWithTokenPair(c *gin.Context, user *service.User) {
|
||||
})
|
||||
}
|
||||
|
||||
func (h *AuthHandler) ensureBackendModeAllowsUser(ctx context.Context, user *service.User) error {
|
||||
if user == nil {
|
||||
return infraerrors.Unauthorized("INVALID_USER", "user not found")
|
||||
}
|
||||
if h == nil || !h.isBackendModeEnabled(ctx) || user.IsAdmin() {
|
||||
return nil
|
||||
}
|
||||
return infraerrors.Forbidden("BACKEND_MODE_ADMIN_ONLY", "Backend mode is active. Only admin login is allowed.")
|
||||
}
|
||||
|
||||
func (h *AuthHandler) ensureBackendModeAllowsNewUserLogin(ctx context.Context) error {
|
||||
if h == nil || !h.isBackendModeEnabled(ctx) {
|
||||
return nil
|
||||
}
|
||||
return infraerrors.Forbidden("BACKEND_MODE_ADMIN_ONLY", "Backend mode is active. Only admin login is allowed.")
|
||||
}
|
||||
|
||||
func (h *AuthHandler) isBackendModeEnabled(ctx context.Context) bool {
|
||||
if h == nil || h.settingSvc == nil {
|
||||
return false
|
||||
}
|
||||
settings, err := h.settingSvc.GetPublicSettings(ctx)
|
||||
if err == nil && settings != nil {
|
||||
return settings.BackendModeEnabled
|
||||
}
|
||||
return h.settingSvc.IsBackendModeEnabled(ctx)
|
||||
}
|
||||
|
||||
// Register handles user registration
|
||||
// POST /api/v1/auth/register
|
||||
func (h *AuthHandler) Register(c *gin.Context) {
|
||||
@@ -178,6 +207,11 @@ func (h *AuthHandler) Login(c *gin.Context) {
|
||||
}
|
||||
_ = token // token 由 authService.Login 返回但此处由 respondWithTokenPair 重新生成
|
||||
|
||||
if err := h.ensureBackendModeAllowsUser(c.Request.Context(), user); err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if TOTP 2FA is enabled for this user
|
||||
if h.totpService != nil && h.settingSvc.IsTotpEnabled(c.Request.Context()) && user.TotpEnabled {
|
||||
// Create a temporary login session for 2FA
|
||||
@@ -195,11 +229,7 @@ func (h *AuthHandler) Login(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Backend mode: only admin can login
|
||||
if h.settingSvc.IsBackendModeEnabled(c.Request.Context()) && !user.IsAdmin() {
|
||||
response.Forbidden(c, "Backend mode is active. Only admin login is allowed.")
|
||||
return
|
||||
}
|
||||
h.authService.RecordSuccessfulLogin(c.Request.Context(), user.ID)
|
||||
|
||||
h.respondWithTokenPair(c, user)
|
||||
}
|
||||
@@ -264,9 +294,8 @@ func (h *AuthHandler) Login2FA(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Backend mode: only admin can login (check BEFORE deleting session)
|
||||
if h.settingSvc.IsBackendModeEnabled(c.Request.Context()) && !user.IsAdmin() {
|
||||
response.Forbidden(c, "Backend mode is active. Only admin login is allowed.")
|
||||
if err := h.ensureBackendModeAllowsUser(c.Request.Context(), user); err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -330,6 +359,10 @@ func (h *AuthHandler) Login2FA(c *gin.Context) {
|
||||
// Delete the login session (only after all checks pass)
|
||||
_ = h.totpService.DeleteLoginSession(c.Request.Context(), req.TempToken)
|
||||
|
||||
if session.PendingOAuthBind == nil {
|
||||
h.authService.RecordSuccessfulLogin(c.Request.Context(), user.ID)
|
||||
}
|
||||
|
||||
h.respondWithTokenPair(c, user)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user