from collections.abc import Iterable from fastapi import Depends, HTTPException, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from sqlalchemy.orm import Session from app.core.security import verify_access_token from app.db.database import get_db from app.models.user import User from app.repositories.user_repository import UserRepository bearer_scheme = HTTPBearer(auto_error=False) 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="Nicht authentifiziert", headers={"WWW-Authenticate": "Bearer"}, ) username = verify_access_token(credentials.credentials) user = UserRepository.get_by_username(db, username) if user is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Nicht authentifiziert", headers={"WWW-Authenticate": "Bearer"}, ) return user def get_current_active_user(current_user: User = Depends(get_current_user)) -> User: if not current_user.is_active: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Nicht authentifiziert", headers={"WWW-Authenticate": "Bearer"}, ) return current_user def get_user_permission_names(user: User) -> set[str]: if user.primary_role is None: return set() return {permission.name for permission in user.primary_role.permissions} def require_permission(permission: str): def dependency(current_user: User = Depends(get_current_active_user)) -> User: if permission not in get_user_permission_names(current_user): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Keine Berechtigung", ) return current_user return dependency def require_any_permission(permissions: Iterable[str]): permission_set = set(permissions) def dependency(current_user: User = Depends(get_current_active_user)) -> User: if get_user_permission_names(current_user).isdisjoint(permission_set): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Keine Berechtigung", ) return current_user return dependency def require_all_permissions(permissions: Iterable[str]): permission_set = set(permissions) def dependency(current_user: User = Depends(get_current_active_user)) -> User: if not permission_set.issubset(get_user_permission_names(current_user)): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Keine Berechtigung", ) return current_user return dependency