Record canonical portal hostname and callback cutover
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
This commit is contained in:
tegwick 2026-09-14 00:16:33 +02:00
parent bea425cf78
commit dc42b0344c
6 changed files with 78 additions and 6 deletions

View file

@ -117,6 +117,7 @@ clients:
displayName: User Engine Portal
redirectUris:
- https://users.92-205-62-239.nip.io/oidc/callback
- https://users.coulomb.social/oidc/callback
allowedScopes:
- openid
- profile

View file

@ -12,7 +12,7 @@ import subprocess
import yaml
ROOT = Path('/home/worsch/net-kingdom/sso-mfa/k8s/keycape')
ROOT = Path(__file__).resolve().parent
def module(name, filename):
@ -43,9 +43,32 @@ def replacement(secret):
ids = [client['clientId'] for client in clients]
require(len(ids) == len(set(ids)), 'duplicate_client_id')
if portal.CLIENT_ID in ids:
require(clients[ids.index(portal.CLIENT_ID)] == portal.CLIENT,
'existing_registration_differs_requires_reconciliation')
return secret['data']['config.yaml'], False
current = clients[ids.index(portal.CLIENT_ID)]
if current == portal.CLIENT:
return secret['data']['config.yaml'], False
legacy = dict(portal.CLIENT, redirectUris=[
'https://users.92-205-62-239.nip.io/oidc/callback'])
require(current == legacy, 'existing_registration_differs_requires_reconciliation')
# Only the exact reviewed legacy public client may gain this callback.
root = yaml.compose(raw)
node = next(value for key, value in root.value if key.value == 'clients')
item = node.value[ids.index(portal.CLIENT_ID)]
redirects = next(value for key, value in item.value if key.value == 'redirectUris')
require(isinstance(redirects, yaml.nodes.SequenceNode) and not redirects.flow_style,
'block_redirect_sequence_required')
index = redirects.end_mark.index
line_start = raw.rfind('\n', 0, index) + 1
if not raw[line_start:index].strip():
index = line_start
addition = ' ' * redirects.start_mark.column + '- https://users.coulomb.social/oidc/callback\n'
if index and raw[index - 1] != '\n':
addition = '\n' + addition
updated = raw[:index] + addition + raw[index:]
expected = copy.deepcopy(config)
expected['clients'][ids.index(portal.CLIENT_ID)] = portal.CLIENT
require(yaml.load(updated, Loader=pin.UniqueLoader) == expected,
'unrelated_configuration_changed')
return base64.b64encode(updated.encode()).decode(), True
root = yaml.compose(raw)
node = next(value for key, value in root.value if key.value == 'clients')
require(isinstance(node, yaml.nodes.SequenceNode) and not node.flow_style,

View file

@ -17,7 +17,8 @@ CLIENT_ID = "user-engine-portal"
CLIENT = {
"clientId": CLIENT_ID,
"displayName": "User Engine Portal",
"redirectUris": ["https://users.92-205-62-239.nip.io/oidc/callback"],
"redirectUris": ["https://users.92-205-62-239.nip.io/oidc/callback",
"https://users.coulomb.social/oidc/callback"],
"allowedScopes": ["openid", "profile", "email", "groups"],
"grantTypes": ["authorization_code"],
"clientType": "public",

View file

@ -32,6 +32,25 @@ class PortalClientTests(unittest.TestCase):
self.assertEqual(yaml.safe_load(updated), expected)
self.assertEqual(secret['data']['key.pem'], 'synthetic-key')
def test_legacy_callback_upgrade_preserves_bytes_and_is_idempotent(self):
legacy = dict(rollout.portal.CLIENT, redirectUris=[
'https://users.92-205-62-239.nip.io/oidc/callback'])
secret, raw = self.fixture([{'clientId': 'existing', 'clientType': 'public'}, legacy])
encoded, changed = rollout.replacement(secret)
updated = base64.b64decode(encoded).decode()
self.assertTrue(changed)
self.assertEqual(updated.replace(' - https://users.coulomb.social/oidc/callback\n', ''), raw)
self.assertEqual(yaml.safe_load(updated)['clients'][-1], rollout.portal.CLIENT)
secret['data']['config.yaml'] = encoded
self.assertEqual(rollout.replacement(secret), (encoded, False))
def test_upgrade_refuses_extra_scope_or_unreviewed_callback(self):
for extra in [dict(allowedScopes=['openid', 'admin']),
dict(redirectUris=['https://users.coulomb.social/oidc/callback']),
dict(clientType='confidential')]:
with self.subTest(extra=extra), self.assertRaises(rollout.Refused):
rollout.replacement(self.fixture([dict(rollout.portal.CLIENT, **extra)])[0])
def test_exact_existing_registration_is_noop(self):
secret, _ = self.fixture([rollout.portal.CLIENT])
self.assertEqual(rollout.replacement(secret), (secret['data']['config.yaml'], False))