"""NK-WP-0051-T06: the OpenBao login page can choose the workload role. The main button stays role platform-admin. Workload roles come only from the presets allow-list. The script runs in node against a minimal DOM stub. """ from __future__ import annotations import json import shutil import subprocess import unittest from pathlib import Path REPO_DIR = Path(__file__).resolve().parents[1] OVERLAY = REPO_DIR / "helm/openbao-ui-overlay" WORKLOAD_ROLE = "reuse-surface-hub-writer-workload-kv-read" HARNESS = r""" const fs = require("fs"); const [script, presetsPath, clickId, selectValue] = process.argv.slice(1); const presets = JSON.parse(fs.readFileSync(presetsPath, "utf8")); presets.workloadRoles = (presets.workloadRoles || []).concat([{ role: "Bad Role!" }]); const els = {}; function el(id) { const node = { id, hidden: false, disabled: false, textContent: "", value: "", children: [], listeners: {}, classList: { add() {} }, appendChild(c) { this.children.push(c); if (!this.value) this.value = c.value; }, addEventListener(t, f) { this.listeners[t] = f; } }; els[id] = node; return node; } ["login-title","login-banner","login-submit","login-error","login-workload", "login-workload-summary","login-workload-hint","login-workload-role","login-workload-submit"].forEach(el); els["login-workload"].hidden = true; const posted = []; global.document = { getElementById: (id) => els[id] || null, createElement: () => ({ value: "", textContent: "" }) }; global.window = { location: { origin: "http://127.0.0.1:18200", assign() {} } }; global.fetch = async (url, opts) => { if (url.endsWith("presets.json")) return { ok: true, json: async () => presets }; posted.push({ url, body: JSON.parse(opts.body) }); return { ok: true, json: async () => ({ data: { auth_url: "https://kc.example/authorize" } }) }; }; eval(fs.readFileSync(script, "utf8")); setTimeout(async () => { if (selectValue) els["login-workload-role"].value = selectValue; await els[clickId].listeners.click(); console.log(JSON.stringify({ posted, options: els["login-workload-role"].children.map((c) => c.value), workloadHidden: els["login-workload"].hidden, error: els["login-error"].textContent })); }, 20); """ @unittest.skipUnless(shutil.which("node"), "node is not installed") class OpenBaoUiRoleSelectTests(unittest.TestCase): def run_page(self, click_id: str, select_value: str = "") -> dict: proc = subprocess.run( ["node", "-e", HARNESS, str(OVERLAY / "login.js"), str(OVERLAY / "presets.json"), click_id, select_value], capture_output=True, text=True, check=True, timeout=30, ) return json.loads(proc.stdout.strip().splitlines()[-1]) def test_presets_keep_platform_admin_and_list_workload_role(self) -> None: presets = json.loads((OVERLAY / "presets.json").read_text(encoding="utf-8")) self.assertEqual(presets["role"], "platform-admin") self.assertEqual(presets["mount"], "netkingdom") self.assertIn(WORKLOAD_ROLE, [entry["role"] for entry in presets["workloadRoles"]]) def test_main_button_stays_platform_admin(self) -> None: result = self.run_page("login-submit") self.assertEqual(len(result["posted"]), 1) self.assertEqual(result["posted"][0]["url"], "/v1/auth/netkingdom/oidc/auth_url") self.assertEqual(result["posted"][0]["body"]["role"], "platform-admin") self.assertEqual( result["posted"][0]["body"]["redirect_uri"], "http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback", ) def test_workload_button_uses_selected_listed_role(self) -> None: result = self.run_page("login-workload-submit", WORKLOAD_ROLE) self.assertFalse(result["workloadHidden"]) self.assertEqual(result["options"], [WORKLOAD_ROLE]) self.assertEqual(result["posted"][0]["body"]["role"], WORKLOAD_ROLE) def test_unlisted_role_is_refused(self) -> None: result = self.run_page("login-workload-submit", "platform-admin") self.assertEqual(result["posted"], []) self.assertIn("listed workload role", result["error"]) if __name__ == "__main__": unittest.main()