"""Short-lived single-use tokens for Desk → Console SSO (Spec 019/035).""" from __future__ import annotations import secrets import time from threading import Lock _HANDOFF: dict[str, dict] = {} _LOCK = Lock() TTL_SEC = 120 def create_handoff(username: str, role: str) -> tuple[str, int]: token = secrets.token_urlsafe(32) exp = time.time() + TTL_SEC with _LOCK: _purge_expired_locked() _HANDOFF[token] = {"username": username, "role": role, "exp": exp} return token, TTL_SEC def consume_handoff(token: str) -> dict | None: with _LOCK: rec = _HANDOFF.pop(token.strip(), None) _purge_expired_locked() if not rec or rec["exp"] < time.time(): return None return rec def _purge_expired_locked() -> None: now = time.time() for key in [k for k, v in _HANDOFF.items() if v["exp"] < now]: del _HANDOFF[key]