40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
import logging
|
|
|
|
from fastapi import HTTPException
|
|
|
|
from ..util import permutil
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def verify(auth: str | None, perm: list[str], match=permutil.has_all):
|
|
"""Validate session token and optional list of required permissions.
|
|
|
|
Returns the session context.
|
|
|
|
Raises HTTPException on failure:
|
|
401: unauthenticated / invalid session
|
|
403: required permissions missing
|
|
"""
|
|
if not auth:
|
|
raise HTTPException(status_code=401, detail="Authentication required")
|
|
|
|
ctx = await permutil.session_context(auth)
|
|
if not ctx:
|
|
raise HTTPException(status_code=401, detail="Session not found")
|
|
|
|
if not match(ctx, perm):
|
|
# Determine which permissions are missing for clearer diagnostics
|
|
missing = sorted(set(perm) - set(ctx.role.permissions))
|
|
logger.warning(
|
|
"Permission denied: user=%s role=%s missing=%s required=%s granted=%s", # noqa: E501
|
|
getattr(ctx.user, "uuid", "?"),
|
|
getattr(ctx.role, "display_name", "?"),
|
|
missing,
|
|
perm,
|
|
ctx.role.permissions,
|
|
)
|
|
raise HTTPException(status_code=403, detail="Permission required")
|
|
|
|
return ctx
|