"""FastAPI dependencies för auth och databas.""" from typing import Optional from uuid import UUID from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.database import get_db from app.models import User, UserRole, UserStatus from app.schemas import TokenPayload from app.security import decode_token oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/login") async def get_current_user( token: str = Depends(oauth2_scheme), db: AsyncSession = Depends(get_db), ) -> User: credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) payload = decode_token(token) if payload is None or payload.get("type") != "access": raise credentials_exception user_id: Optional[str] = payload.get("sub") if user_id is None: raise credentials_exception result = await db.execute(select(User).where(User.id == UUID(user_id))) user = result.scalar_one_or_none() if user is None: raise credentials_exception if user.status != UserStatus.ACTIVE: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="User account is inactive or pending", ) return user async def get_current_active_superuser( current_user: User = Depends(get_current_user), ) -> User: if not current_user.is_superuser: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Superuser privilege required", ) return current_user class RoleChecker: def __init__(self, min_role: UserRole): self.min_role = min_role async def __call__(self, current_user: User = Depends(get_current_user)) -> User: from app.security import role_level if role_level(current_user.role) < role_level(self.min_role): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail=f"Requires role {self.min_role.value} or higher", ) return current_user require_admin = RoleChecker(UserRole.ADMIN) require_manager = RoleChecker(UserRole.MANAGER) require_analyst = RoleChecker(UserRole.ANALYST)