import logging import secrets import time logger = logging.getLogger(__name__) MAX_ATTEMPTS = 5 CODE_TTL_SECONDS = 600 class WebexPairing: id_label = "webexPersonId" def __init__(self): self._codes: dict[str, dict] = {} async def generate_code(self, peer_id: str) -> str: code = f"{secrets.randbelow(1_000_000):06d}" self._codes[peer_id] = { "code": code, "attempts": 0, "expires_at": time.monotonic() + CODE_TTL_SECONDS, } logger.info("Generated pairing code for peer %s (expires in %ds)", peer_id, CODE_TTL_SECONDS) return code async def verify_code(self, peer_id: str, code: str) -> bool: entry = self._codes.pop(peer_id, None) if entry is None: return False if time.monotonic() > entry["expires_at"]: return False if entry["attempts"] >= MAX_ATTEMPTS: return False entry["attempts"] += 1 if entry["code"] != code: self._codes[peer_id] = entry return False return True def normalize_allow_entry(self, entry: str) -> str: for prefix in ("webex:",): if entry.startswith(prefix): return entry[len(prefix) :] return entry async def notify_approval(self, config, peer_id, account_id=None): logger.info("Webex pairing approved for peer %s", peer_id)