#!/usr/bin/env python3 """Open the approved OpenBao login in a new empty Playwright Chromium profile. The Windows default browser is not used. A previous login opened Firefox, which was already signed in as another account. This launcher uses the headed Chromium binary pinned by coulomb-social's Playwright install. """ import json import os import pwd import subprocess import sys import tempfile from pathlib import Path from urllib.parse import parse_qs, urlsplit BROWSERS_JSON = Path( "/home/worsch/coulomb-social/scripts/node_modules/playwright-core/browsers.json" ) def allowed(url): try: parsed = urlsplit(url) query = parse_qs(parsed.query) return ( parsed.scheme == "https" and parsed.hostname == "kc.coulomb.social" and parsed.port in (None, 443) and parsed.username is None and parsed.password is None and not parsed.fragment and not any(char in url for char in "\r\n\x00") and query.get("redirect_uri") in ( ["http://localhost:8250/oidc/callback"], ["http://127.0.0.1:8250/oidc/callback"], ) ) except ValueError: return False def chromium_executable(browsers_json, cache_root): try: spec = json.loads(Path(browsers_json).read_text(encoding="utf-8")) except (OSError, UnicodeError, json.JSONDecodeError): return "" browsers = spec.get("browsers") if isinstance(spec, dict) else None if not isinstance(browsers, list): return "" revision = "" for item in browsers: if isinstance(item, dict) and item.get("name") == "chromium": revision = str(item.get("revision") or "") break if not revision.isdecimal(): return "" candidate = Path(cache_root) / f"chromium-{revision}" / "chrome-linux64" / "chrome" if candidate.is_file() and os.access(candidate, os.X_OK): return str(candidate) return "" def playwright_cache(process_home, account_home): """The Chromium pin lives in the account cache. Attended platform-admin login replaces the process home with an empty session before OpenBao starts. Looking under that session misses the binary, the window never opens, and the OIDC callback times out. """ del process_home return Path(account_home) / ".cache" / "ms-playwright" def browser_path(): account_home = pwd.getpwuid(os.getuid()).pw_dir return chromium_executable( BROWSERS_JSON, playwright_cache(Path.home(), account_home) ) def launch_argv(browser, profile_dir, url): return [ browser, f"--user-data-dir={profile_dir}", "--no-first-run", "--no-default-browser-check", "--disable-sync", "--new-window", url, ] def classify_cmd(argv): """Classify OpenBao's WSL launch, `cmd.exe /c start `. hashicorp/cap replaces each & with ^& before calling the Windows default browser. Other cmd.exe uses are left for the real binary. """ if list(argv[:2]) != ["/c", "start"] or len(argv) != 3: return "delegate", "" url = str(argv[2]).replace("^&", "&") if allowed(url): return "open", url return "reject", "" def stamp(result): path = Path("/home/worsch/.local/state/railiance/receipts/operator-browser-last.txt") try: path.parent.mkdir(mode=0o700, parents=True, exist_ok=True) path.write_text(result + "\n", encoding="utf-8") os.chmod(path, 0o600) except OSError: return def open_url(url): if not os.environ.get("DISPLAY") and not os.environ.get("WAYLAND_DISPLAY"): stamp("no-display") return 1 browser = browser_path() if not browser: stamp("no-browser") return 1 profile = Path(tempfile.mkdtemp(prefix="operator-browser-")) os.chmod(profile, 0o700) command = launch_argv(browser, str(profile), url) try: subprocess.Popen( command, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True, ) except OSError: stamp("open-failed") return 1 stamp("opened") return 0 def main(): stamp("called") if len(sys.argv) != 2 or not allowed(sys.argv[1]): stamp("rejected") return 1 return open_url(sys.argv[1]) if __name__ == "__main__": raise SystemExit(main())