""" web/dependencies.py — FastAPI dependency functions. get_current_user: reads the access_token cookie, decodes + validates it, loads the user row from web.db. Raises 401 if anything fails. require_role(min_role): returns a dependency that enforces a minimum RBAC level. """ from fastapi import Cookie, Depends, HTTPException, status from web import auth, db _ROLE_ORDER = ["reader", "admin", "superadmin"] def _role_rank(role: str) -> int: try: return _ROLE_ORDER.index(role) except ValueError: return -1 async def get_current_user( access_token: str | None = Cookie(default=None), ) -> db.sqlite3.Row: exc = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authenticated", headers={"WWW-Authenticate": "Bearer"}, ) if not access_token: raise exc payload = auth.decode_access_token(access_token) if payload is None: raise exc user = db.get_user_by_id(payload["sub"]) if user is None or not user["is_active"]: raise exc return user def require_role(min_role: str): """FastAPI dependency factory: ensures user role >= min_role.""" async def _dep(user=Depends(get_current_user)): if _role_rank(user["role"]) < _role_rank(min_role): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail=f"Requires role: {min_role}", ) return user return _dep