Refactor auth and unify error handling in routers

Renamed AuthRequired/AdminRequired to auth_required/admin_required and updated all references. Replaced direct HTTPException usage with utils.http_exceptions for consistent error handling. Updated router endpoints to use new auth dependency and standardized not implemented responses. Cleaned up unused theme fields in SiteConfigResponse and improved site config endpoint. Minor type and import cleanups across routers and middleware.
This commit is contained in:
2025-12-25 19:08:46 +08:00
parent 5835b4c626
commit abd85e2290
24 changed files with 347 additions and 391 deletions

View File

@@ -1,25 +1,19 @@
from typing import Literal
from loguru import logger as log
from sqlmodel.ext.asyncio.session import AsyncSession
from loguru import logger
from middleware.dependencies import SessionDep
from models import LoginRequest, TokenResponse, User
from utils import http_exceptions
from utils.JWT.JWT import create_access_token, create_refresh_token
from utils.password.pwd import Password, PasswordStatus
async def Login(
session: AsyncSession,
async def login(
session: SessionDep,
login_request: LoginRequest,
) -> TokenResponse | bool | Literal["2fa_required", "2fa_invalid"] | None:
) -> TokenResponse:
"""
根据账号密码进行登录。
如果登录成功,返回一个 TokenResponse 对象,包含访问令牌和刷新令牌以及它们的过期时间。
如果登录异常,返回 `False`(未完成注册或账号被封禁)。
如果登录失败,返回 `None`。
如果需要两步验证但未提供验证码,返回 `"2fa_required"`。
如果两步验证码无效,返回 `"2fa_invalid"`。
:param session: 数据库会话
:param login_request: 登录请求
@@ -38,30 +32,29 @@ async def Login(
# 验证用户是否存在
if not current_user:
log.debug(f"Cannot find user with username: {login_request.username}")
return None
logger.debug(f"Cannot find user with username: {login_request.username}")
http_exceptions.raise_unauthorized("Invalid username or password")
# 验证密码是否正确
if Password.verify(current_user.password, login_request.password) != PasswordStatus.VALID:
log.debug(f"Password verification failed for user: {login_request.username}")
return None
logger.debug(f"Password verification failed for user: {login_request.username}")
http_exceptions.raise_unauthorized("Invalid username or password")
# 验证用户是否可登录
if not current_user.status:
# 未完成注册 or 账号已被封禁
return False
http_exceptions.raise_forbidden("Your account is disabled")
# 检查两步验证
if current_user.two_factor:
# 用户已启用两步验证
if not login_request.two_fa_code:
log.debug(f"2FA required for user: {login_request.username}")
return "2fa_required"
logger.debug(f"2FA required for user: {login_request.username}")
http_exceptions.raise_precondition_required("2FA required")
# 验证 OTP 码
if Password.verify_totp(current_user.two_factor, login_request.two_fa_code) != PasswordStatus.VALID:
log.debug(f"Invalid 2FA code for user: {login_request.username}")
return "2fa_invalid"
logger.debug(f"Invalid 2FA code for user: {login_request.username}")
http_exceptions.raise_unauthorized("Invalid 2FA code")
# 创建令牌
access_token, access_expire = create_access_token(data={'sub': current_user.username})