Squashed 'core/' content from commit 92ec910

git-subtree-dir: core
git-subtree-split: 92ec910a132e379a3a6e442a75bcb07cac0f0010
This commit is contained in:
Du Wenbo
2026-04-04 18:16:49 +08:00
commit d8e4449f10
227 changed files with 39179 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException, Request, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from pydantic import BaseModel
from app.core.database import get_db
from app.core.security import verify_password, create_access_token, hash_password
from app.core.deps import get_current_user
from app.models.user import User
from app.services.audit import log_audit
router = APIRouter(prefix="/auth", tags=["认证"])
class Token(BaseModel):
access_token: str
token_type: str = "bearer"
user: dict
class RegisterRequest(BaseModel):
username: str
password: str
full_name: str | None = None
email: str | None = None
phone: str | None = None
@router.post("/login", response_model=Token)
async def login(request: Request, form: OAuth2PasswordRequestForm = Depends(), db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User).where(User.username == form.username))
user = result.scalar_one_or_none()
if not user or not verify_password(form.password, user.hashed_password):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户名或密码错误")
if not user.is_active:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="账号已禁用")
user.last_login = datetime.now(timezone.utc)
token = create_access_token({"sub": str(user.id), "role": user.role})
client_ip = request.client.host if request.client else None
await log_audit(db, user.id, "login", "auth", detail=f"用户 {user.username} 登录", ip_address=client_ip)
return Token(
access_token=token,
user={"id": user.id, "username": user.username, "full_name": user.full_name, "role": user.role}
)
@router.get("/me")
async def get_me(user: User = Depends(get_current_user)):
return {
"id": user.id, "username": user.username, "full_name": user.full_name,
"email": user.email, "phone": user.phone, "role": user.role, "is_active": user.is_active,
}