Spaces:
Sleeping
Sleeping
File size: 1,431 Bytes
990895d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | """Provide FastAPI dependencies for protected routes.
Session validity is checked against expiry and durable session version.
"""
import time
from typing import Any
from fastapi import HTTPException, Request, status
from app.models import StoredConfig
def api_http_error(status_code: int, code: str, message: str) -> HTTPException:
"""Create an HTTP exception understood by the envelope handler."""
return HTTPException(
status_code=status_code,
detail={"code": code, "message": message},
)
def require_login(request: Request) -> StoredConfig:
"""Require a current signed session and return durable config."""
config: StoredConfig | None = request.app.state.config_store.load()
if config is None:
raise api_http_error(
status.HTTP_503_SERVICE_UNAVAILABLE,
"setup_required",
"Application setup is required",
)
session: dict[str, Any] = request.session
authenticated = session.get("auth") is True
version_matches = session.get("sv") == config.session_version
expiry = session.get("exp")
unexpired = isinstance(expiry, (int, float)) and expiry >= time.time()
if not (authenticated and version_matches and unexpired):
request.session.clear()
raise api_http_error(
status.HTTP_401_UNAUTHORIZED,
"unauthorized",
"Login required",
)
return config
|