from fastapi import Depends, HTTPException, status, Query from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from sqlalchemy.orm import Session from jose import JWTError, jwt from database import get_db, SECRET_KEY, ALGORITHM from models import User security = HTTPBearer() async def get_current_user( credentials: HTTPAuthorizationCredentials = Depends(security), db: Session = Depends(get_db) ) -> User: """Validate JWT token and return current user.""" token = credentials.credentials credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired token", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) user_id_str = payload.get("sub") if user_id_str is None: raise credentials_exception try: user_id = int(user_id_str) except (ValueError, TypeError): raise credentials_exception except JWTError: raise credentials_exception user = db.query(User).filter(User.id == user_id, User.is_active == True).first() if user is None: raise credentials_exception return user async def get_current_admin(current_user: User = Depends(get_current_user)) -> User: """Ensure current user is an admin.""" if current_user.role != "admin": raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin access required" ) return current_user async def get_current_user_from_query( token: str = Query(...), db: Session = Depends(get_db) ) -> User: """Validate JWT token from query parameter and return current user.""" credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired token", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) user_id_str = payload.get("sub") if user_id_str is None: raise credentials_exception user_id = int(user_id_str) except (JWTError, ValueError, TypeError): raise credentials_exception user = db.query(User).filter(User.id == user_id, User.is_active == True).first() if user is None: raise credentials_exception return user