jawadsaghir12's picture
Add application file
a8a2cf5
# src/api/routes/auth.py
from fastapi import APIRouter, HTTPException, status, Depends, Request
from sqlmodel.ext.asyncio.session import AsyncSession
from ...models import UserCreate, UserLogin, Token, UserResponse
from ...core.dependencies import create_access_token
from ...services.user_service import UserService
from ...db.database import get_session
import logging
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/auth", tags=["Authentication"])
@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def register(user_data: UserCreate, session: AsyncSession = Depends(get_session)):
"""
Register a new user.
Args:
user_data: User registration data (email, name, password)
Returns:
UserResponse with created user data
Raises:
HTTPException 400: If email already exists
HTTPException 500: If database operation fails
"""
try:
# Attempt to create user
user = await UserService.create_user(user_data, session)
if user is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Email already registered"
)
logger.info(f"New user registered: {user.email}")
return user
except HTTPException:
raise
except Exception as e:
logger.error(f"Registration error: {e}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to register user"
)
@router.post("/login", response_model=Token)
async def login(credentials: UserLogin, request: Request, session: AsyncSession = Depends(get_session)):
"""
Login and get access token.
Args:
credentials: User login credentials (email, password)
request: FastAPI request object (for IP and user agent)
Returns:
Token with JWT access token
Raises:
HTTPException 401: If credentials are invalid
HTTPException 500: If database operation fails
"""
try:
# Verify credentials
user = await UserService.verify_credentials(
credentials.email,
credentials.password,
session,
)
if user is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid email or password"
)
# Log the login session
ip_address = request.client.host if request.client else None
user_agent = request.headers.get("user-agent")
session_id = await UserService.log_login(
user_id=user['id'],
session=session,
ip_address=ip_address,
user_agent=user_agent,
)
# Create JWT token with session ID
token = create_access_token(
user_id=user['id'],
email=user['email']
)
logger.info(f"User logged in: {user['email']}, session: {session_id}")
return Token(access_token=token)
except HTTPException:
raise
except Exception as e:
logger.error(f"Login error: {e}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to login"
)