"""Authentication endpoints.""" from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.auth.jwt import create_access_token from app.auth.repository import UserRepository from app.auth.schemas import TokenResponse, UserCreate, UserLogin, UserResponse from app.auth.security import validate_password_strength, verify_password from app.core.deps import get_current_user, get_db from app.database.models.user import User router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED) def register_user(user_data: UserCreate, db: Session = Depends(get_db)): """ Register a new user. Args: user_data: User registration data db: Database session Returns: Created user information Raises: HTTPException: If email already exists or password is weak """ repo = UserRepository(db) # Check if email already exists if repo.email_exists(user_data.email): raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="Email already registered" ) # Validate password strength is_valid, error_message = validate_password_strength(user_data.password) if not is_valid: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=error_message ) # Create user user = repo.create_user(email=user_data.email, password=user_data.password) return UserResponse.from_orm(user) @router.post("/login", response_model=TokenResponse) def login_user(login_data: UserLogin, db: Session = Depends(get_db)): """ Login user and return JWT token. Args: login_data: Login credentials db: Database session Returns: JWT access token and user information Raises: HTTPException: If credentials are invalid """ repo = UserRepository(db) # Get user by email user = repo.get_user_by_email(login_data.email) # Verify user exists and password is correct if not user or not verify_password(login_data.password, user.password_hash): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect email or password", headers={"WWW-Authenticate": "Bearer"}, ) # Check if user is active if not user.is_active: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="User account is deactivated" ) # Create access token access_token = create_access_token(user_id=user.id, email=user.email) return TokenResponse( access_token=access_token, token_type="bearer", user=UserResponse.from_orm(user) ) @router.get("/me", response_model=UserResponse) def get_current_user_info(current_user: User = Depends(get_current_user)): """ Get current authenticated user information. Args: current_user: Current authenticated user (from JWT) Returns: Current user information """ return UserResponse.from_orm(current_user)