"""Diagnose Cloudflare API auth without printing secrets.""" from __future__ import annotations import os import sys import urllib.error import urllib.request from pathlib import Path STAGED = Path(__file__).resolve().parents[1] / ".refresh" / "cf_creds.env" def load_staged() -> None: if not STAGED.is_file(): return for line in STAGED.read_text(encoding="utf-8").splitlines(): if "=" not in line or line.startswith("#"): continue k, v = line.split("=", 1) os.environ.setdefault(k.strip(), v.strip()) def probe(path: str, email: str, key: str) -> None: req = urllib.request.Request( "https://api.cloudflare.com/client/v4" + path, headers={ "X-Auth-Email": email, "X-Auth-Key": key, "User-Agent": "climperor-cf-diag", }, ) try: with urllib.request.urlopen(req, timeout=45) as resp: body = resp.read(120).decode("utf-8", errors="replace") print(f"{path} -> {resp.status} ray={resp.headers.get('cf-ray')} body={body[:80]!r}") except urllib.error.HTTPError as e: raw = e.read(200).decode("utf-8", errors="replace") print( f"{path} -> HTTP {e.code} ray={e.headers.get('cf-ray') if e.headers else None} " f"body={raw[:120]!r}" ) except Exception as e: print(f"{path} -> {type(e).__name__}: {e}") def main() -> int: load_staged() email = os.environ.get("CLOUDFLARE_EMAIL") or os.environ.get( "KEYZOO_ASSET_META_USERNAME" ) key = os.environ.get("CLOUDFLARE_API_KEY") or os.environ.get( "KEYZOO_ASSET_SECRET_GLOBAL_API_KEY" ) if not email or not key: print("missing credentials") return 2 print(f"email_len={len(email)} key_len={len(key)} email_has_at={'@' in email}") for path in ("/user", "/accounts", "/user/tokens/verify"): probe(path, email, key) return 0 if __name__ == "__main__": raise SystemExit(main())