import secrets from fastapi import HTTPException, Request, status def configured_token(app) -> str: runtime = getattr(app.state, "runtime", None) return runtime.settings.chart_auth_token if runtime else "" def token_matches(app, presented: str) -> bool: """True when the caller may proceed. An empty CHART_AUTH_TOKEN leaves everything open, which is what local development wants — the check only engages once a token is configured. """ want = configured_token(app) if not want: return True return secrets.compare_digest(presented or "", want) def require_token(request: Request) -> None: presented = request.headers.get("x-chart-token") or request.query_params.get("token", "") if not token_matches(request.app, presented): raise HTTPException( status.HTTP_401_UNAUTHORIZED, "Missing or invalid chart token", headers={"WWW-Authenticate": "X-Chart-Token"}, )