Establish scoped KeyCape factor custody and verified automatic renewal
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
KeyCape factor custody acceptance / acceptance (push) Successful in 7s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
This commit is contained in:
codex 2026-09-13 16:25:33 +02:00
parent b75729b799
commit 2e2c31d237
22 changed files with 1169 additions and 1 deletions

View file

@ -0,0 +1,21 @@
import base64,importlib.util,json,time,unittest
from pathlib import Path
from unittest.mock import patch
spec=importlib.util.spec_from_file_location("factor_provider",Path(__file__).resolve().parents[1]/"scripts/keycape_factor_provider.py")
m=importlib.util.module_from_spec(spec);spec.loader.exec_module(m)
class FactorProviderTests(unittest.TestCase):
def check(self,role="admin",auth_status=True,expiry=3600,policy_status=403,listing_status=True):
token="synthetic."+base64.urlsafe_b64encode(json.dumps({"exp":int(time.time())+expiry}).encode()).decode().rstrip("=")+".signature"
def request(path,payload=None,token=None):
if path=="/auth":return 200,{"result":{"status":auth_status,"value":{"role":role,"username":m.USER,"token":self.token}}}
if path=="/policy/":return policy_status,{}
return 200,{"result":{"status":listing_status,"value":{"tokens":[{}],"count":1}}}
self.token=token
with patch.object(m,"request",side_effect=request):return m.token_result("synthetic-password-not-a-real-secret")
def test_success_requires_scoped_admin_and_expiry(self):
r=self.check();self.assertTrue(r["policy_read_denied"]);self.assertTrue(r["cross_user_factor_visible"])
def test_rejects_user_token_expiry_and_privilege_leak(self):
for kwargs in [dict(role="user"),dict(auth_status=False),dict(expiry=-1),dict(expiry=9000),dict(policy_status=200),dict(policy_status=500),dict(listing_status=False)]:
with self.subTest(kwargs=kwargs):
with self.assertRaises(RuntimeError):self.check(**kwargs)
def test_no_redirect_forwarding(self):self.assertIsNone(m.NoRedirect().redirect_request(None,None,None,None,None,None))