Spaces:
Sleeping
Sleeping
| # 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"]) | |
| 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" | |
| ) | |
| 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" | |
| ) |