aps-agent/server/auth/context.py

52 lines
1.3 KiB
Python

from __future__ import annotations
from contextvars import ContextVar, Token
from dataclasses import asdict, dataclass
@dataclass(frozen=True, slots=True)
class IdentityContext:
user_id: int
username: str
fullname: str
tenant_uuid: str
roles: tuple[str, ...] = ()
expires_at: int | None = None
auth_kind: str = "user"
license_type: str | None = None
license_activated_at: int | None = None
license_expires_at: int | None = None
activation_id: str | None = None
def to_dict(self) -> dict:
data = asdict(self)
data["roles"] = list(self.roles)
return data
_identity: ContextVar[IdentityContext | None] = ContextVar("aps_identity", default=None)
def bind_identity(identity: IdentityContext) -> Token:
return _identity.set(identity)
def reset_identity(token: Token) -> None:
_identity.reset(token)
def get_identity(*, required: bool = False) -> IdentityContext:
identity = _identity.get()
if identity is not None:
return identity
if required:
raise RuntimeError("authenticated identity is required")
# Direct domain tests and maintenance scripts do not run inside an HTTP request.
return IdentityContext(
user_id=0,
username="system",
fullname="System",
tenant_uuid="platform",
roles=("system",),
)