Implement credential change request review flow

This commit is contained in:
2026-06-27 22:57:21 +02:00
parent 8c1e64d5e0
commit 815b124ab1
7 changed files with 772 additions and 14 deletions

View File

@@ -0,0 +1,80 @@
from __future__ import annotations
import importlib.util
import os
import shutil
import sys
import tempfile
import unittest
from pathlib import Path
REPO_DIR = Path(__file__).resolve().parents[1]
SPEC = importlib.util.spec_from_file_location(
"credential_change", REPO_DIR / "scripts/credential-change.py"
)
credential_change = importlib.util.module_from_spec(SPEC)
assert SPEC.loader is not None
sys.modules[SPEC.name] = credential_change
SPEC.loader.exec_module(credential_change)
class CredentialChangeTests(unittest.TestCase):
def setUp(self) -> None:
self.sample = (
REPO_DIR
/ "credential-change-requests/CCR-2026-0001-whynot-design-npm-token.yaml"
)
def test_sample_ccr_validates_with_bound_claim_warning(self) -> None:
_ccr, errors, warnings = credential_change.validate_ccr(self.sample)
self.assertEqual(errors, [])
self.assertIn("bound claim is not confirmed", warnings[0])
def test_render_summary_contains_review_fields(self) -> None:
ccr, _errors, warnings = credential_change.validate_ccr(self.sample)
rendered = credential_change.render_summary(ccr, warnings)
self.assertIn("whynot-design npm publish token lane", rendered)
self.assertIn("platform/workloads/whynot-design/whynot-design/npm-publish", rendered)
self.assertIn("approve | deny | needs_changes", rendered)
def test_apply_plan_refuses_unapproved_ccr(self) -> None:
with self.assertRaises(SystemExit):
credential_change.command_apply_plan(type("Args", (), {"ref": str(self.sample)})())
def test_approve_records_comment_but_unconfirmed_claim_still_blocks_apply(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
tmp_path = Path(tmp)
ccr_dir = tmp_path / "ccrs"
ccr_dir.mkdir()
copied = ccr_dir / self.sample.name
shutil.copy2(self.sample, copied)
old_ccr_dir = os.environ.get("CCR_DIR")
os.environ["CCR_DIR"] = str(ccr_dir)
try:
credential_change.append_decision(
copied, "approved", "unit-test", "looks right"
)
ccr, errors, _warnings = credential_change.validate_ccr(copied)
self.assertEqual(errors, [])
self.assertEqual(ccr["status"], "approved")
self.assertEqual(ccr["review"]["comments"][-1]["comment"], "looks right")
with self.assertRaises(SystemExit):
credential_change.command_apply_plan(
type("Args", (), {"ref": "CCR-2026-0001"})()
)
finally:
if old_ccr_dir is None:
os.environ.pop("CCR_DIR", None)
else:
os.environ["CCR_DIR"] = old_ccr_dir
def test_generated_policy_is_narrow(self) -> None:
ccr, _errors, _warnings = credential_change.validate_ccr(self.sample)
policy = credential_change.generated_policy_hcl(ccr)
self.assertIn('path "platform/data/workloads/whynot-design/whynot-design/npm-publish"', policy)
self.assertNotIn("*", policy)
self.assertNotIn("delete", policy)
if __name__ == "__main__":
unittest.main()