Bind password setup grants to approved company welcome pages
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
This commit is contained in:
parent
c8ad7a85ea
commit
48a75b1a54
7 changed files with 267 additions and 8 deletions
34
sso-mfa/k8s/keycape/test_vergabe_client_rollout.py
Normal file
34
sso-mfa/k8s/keycape/test_vergabe_client_rollout.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import base64
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
import unittest
|
||||
import yaml
|
||||
|
||||
spec = importlib.util.spec_from_file_location('vergabe', Path(__file__).with_name('vergabe-client-rollout.py'))
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
|
||||
class RegistrationTests(unittest.TestCase):
|
||||
def secret(self, clients):
|
||||
self.config = {'issuer': 'https://kc.coulomb.social', 'authelia': {'issuer': 'https://auth.coulomb.social'},
|
||||
'clients': clients}
|
||||
raw = yaml.safe_dump(self.config, sort_keys=False)
|
||||
return {'data': {'config.yaml': base64.b64encode(raw.encode()).decode()}}
|
||||
|
||||
def test_adds_only_exact_public_client_and_is_idempotent(self):
|
||||
prior = {'clientId': 'existing', 'clientType': 'public',
|
||||
'redirectUris': ['https://existing.example/callback']}
|
||||
secret = self.secret([prior])
|
||||
encoded, changed = module.replacement(secret)
|
||||
self.assertTrue(changed)
|
||||
result = yaml.safe_load(base64.b64decode(encoded))
|
||||
self.assertEqual(dict(self.config, clients=[prior, module.CLIENT]), result)
|
||||
secret['data']['config.yaml'] = encoded
|
||||
self.assertEqual((encoded, False), module.replacement(secret))
|
||||
|
||||
def test_no_existing_client_rewrite_and_new_binary_invalid_fields_refused(self):
|
||||
for client in [dict(module.CLIENT, redirectUris=['https://wrong.example/']),
|
||||
{'clientId': 'existing', 'roles': ['operator']}]:
|
||||
with self.assertRaises(module.rollout.Refused):
|
||||
module.replacement(self.secret([client]))
|
||||
39
sso-mfa/k8s/keycape/vergabe-client-rollout.py
Normal file
39
sso-mfa/k8s/keycape/vergabe-client-rollout.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Fixed Vergabe registration using the existing guarded KeyCape rollout lane."""
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
spec = importlib.util.spec_from_file_location('portal_rollout', ROOT / 'portal-client-rollout.py')
|
||||
rollout = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(rollout)
|
||||
CLIENT = {
|
||||
'clientId': 'vergabe-demo-company',
|
||||
'displayName': 'Vergabe Demo Company',
|
||||
'redirectUris': ['https://vergabe-teilnahme.coulomb.social/demo-company/accounts/oidc/callback/'],
|
||||
'allowedScopes': ['openid', 'profile', 'groups'],
|
||||
'grantTypes': ['authorization_code'],
|
||||
'clientType': 'public',
|
||||
}
|
||||
# Reuse the owner's byte-preserving insertion, CAS, cluster pin and safe receipts.
|
||||
# The portal-specific legacy migration branch is explicitly unreachable here.
|
||||
original_replacement = rollout.replacement
|
||||
rollout.portal = SimpleNamespace(CLIENT_ID=CLIENT['clientId'], CLIENT=CLIENT)
|
||||
|
||||
|
||||
def replacement(secret):
|
||||
_, config, _ = rollout.pin.issuer_document(secret)
|
||||
for client in config.get('clients', []):
|
||||
if 'client_credentials' not in client.get('grantTypes', []):
|
||||
rollout.require(not client.get('roles') and not client.get('serviceSubject'),
|
||||
'browser_service_identity_fields_block_new_binary')
|
||||
if client.get('clientId') == CLIENT['clientId']:
|
||||
rollout.require(client == CLIENT, 'existing_vergabe_registration_differs')
|
||||
return original_replacement(secret)
|
||||
|
||||
|
||||
rollout.replacement = replacement
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(rollout.main())
|
||||
Loading…
Add table
Add a link
Reference in a new issue