"""Attribution for quote_events.actor — the VERIFIED user, not the raw token. Historically this stored the bearer token string verbatim (unverifiable and a token leak into the database). All routes that use it now sit behind the global JWT dependency, so the token is resolved to the authenticated user and the display name is recorded instead. """ from fastapi import Depends, Request from sqlalchemy.ext.asyncio import AsyncSession from app.auth import get_optional_user from app.db.engine import get_db async def get_actor(request: Request, db: AsyncSession = Depends(get_db)) -> str | None: """Resolve the caller's display name from the Casdoor Bearer token.""" ctx = await get_optional_user(request, db) if ctx is not None: return ctx.display_name # Dev-mode header fallback (only active when DEV_LOGIN_ENABLED) carries # the name in X-User-Name / X-User-Name-B64 — keep attribution useful. name = request.headers.get("x-user-name") import base64 b64 = request.headers.get("x-user-name-b64") if b64: try: name = base64.b64decode(b64.encode()).decode("utf-8") except Exception: pass return name