"""Bounded, non-sending diagnostics rendered only after platform authorization.""" from concurrent.futures import ThreadPoolExecutor from datetime import datetime, timezone from html import escape import json from urllib.request import Request, build_opener, HTTPRedirectHandler from urllib.error import HTTPError class NoRedirect(HTTPRedirectHandler): def redirect_request(self, *args, **kwargs): return None def sign_in_status(base): try: response = build_opener(NoRedirect()).open( base.rstrip("/") + "/readyz", timeout=5 ) except HTTPError as exc: response = exc with response: raw = response.read(16385) if len(raw) > 16384: raise ValueError("oversized status") return json.loads(raw) def check_services(oidc, delivery): def safe(call): try: return call() except Exception: return {} with ThreadPoolExecutor(max_workers=2) as pool: sign = pool.submit( safe, lambda: sign_in_status(oidc.backend_url) if oidc else {} ) mail = pool.submit( safe, lambda: delivery.mail_status() if hasattr(delivery, "mail_status") else {}, ) sign, mail = sign.result(), mail.result() values = {} sign_checks = sign.get("checks", []) if isinstance(sign, dict) else [] for row in sign_checks if isinstance(sign_checks, list) else []: if isinstance(row, dict): values[row.get("name")] = row.get("status") checks = [ ( "Directory sign-in", values.get("lldap"), "Sign-in and identity lookup", "Retry the check; if it still fails, ask the identity service owner to restore directory connectivity.", ), ( "Primary authentication", values.get("authelia"), "Fresh sign-in", "Retry after the authentication service recovers. Existing sessions do not prove new sign-in works.", ), ( "Authenticator provider", values.get("privacyidea"), "MFA verification and enrollment", "Retry after the MFA service recovers. Do not disable MFA to work around an outage.", ), ( "Factor-read credential", values.get("factor_reader"), "Enrollment decisions and MFA verification", "Renewal is automatic. A failure can mean expiry, lost permissions or projection failure; ask the credential owner to run the scoped renewal check.", ), ] statuses = mail.get("checks", {}) if isinstance(mail, dict) else {} if not isinstance(statuses, dict): statuses = {} checks += [ ( "Mail record store", statuses.get("database"), "Durable delivery tracking", "Restore the mail store before resuming delivery.", ), ( "SMTP authentication", statuses.get("smtp_authentication"), "Invitation and verification mail", "Check the configured mail lane. Use assisted password setup when the person cannot receive email.", ), ] rows = "" for name, status, impact, recovery in checks: label = { "ok": "Check passed", "failed": "Unavailable", "unconfigured": "Not configured", }.get(status, "Unknown — check unavailable") rows += ( "
Checked at " + escape(datetime.now(timezone.utc).isoformat(timespec="seconds")) + ". SMTP authentication may be cached for 30 seconds. These checks send no email and do not prove inbox receipt.
| Component | State | Affected journeys | Recovery |
|---|
" + escape(detail) + "