style: normalize python formatting gates
This commit is contained in:
@@ -5,36 +5,35 @@ This module is intentionally disabled until the DI container/auth ports are rebu
|
||||
Do not mount it directly; use `auth_simple.py` only as the current compatibility route.
|
||||
"""
|
||||
|
||||
raise RuntimeError(
|
||||
"apps.api.app.api.routes.auth is disabled: rebuild DI container before mounting full auth routes"
|
||||
)
|
||||
raise RuntimeError("apps.api.app.api.routes.auth is disabled: rebuild DI container before mounting full auth routes")
|
||||
|
||||
from fastapi import APIRouter, HTTPException, status, Depends, Request
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
||||
from pydantic import BaseModel, EmailStr
|
||||
|
||||
from packages.application.auth import (
|
||||
RegisterUserUseCase,
|
||||
RegisterUserRequest,
|
||||
LoginUseCase,
|
||||
LoginRequest,
|
||||
LogoutUseCase,
|
||||
LogoutRequest,
|
||||
VerifyEmailUseCase,
|
||||
VerifyEmailRequest,
|
||||
RequestPasswordResetUseCase,
|
||||
RequestPasswordResetRequest,
|
||||
ResetPasswordUseCase,
|
||||
ResetPasswordRequest,
|
||||
)
|
||||
from packages.domain.entities import User
|
||||
from apps.api.app.dependencies import get_container
|
||||
from apps.api.app.middleware.auth import get_current_user
|
||||
from packages.application.auth import (
|
||||
LoginRequest,
|
||||
LoginUseCase,
|
||||
LogoutRequest,
|
||||
LogoutUseCase,
|
||||
RegisterUserRequest,
|
||||
RegisterUserUseCase,
|
||||
RequestPasswordResetRequest,
|
||||
RequestPasswordResetUseCase,
|
||||
ResetPasswordRequest,
|
||||
ResetPasswordUseCase,
|
||||
VerifyEmailRequest,
|
||||
VerifyEmailUseCase,
|
||||
)
|
||||
from packages.domain.entities import User
|
||||
|
||||
router = APIRouter(prefix="/auth", tags=["Authentication"])
|
||||
|
||||
|
||||
# ==================== Request/Response Models ====================
|
||||
|
||||
|
||||
class RegisterRequestModel(BaseModel):
|
||||
email: EmailStr
|
||||
password: str
|
||||
@@ -77,11 +76,16 @@ class ResetPasswordModel(BaseModel):
|
||||
|
||||
# ==================== API Endpoints ====================
|
||||
|
||||
@router.post("/register", response_model=RegisterResponseModel, status_code=status.HTTP_201_CREATED)
|
||||
|
||||
@router.post(
|
||||
"/register",
|
||||
response_model=RegisterResponseModel,
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
)
|
||||
async def register(request: RegisterRequestModel):
|
||||
"""
|
||||
用户注册
|
||||
|
||||
|
||||
- 邮箱必须唯一
|
||||
- 用户名必须唯一
|
||||
- 密码至少 8 位,包含大小写字母和数字
|
||||
@@ -89,22 +93,22 @@ async def register(request: RegisterRequestModel):
|
||||
"""
|
||||
container = get_container()
|
||||
use_case = container.get_register_user_use_case()
|
||||
|
||||
|
||||
req = RegisterUserRequest(
|
||||
email=request.email,
|
||||
password=request.password,
|
||||
username=request.username,
|
||||
display_name=request.display_name,
|
||||
)
|
||||
|
||||
|
||||
response, error = use_case.execute(req)
|
||||
|
||||
|
||||
if error:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=error,
|
||||
)
|
||||
|
||||
|
||||
return RegisterResponseModel(
|
||||
user_id=response.user_id,
|
||||
email=response.email,
|
||||
@@ -118,7 +122,7 @@ async def register(request: RegisterRequestModel):
|
||||
async def login(request: LoginRequestModel):
|
||||
"""
|
||||
用户登录
|
||||
|
||||
|
||||
- 使用邮箱和密码登录
|
||||
- 返回 access_token 和 refresh_token
|
||||
- access_token 有效期 30 分钟
|
||||
@@ -126,20 +130,20 @@ async def login(request: LoginRequestModel):
|
||||
"""
|
||||
container = get_container()
|
||||
use_case = container.get_login_use_case()
|
||||
|
||||
|
||||
req = LoginRequest(
|
||||
email=request.email,
|
||||
password=request.password,
|
||||
)
|
||||
|
||||
|
||||
response, error = use_case.execute(req)
|
||||
|
||||
|
||||
if error:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=error,
|
||||
)
|
||||
|
||||
|
||||
return LoginResponseModel(
|
||||
access_token=response.access_token,
|
||||
refresh_token=response.refresh_token,
|
||||
@@ -159,16 +163,16 @@ async def logout(
|
||||
):
|
||||
"""
|
||||
用户登出
|
||||
|
||||
|
||||
- 默认只登出当前设备
|
||||
- 设置 logout_all_devices=true 可登出所有设备
|
||||
"""
|
||||
container = get_container()
|
||||
use_case = container.get_logout_use_case()
|
||||
|
||||
|
||||
# 从 JWT token 中提取 session_id
|
||||
from packages.domain.auth import jwt_service
|
||||
|
||||
|
||||
# 从 request 中获取 token
|
||||
auth_header = request.headers.get("Authorization")
|
||||
session_id = None
|
||||
@@ -179,15 +183,15 @@ async def logout(
|
||||
session_id = payload.get("sid") # 从 payload 提取 session_id
|
||||
except:
|
||||
pass # token 无效或没有 session_id,继续使用 None
|
||||
|
||||
|
||||
req = LogoutRequest(
|
||||
user_id=current_user.id,
|
||||
session_id=session_id,
|
||||
logout_all_devices=logout_all_devices,
|
||||
)
|
||||
|
||||
|
||||
success, error = use_case.execute(req)
|
||||
|
||||
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
@@ -199,23 +203,23 @@ async def logout(
|
||||
async def verify_email(token: str):
|
||||
"""
|
||||
邮箱验证
|
||||
|
||||
|
||||
- 通过邮件中的链接访问此接口
|
||||
- 验证成功后标记邮箱为已验证
|
||||
"""
|
||||
container = get_container()
|
||||
use_case = container.get_verify_email_use_case()
|
||||
|
||||
|
||||
req = VerifyEmailRequest(token=token)
|
||||
|
||||
|
||||
success, error = use_case.execute(req)
|
||||
|
||||
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=error,
|
||||
)
|
||||
|
||||
|
||||
return {"message": "Email verified successfully"}
|
||||
|
||||
|
||||
@@ -223,18 +227,18 @@ async def verify_email(token: str):
|
||||
async def forgot_password(request: PasswordResetRequestModel):
|
||||
"""
|
||||
请求密码重置
|
||||
|
||||
|
||||
- 发送密码重置邮件
|
||||
- 邮件中包含重置链接(有效期 1 小时)
|
||||
- 即使邮箱不存在也返回成功(安全考虑)
|
||||
"""
|
||||
container = get_container()
|
||||
use_case = container.get_request_password_reset_use_case()
|
||||
|
||||
|
||||
req = RequestPasswordResetRequest(email=request.email)
|
||||
|
||||
|
||||
success, error = use_case.execute(req)
|
||||
|
||||
|
||||
# 不论成功失败都返回 202(安全考虑)
|
||||
return {"message": "Password reset email sent if account exists"}
|
||||
|
||||
@@ -243,24 +247,24 @@ async def forgot_password(request: PasswordResetRequestModel):
|
||||
async def reset_password(request: ResetPasswordModel):
|
||||
"""
|
||||
重置密码
|
||||
|
||||
|
||||
- 使用邮件中的 token 重置密码
|
||||
- 新密码必须符合密码强度要求
|
||||
"""
|
||||
container = get_container()
|
||||
use_case = container.get_reset_password_use_case()
|
||||
|
||||
|
||||
req = ResetPasswordRequest(
|
||||
token=request.token,
|
||||
new_password=request.new_password,
|
||||
)
|
||||
|
||||
|
||||
success, error = use_case.execute(req)
|
||||
|
||||
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=error,
|
||||
)
|
||||
|
||||
|
||||
return {"message": "Password reset successfully"}
|
||||
|
||||
Reference in New Issue
Block a user