archive-backend/routers/auth.py
2026-11-07 19:35:15 +00:00

83 lines
2.5 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, Request, Response
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from core.authx import auth
from core.db import get_db
from core.security import hash_password, verify_password
from models.users import User
from schemas.user_schema import UserCreate, UserLogin, UserRead
router = APIRouter(prefix="/auth", tags=["auth"])
@router.post("/register", response_model=UserRead, status_code=201)
async def register(
data: UserCreate,
response: Response,
db: AsyncSession = Depends(get_db), # noqa: B008
):
existing = await db.execute(select(User).where(User.username == data.username))
if existing.scalar_one_or_none():
raise HTTPException(400, "Username already taken")
user = User(
username=data.username,
hashed_password=hash_password(data.password),
isAdmin=False,
)
db.add(user)
await db.commit()
await db.refresh(user)
access = auth.create_access_token(uid=user.username)
refresh = auth.create_refresh_token(uid=user.username)
auth.set_access_cookies(access, response)
auth.set_refresh_cookies(refresh, response)
return user
@router.post("/login", response_model=UserRead)
async def login(
data: UserLogin,
response: Response,
db: AsyncSession = Depends(get_db), # noqa: B008
):
result = await db.execute(select(User).where(User.username == data.username))
user = result.scalar_one_or_none()
if not user or not verify_password(data.password, user.hashed_password):
raise HTTPException(401, "Invalid credentials")
access = auth.create_access_token(uid=user.username)
refresh = auth.create_refresh_token(uid=user.username)
auth.set_access_cookies(access, response)
auth.set_refresh_cookies(refresh, response)
return user
@router.post("/refresh")
async def refresh(
request: Request,
response: Response,
db: AsyncSession = Depends(get_db), # noqa: B008
):
payload = await auth.get_refresh_token_from_request(request)
result = await db.execute(select(User).where(User.username == payload.sub))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(401, "User not found")
new_access = auth.create_access_token(uid=user.username)
auth.set_access_cookies(new_access, response)
return {"status": "ok"}
@router.post("/logout")
async def logout(response: Response):
auth.unset_cookies(response)
return {"status": "ok"}