Source code for loom.core.identity.context

"""Active caller-identity context guard.

Provides a ``contextvars.ContextVar`` that propagates the verified caller
across the async execution stack — from the transport that authenticated the
request down to the layer that takes an authorization decision.

Rules:
    - Only the transport layer (HTTP middleware, Celery worker, test harness)
      calls :func:`set_identity` / :func:`reset_identity`.
    - Any layer may call :func:`current_identity` without introducing upward
      coupling.
    - The token returned by :func:`set_identity` **must** be passed to
      :func:`reset_identity` in a ``finally`` block: without it, a reused
      worker task inherits the previous caller's identity.
"""

from __future__ import annotations

from contextvars import ContextVar, Token

from loom.core.identity.identity import ANONYMOUS, Identity

_identity: ContextVar[Identity] = ContextVar("_identity", default=ANONYMOUS)


[docs] def current_identity() -> Identity: """Return the identity active in the current async context. Never returns ``None``: contexts with no authenticated caller yield :data:`~loom.core.identity.identity.ANONYMOUS`, so consumers cannot accidentally treat "unknown" as "authorized". Returns: The active identity, or the anonymous one. """ return _identity.get()
[docs] def set_identity(identity: Identity) -> Token[Identity]: """Install *identity* for the current async context. Args: identity: Verified identity produced by an authentication mechanism. Returns: A :class:`~contextvars.Token` that must be passed to :func:`reset_identity` in a ``finally`` block. Example:: token = set_identity(identity) try: await handle_request() finally: reset_identity(token) """ return _identity.set(identity)
[docs] def reset_identity(token: Token[Identity]) -> None: """Restore the identity active before the matching :func:`set_identity`. Args: token: Token returned by the corresponding :func:`set_identity` call. """ _identity.reset(token)