42 lines
1.7 KiB
Python
42 lines
1.7 KiB
Python
from fastapi import APIRouter, HTTPException, Request, status
|
|
|
|
from app.core.deps import CurrentUser, DbSession, SettingsDep
|
|
from app.core.rate_limit import enforce_rate_limit
|
|
from app.core.security import create_user_access_token
|
|
from app.models.user import User
|
|
from app.schemas.auth import LoginRequest, RegisterRequest, Token, UserPublic
|
|
from app.services.users import EmailAlreadyRegisteredError, authenticate_user, register_user
|
|
|
|
router = APIRouter(prefix="/auth", tags=["auth"])
|
|
|
|
|
|
@router.post("/register", response_model=Token, status_code=status.HTTP_201_CREATED)
|
|
def register(body: RegisterRequest, request: Request, db: DbSession, settings: SettingsDep) -> Token:
|
|
enforce_rate_limit(request, scope="auth_register", limit=10, window_seconds=60)
|
|
try:
|
|
user = register_user(db, body)
|
|
except EmailAlreadyRegisteredError:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_409_CONFLICT,
|
|
detail="An account with this email already exists",
|
|
)
|
|
token = create_user_access_token(user.id, settings)
|
|
return Token(access_token=token)
|
|
|
|
|
|
@router.post("/login", response_model=Token)
|
|
def login(body: LoginRequest, request: Request, db: DbSession, settings: SettingsDep) -> Token:
|
|
enforce_rate_limit(request, scope="auth_login", limit=20, window_seconds=60)
|
|
user = authenticate_user(db, body.email, body.password)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="Invalid credentials",
|
|
)
|
|
token = create_user_access_token(user.id, settings)
|
|
return Token(access_token=token)
|
|
|
|
|
|
@router.get("/me", response_model=UserPublic)
|
|
def me(user: CurrentUser) -> User:
|
|
return user
|