""" Dépendances FastAPI """ from fastapi import Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from sqlalchemy.orm import Session from typing import Generator from app.core.security import decode_access_token from app.db.session import SessionLocal from app.db.repositories.user_repo import UserRepository def get_db() -> Generator[Session, None, None]: """Dependency pour obtenir une session DB""" db = SessionLocal() try: yield db finally: db.close() security = HTTPBearer() async def get_current_user( token: str = None, credentials: HTTPAuthorizationCredentials = Depends(HTTPBearer(auto_error=False)), db: Session = Depends(get_db) ): """Récupère l'utilisateur courant depuis le token JWT (Supporte Header Bearer et Query Param)""" token_str = None if credentials: token_str = credentials.credentials elif token: token_str = token if not token_str: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Authentication required" ) payload = decode_access_token(token_str) if payload is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token" ) user_id = payload.get("sub") if user_id is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token" ) # If it's a demo token, bypass DB lookup if payload.get("demo"): class MockUser: def __init__(self, id, email, name): self.id = id self.email = email self.name = name self.institution = "Demo" self.role = "Researcher" self.is_admin = False self.credits = 2000 return MockUser(user_id, "demo@example.com", "Demo User") user_repo = UserRepository(db) try: user = user_repo.get_by_id(user_id) if user: # Automatiquement vérifier le refill à chaque accès user = user_repo.check_and_refill_credits(user) except Exception as e: # If DB is down, we can't verify the user unless it's a demo token from app.core.logging import logger logger.error(f"Database error in get_current_user: {e}") raise HTTPException( status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Database connection failed. Please use Demo Mode." ) if user is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found" ) return user async def get_admin_user( current_user = Depends(get_current_user) ): """Vérifie que l'utilisateur est admin""" if not current_user.is_admin: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin access required" ) return current_user