merge testing->tomerge/main #7

Open
anti wants to merge 242 commits from testing into tomerge/main
Showing only changes of commit de4b64d857 - Show all commits

View File

@@ -105,13 +105,26 @@ async def get_current_user_unchecked(request: Request) -> str:
def require_role(*allowed_roles: str): def require_role(*allowed_roles: str):
"""Factory that returns a FastAPI dependency enforcing role membership. """Factory that returns a FastAPI dependency enforcing role membership.
The returned dependency chains from ``get_current_user`` (JWT + must_change_password) Inlines JWT decode + user lookup + must_change_password + role check so the
then verifies the user's role is in *allowed_roles*. Returns the full user dict so user is only loaded from the DB once per request (not once in
endpoints can inspect ``user["uuid"]``, ``user["role"]``, etc. without a second lookup. ``get_current_user`` and again here). Returns the full user dict so
endpoints can inspect ``user["uuid"]``, ``user["role"]``, etc.
""" """
async def _check(current_user: str = Depends(get_current_user)) -> dict: async def _check(request: Request) -> dict:
user = await repo.get_user_by_uuid(current_user) user_uuid = await _decode_token(request)
if not user or user["role"] not in allowed_roles: user = await repo.get_user_by_uuid(user_uuid)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
if user.get("must_change_password"):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Password change required before accessing this resource",
)
if user["role"] not in allowed_roles:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, status_code=status.HTTP_403_FORBIDDEN,
detail="Insufficient permissions", detail="Insufficient permissions",