Files
hive-manage-v3/backend/app/api/auth.py
T
2026-07-22 16:52:09 +08:00

75 lines
2.4 KiB
Python

"""Auth API: register, login, refresh, change-password."""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.config import settings
from app.database import get_db
from app.middleware.auth import require_auth
from app.models.user import User
from app.schemas.auth import (
ChangePasswordRequest,
LoginRequest,
RegisterRequest,
TokenResponse,
)
from app.schemas.user import UserResponse
from app.services.auth_service import (
authenticate_user,
create_access_token,
create_user,
decode_access_token,
get_user_by_username,
hash_password,
verify_password,
)
router = APIRouter(prefix="/api/v1/auth", tags=["auth"])
@router.post("/register", status_code=201, response_model=UserResponse)
async def register(body: RegisterRequest, db: AsyncSession = Depends(get_db)):
existing = await get_user_by_username(db, body.username)
if existing:
raise HTTPException(status_code=409, detail="Username already exists")
result = await db.execute(select(User).where(User.email == body.email))
if result.scalar_one_or_none():
raise HTTPException(status_code=409, detail="Email already exists")
user = await create_user(db, body.username, body.email, body.password)
return user
@router.post("/login", response_model=TokenResponse)
async def login(body: LoginRequest, db: AsyncSession = Depends(get_db)):
user = await authenticate_user(db, body.username, body.password)
token = create_access_token(user.id, user.role.value)
return TokenResponse(
access_token=token,
expires_in=settings.jwt_expire_minutes * 60,
)
@router.post("/refresh", response_model=TokenResponse)
async def refresh(user: User = Depends(require_auth)):
token = create_access_token(user.id, user.role.value)
return TokenResponse(
access_token=token,
expires_in=settings.jwt_expire_minutes * 60,
)
@router.post("/change-password")
async def change_password(
body: ChangePasswordRequest,
user: User = Depends(require_auth),
db: AsyncSession = Depends(get_db),
):
if not verify_password(body.old_password, user.hashed_password):
raise HTTPException(status_code=400, detail="Old password is incorrect")
user.hashed_password = hash_password(body.new_password)
await db.commit()
return {"detail": "Password changed successfully"}