""" Authentication API endpoints """ from datetime import timedelta from typing import List from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from models import get_db, User from models.utils import get_user_by_email, create_user from api.auth import ( authenticate_user, create_access_token, get_password_hash, ACCESS_TOKEN_EXPIRE_MINUTES, get_current_active_user ) from api.schemas import UserLogin, UserRegister, Token, UserResponse, BaseResponse router = APIRouter(prefix="/auth", tags=["Authentication"]) @router.post("/login", response_model=Token) async def login(user_credentials: UserLogin, db: Session = Depends(get_db)): """ Authenticate user and return JWT token """ user = authenticate_user(db, user_credentials.email, user_credentials.password) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect email or password", headers={"WWW-Authenticate": "Bearer"}, ) access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( data={"sub": user.email}, expires_delta=access_token_expires ) return { "access_token": access_token, "token_type": "bearer", "expires_in": ACCESS_TOKEN_EXPIRE_MINUTES * 60, # seconds "user": user.to_dict() } @router.post("/register", response_model=UserResponse) async def register(user_data: UserRegister, db: Session = Depends(get_db)): """ Register a new user """ # Check if user already exists if get_user_by_email(db, user_data.email): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Email already registered" ) # Create new user hashed_password = get_password_hash(user_data.password) user_dict = user_data.dict() user_dict.pop("password") user_dict["password_hash"] = hashed_password user_dict["is_email_verified"] = False user = create_user(db, user_dict) return user @router.get("/me", response_model=UserResponse) async def get_current_user_info(current_user: User = Depends(get_current_active_user)): """ Get current user information """ return current_user @router.post("/logout", response_model=BaseResponse) async def logout(current_user: User = Depends(get_current_active_user)): """ Logout user (client should remove token) """ return {"success": True, "message": "Successfully logged out"} @router.post("/refresh", response_model=Token) async def refresh_token(current_user: User = Depends(get_current_active_user)): """ Refresh JWT token """ access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( data={"sub": current_user.email}, expires_delta=access_token_expires ) return { "access_token": access_token, "token_type": "bearer", "expires_in": ACCESS_TOKEN_EXPIRE_MINUTES * 60, "user": current_user.to_dict() } @router.get("/users/interviewers") async def get_interviewers( db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """ Get all users with interviewer or recruiter roles """ from sqlalchemy import or_ try: users = db.query(User).filter( or_( User.role.in_(["INTERVIEWER", "RECRUITER", "interviewer", "recruiter"]), User.role.in_(["ADMIN", "admin"]) # Admins can also conduct interviews ) ).all() # Convert to dict to avoid Pydantic serialization issues return [user.to_dict() for user in users] except Exception as e: print(f"Error in get_interviewers: {str(e)}") import traceback traceback.print_exc() raise