"""Exercise the installed HTTP entrypoint with metadata-only output. Port 8080 must be free.""" import argparse, json, os, socket, subprocess, sys, time from urllib.request import build_opener, HTTPRedirectHandler, ProxyHandler, Request from urllib.error import HTTPError, URLError from urllib.parse import urlsplit, parse_qs from pathlib import Path parser = argparse.ArgumentParser(description="Local auth-shell smoke; never follows the issuer redirect.") parser.add_argument("--receipt", type=Path) args = parser.parse_args() class NoRedirect(HTTPRedirectHandler): def redirect_request(self, *args): return None opener = build_opener(ProxyHandler({}), NoRedirect()) with socket.socket() as sock: sock.bind(("127.0.0.1", 8080)) env = {**os.environ, "INFD_KEYCAPE_ISSUER": "https://kc.coulomb.social"} proc = subprocess.Popen([str(Path(sys.executable).with_name("informed-decision-web"))], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) checks = {} try: for attempt in range(50): try: with opener.open("http://127.0.0.1:8080/healthz", timeout=1) as r: checks["installed_entrypoint_health"] = r.status == 200 and json.load(r) == {"status": "ok"} break except URLError: if proc.poll() is not None: raise RuntimeError("service failed to start") time.sleep(0.1) assert checks.get("installed_entrypoint_health") try: opener.open("http://127.0.0.1:8080/auth/start", timeout=2) except HTTPError as r: parsed=urlsplit(r.headers["Location"]); q=parse_qs(parsed.query) checks["fixed_issuer_authorization_redirect"] = r.code==303 and parsed.scheme=="https" and parsed.netloc=="kc.coulomb.social" and parsed.path=="/authorize" checks["exact_registered_callback_and_scopes"] = q["redirect_uri"]==["https://decisions.coulomb.social/auth/callback"] and q["scope"]==["openid approval:read approval:approve"] checks["pkce_s256_and_browser_cookie"] = q["code_challenge_method"]==["S256"] and "Secure; HttpOnly; SameSite=Lax" in r.headers["Set-Cookie"] r.close() try: opener.open("http://127.0.0.1:8080/readyz", timeout=2) except HTTPError as r: checks["incomplete_approval_path_not_ready"] = r.code==503 and json.load(r)["reason"]=="approval_path_not_connected" r.close() try: opener.open(Request("http://127.0.0.1:8080/approvals/fixture/accept", data=b"{}"), timeout=2) except HTTPError as r: checks["binding_route_unavailable"] = r.code==404 r.close() assert len(checks)==6 and all(checks.values()) receipt={"status":"passed", "checks":checks,"issuer_contacted":False,"native_human_login":False,"model_calls":0} if args.receipt: args.receipt.write_text(json.dumps(receipt,indent=2)+"\n") print(json.dumps(receipt,indent=2)) finally: proc.terminate() try: proc.communicate(timeout=5) except subprocess.TimeoutExpired: proc.kill(); proc.communicate()