from collections.abc import Generator from fastapi import Depends, HTTPException, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from sqlalchemy.orm import Session import jwt from app.core.database import SessionLocal from app.core.security import decode_access_token from app.models.user import User bearer_scheme = HTTPBearer(auto_error=False) def get_db() -> Generator[Session, None, None]: db = SessionLocal() try: yield db finally: db.close() def get_current_user( credentials: HTTPAuthorizationCredentials | None = Depends(bearer_scheme), db: Session = Depends(get_db), ) -> User: if credentials is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authenticated", ) try: payload = decode_access_token(credentials.credentials) user_id = int(payload["sub"]) except (KeyError, ValueError, TypeError, jwt.PyJWTError): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token", ) from None user = db.get(User, user_id) if user is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found", ) return user def get_current_admin_user( current_user: User = Depends(get_current_user), ) -> User: if not current_user.is_admin: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin access required", ) return current_user