83 lines
2.5 KiB
Python
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"}
|