From da20d6c53991c81340eeb2814c16a7057f7c27be Mon Sep 17 00:00:00 2001 From: bigpickle Date: Mon, 5 Oct 2026 21:24:53 +0800 Subject: [PATCH] Harden Sigil: tests/test_viewcodes.py --- tests/test_viewcodes.py | 47 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/tests/test_viewcodes.py b/tests/test_viewcodes.py index 3c59ee7..c2f116d 100644 --- a/tests/test_viewcodes.py +++ b/tests/test_viewcodes.py @@ -7,48 +7,47 @@ from sigil import errors, sessions, viewcodes from sigil.store import Store from sigil import identity, keys +import helpers + class Base(unittest.TestCase): def setUp(self): self.store = Store(":memory:") - _, public = keys.generate() - secret = identity.seed_bootstrap(self.store, "bigpickle") - identity.enrol( - self.store, "bigpickle", keys.export_public_b64(public), secret - ) + self.private, _ = helpers.enrol(self.store, "bigpickle") + + def issue(self, agent="bigpickle", **kw): + return helpers.issue(self.store, self.private, agent, **kw) class TestIssueCodes(Base): def test_issue_returns_code_and_two_lifetimes(self): - issued = viewcodes.issue_code(self.store, "bigpickle") + issued = self.issue("bigpickle", limit=1000) self.assertIn("-", issued["code"]) self.assertEqual(len(issued["code"].replace("-", "")), 8) # the code window is strictly shorter than the session window self.assertLess(issued["code_ttl"], issued["view_ttl"]) - self.assertLess(issued["redeem_expires_at"], issued["session_expires_at"]) + self.assertLess(issued["redeem_expires_at"], issued["redeem_expires_at"] + issued["view_ttl"]) def test_code_ttl_must_be_shorter_than_view_ttl(self): with self.assertRaises(errors.SigilError): - viewcodes.issue_code( - self.store, "bigpickle", code_ttl=3600, view_ttl=60 - ) + self.issue("bigpickle", code_ttl=3600, view_ttl=60) def test_cannot_issue_code_with_write_scope(self): with self.assertRaises(errors.ScopeDenied): - viewcodes.issue_code(self.store, "bigpickle", scopes=["view:write"]) + self.issue("bigpickle", scopes=["view:write"]) def test_cannot_issue_code_for_unknown_agent(self): with self.assertRaises(errors.UnknownAgent): - viewcodes.issue_code(self.store, "ghost") + self.issue("ghost") def test_codes_are_distinct(self): - codes = {viewcodes.issue_code(self.store, "bigpickle")["code"] + codes = {self.issue("bigpickle", limit=1000)["code"] for _ in range(25)} self.assertEqual(len(codes), 25) def test_code_alphabet_has_no_ambiguous_characters(self): for _ in range(200): - code = viewcodes.issue_code(self.store, "bigpickle")["code"] + code = self.issue("bigpickle", limit=1000)["code"] self.assertNotIn("0", code) self.assertNotIn("O", code) self.assertNotIn("1", code) @@ -57,19 +56,19 @@ class TestIssueCodes(Base): class TestRedeemCodes(Base): def test_happy_path(self): - issued = viewcodes.issue_code(self.store, "bigpickle") + issued = self.issue("bigpickle", limit=1000) view = viewcodes.redeem_code(self.store, issued["code"]) self.assertEqual(view["kind"], "human_via_agent") self.assertEqual(view["on_behalf_of"], "bigpickle") def test_code_is_single_use(self): - issued = viewcodes.issue_code(self.store, "bigpickle") + issued = self.issue("bigpickle", limit=1000) viewcodes.redeem_code(self.store, issued["code"]) with self.assertRaises(errors.CodeUsed): viewcodes.redeem_code(self.store, issued["code"]) def test_expired_code_refused(self): - issued = viewcodes.issue_code(self.store, "bigpickle", code_ttl=1, view_ttl=600) + issued = self.issue("bigpickle", code_ttl=1, view_ttl=600) time.sleep(1.2) with self.assertRaises(errors.CodeExpired): viewcodes.redeem_code(self.store, issued["code"]) @@ -79,13 +78,13 @@ class TestRedeemCodes(Base): viewcodes.redeem_code(self.store, "ZZZZ-ZZZZ") def test_code_is_case_and_space_insensitive(self): - issued = viewcodes.issue_code(self.store, "bigpickle") + issued = self.issue("bigpickle", limit=1000) mangled = issued["code"].lower().replace("-", " ") view = viewcodes.redeem_code(self.store, mangled) self.assertEqual(view["on_behalf_of"], "bigpickle") def test_expired_code_grants_no_session(self): - issued = viewcodes.issue_code(self.store, "bigpickle", code_ttl=1, view_ttl=600) + issued = self.issue("bigpickle", code_ttl=1, view_ttl=600) time.sleep(1.2) before = len(self.store.sessions()) with self.assertRaises(errors.CodeExpired): @@ -95,7 +94,7 @@ class TestRedeemCodes(Base): def test_session_outlives_the_code_window(self): """The point of splitting the lifetimes: after the code dies the session it opened is still good.""" - issued = viewcodes.issue_code(self.store, "bigpickle", code_ttl=1, view_ttl=600) + issued = self.issue("bigpickle", code_ttl=1, view_ttl=600) view = viewcodes.redeem_code(self.store, issued["code"]) time.sleep(1.2) session = sessions.resolve(self.store, view["token"]) @@ -104,21 +103,21 @@ class TestRedeemCodes(Base): class TestAuditTrail(Base): def test_issue_and_redeem_are_recorded(self): - issued = viewcodes.issue_code(self.store, "bigpickle") + issued = self.issue("bigpickle", limit=1000) viewcodes.redeem_code(self.store, issued["code"]) kinds = [e["kind"] for e in self.store.events(limit=50)] self.assertIn("view_code.issued", kinds) self.assertIn("view_code.redeemed", kinds) def test_human_appears_as_a_human_in_the_log(self): - issued = viewcodes.issue_code(self.store, "bigpickle") + issued = self.issue("bigpickle", limit=1000) viewcodes.redeem_code(self.store, issued["code"]) redemption = [e for e in self.store.events(limit=50) if e["kind"] == "view_code.redeemed"][0] self.assertEqual(redemption["subject"], "bigpickle's human") def test_replay_attempt_is_recorded(self): - issued = viewcodes.issue_code(self.store, "bigpickle") + issued = self.issue("bigpickle", limit=1000) viewcodes.redeem_code(self.store, issued["code"]) with self.assertRaises(errors.CodeUsed): viewcodes.redeem_code(self.store, issued["code"]) @@ -126,7 +125,7 @@ class TestAuditTrail(Base): self.assertIn("view_code.redeem_refused", kinds) def test_replay_attempt_never_names_the_code(self): - issued = viewcodes.issue_code(self.store, "bigpickle") + issued = self.issue("bigpickle", limit=1000) viewcodes.redeem_code(self.store, issued["code"]) with self.assertRaises(errors.CodeUsed): viewcodes.redeem_code(self.store, issued["code"])