from __future__ import annotations from typing import Annotated from fastapi import APIRouter, Depends, Request, status from sqlalchemy.orm import Session from app.api.dependencies import get_current_user from app.core.exceptions import UnauthorizedError from app.core.rate_limit import login_rate_limiter from app.db.session import get_db from app.models.user import User from app.schemas.auth import LoginRequest, TokenResponse, UserCreate, UserResponse from app.services.auth_service import AuthService router = APIRouter() @router.post( "/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED, summary="Register a customer account", ) def register_user( payload: UserCreate, db: Annotated[Session, Depends(get_db)], ) -> UserResponse: user = AuthService(db).register_user(payload) return UserResponse.model_validate(user) @router.post( "/login", response_model=TokenResponse, status_code=status.HTTP_200_OK, summary="Authenticate and receive a JWT access token", ) def login( payload: LoginRequest, request: Request, db: Annotated[Session, Depends(get_db)], ) -> TokenResponse: client_host = request.client.host if request.client else "unknown" throttle_key = login_rate_limiter.build_key(payload.username, client_host) if login_rate_limiter.is_limited(throttle_key): login_rate_limiter.raise_limit_exceeded() try: access_token = AuthService(db).authenticate_user(payload) except UnauthorizedError: login_rate_limiter.record_failure(throttle_key) raise login_rate_limiter.reset(throttle_key) return TokenResponse(access_token=access_token) @router.get( "/me", response_model=UserResponse, status_code=status.HTTP_200_OK, summary="Get the authenticated user profile", ) def get_me( current_user: Annotated[User, Depends(get_current_user)], ) -> UserResponse: return UserResponse.model_validate(current_user)