Spaces:
Runtime error
Runtime error
| from fastapi import APIRouter, Depends, HTTPException, status | |
| from sqlalchemy.orm import Session | |
| from app.database.connection import get_db | |
| from app.schemas.auth import UserCreate, UserLogin, UserResponse, TokenResponse | |
| from app.services.auth_service import AuthService | |
| from app.middleware.auth import get_current_user | |
| from app.database.models import User | |
| from app.utils.validators import validate_email, validate_password | |
| router = APIRouter(prefix="/api", tags=["auth"]) | |
| async def signup(user_data: UserCreate, db: Session = Depends(get_db)): | |
| """ | |
| Create a new user account. | |
| Args: | |
| user_data: User registration data | |
| db: Database session | |
| Returns: | |
| Access and refresh tokens with user info | |
| Raises: | |
| HTTPException: If email is invalid or already registered | |
| """ | |
| print(f"[SIGNUP] Received signup request for email: {user_data.email}") | |
| # Validate email | |
| if not validate_email(user_data.email): | |
| print(f"[SIGNUP] Invalid email format: {user_data.email}") | |
| raise HTTPException( | |
| status_code=status.HTTP_400_BAD_REQUEST, | |
| detail="Invalid email format" | |
| ) | |
| # Validate password | |
| is_valid, error_msg = validate_password(user_data.password) | |
| if not is_valid: | |
| print(f"[SIGNUP] Password validation failed: {error_msg}") | |
| raise HTTPException( | |
| status_code=status.HTTP_400_BAD_REQUEST, | |
| detail=error_msg | |
| ) | |
| try: | |
| # Create user | |
| print(f"[SIGNUP] Creating user...") | |
| user = AuthService.create_user( | |
| db=db, | |
| email=user_data.email, | |
| password=user_data.password, | |
| name=user_data.name | |
| ) | |
| print(f"[SIGNUP] User created successfully: {user.id}") | |
| # Generate tokens | |
| tokens = AuthService.generate_tokens(user) | |
| print(f"[SIGNUP] Tokens generated successfully") | |
| return TokenResponse( | |
| access_token=tokens["access_token"], | |
| refresh_token=tokens["refresh_token"], | |
| user=UserResponse.from_orm(user) | |
| ) | |
| except ValueError as e: | |
| print(f"[SIGNUP] ValueError: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_400_BAD_REQUEST, | |
| detail=str(e) | |
| ) | |
| except Exception as e: | |
| print(f"[SIGNUP] Unexpected error: {type(e).__name__}: {str(e)}") | |
| import traceback | |
| traceback.print_exc() | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail="An error occurred during signup" | |
| ) | |
| async def login(credentials: UserLogin, db: Session = Depends(get_db)): | |
| """ | |
| Authenticate user and return tokens. | |
| Args: | |
| credentials: User login credentials | |
| db: Database session | |
| Returns: | |
| Access and refresh tokens with user info | |
| Raises: | |
| HTTPException: If credentials are invalid | |
| """ | |
| # Authenticate user | |
| user = AuthService.authenticate_user( | |
| db=db, | |
| email=credentials.email, | |
| password=credentials.password | |
| ) | |
| if not user: | |
| raise HTTPException( | |
| status_code=status.HTTP_401_UNAUTHORIZED, | |
| detail="Incorrect email or password" | |
| ) | |
| # Generate tokens | |
| tokens = AuthService.generate_tokens(user) | |
| return TokenResponse( | |
| access_token=tokens["access_token"], | |
| refresh_token=tokens["refresh_token"], | |
| user=UserResponse.from_orm(user) | |
| ) | |
| async def check_auth(current_user: User = Depends(get_current_user)): | |
| """ | |
| Verify authentication token and return user info. | |
| Args: | |
| current_user: Current authenticated user | |
| Returns: | |
| User information | |
| Raises: | |
| HTTPException: If token is invalid or expired | |
| """ | |
| return UserResponse.from_orm(current_user) | |
| async def google_auth( | |
| request: dict, | |
| db: Session = Depends(get_db) | |
| ): | |
| """ | |
| Authenticate user with Google OAuth and return JWT tokens. | |
| Args: | |
| request: Dictionary with 'credential' field (Google JWT token) | |
| db: Database session | |
| Returns: | |
| Access and refresh JWT tokens with user info | |
| Raises: | |
| HTTPException: If Google token is invalid | |
| """ | |
| from app.config.settings import settings | |
| print(f"[GOOGLE AUTH] Received Google OAuth request") | |
| try: | |
| credential = request.get("credential") | |
| if not credential: | |
| raise HTTPException( | |
| status_code=status.HTTP_400_BAD_REQUEST, | |
| detail="Google credential is required" | |
| ) | |
| print(f"[GOOGLE AUTH] Verifying Google token...") | |
| # Verify Google token and get user info | |
| google_data = await AuthService.verify_google_token( | |
| credential=credential, | |
| client_id=settings.GOOGLE_CLIENT_ID | |
| ) | |
| print(f"[GOOGLE AUTH] Token verified for email: {google_data['email']}") | |
| # Create or get user | |
| user = AuthService.create_user_from_google( | |
| db=db, | |
| google_id=google_data["google_id"], | |
| email=google_data["email"], | |
| name=google_data.get("name") | |
| ) | |
| print(f"[GOOGLE AUTH] User created/retrieved: {user.id}") | |
| # Generate JWT tokens (same as email/password login) | |
| tokens = AuthService.generate_tokens(user) | |
| print(f"[GOOGLE AUTH] JWT tokens generated successfully") | |
| return TokenResponse( | |
| access_token=tokens["access_token"], | |
| refresh_token=tokens["refresh_token"], | |
| user=UserResponse.from_orm(user) | |
| ) | |
| except ValueError as e: | |
| print(f"[GOOGLE AUTH] ValueError: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_400_BAD_REQUEST, | |
| detail=str(e) | |
| ) | |
| except Exception as e: | |
| print(f"[GOOGLE AUTH] Unexpected error: {type(e).__name__}: {str(e)}") | |
| import traceback | |
| traceback.print_exc() | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail="Failed to authenticate with Google" | |
| ) | |