import copy import importlib.util import json from pathlib import Path import pytest spec = importlib.util.spec_from_file_location( 'prune', Path(__file__).resolve().parents[1] / 'scripts/openbao_platform_admin_callback_prune.py') m = importlib.util.module_from_spec(spec) spec.loader.exec_module(m) DECLARED = json.loads((Path(__file__).resolve().parents[1] / 'openbao/auth/netkingdom-platform-admin-role.json').read_text()) def live(role): state = {'role': copy.deepcopy(role)} writes = [] def write(value): writes.append(value) state['role'].update(value) return state, writes, (lambda: copy.deepcopy(state['role'])), write def test_prunes_only_the_two_retired_callbacks_and_keeps_settings(): # The declaration is post-prune; re-add the retired callbacks to model the pre-prune role. role = dict(DECLARED, allowed_redirect_uris=list(DECLARED['allowed_redirect_uris']) + list(m.RETIRED)) state, writes, read, write = live(role) changed, uris = m.prune(read, write) assert changed and len(writes) == 1 assert not set(m.RETIRED) & set(uris) assert m.KEEP in uris and 'http://localhost:8250/oidc/callback' in uris assert state['role']['token_policies'] == ['platform-admin', 'operator-custody'] assert state['role']['bound_claims'] == {'groups': ['net-kingdom-admins']} def test_idempotent_when_already_pruned(): role = dict(DECLARED, allowed_redirect_uris=[u for u in DECLARED['allowed_redirect_uris'] if u not in m.RETIRED]) _, writes, read, write = live(role) assert m.prune(read, write)[0] is False and writes == [] def test_refuses_without_tunnel_callback(): role = dict(DECLARED, allowed_redirect_uris=list(m.RETIRED)) _, writes, read, write = live(role) with pytest.raises(m.Refused, match='tunnel_callback_missing'): m.prune(read, write) assert writes == [] def test_refuses_when_readback_drops_other_settings(): role = dict(copy.deepcopy(DECLARED), allowed_redirect_uris=list(DECLARED['allowed_redirect_uris']) + list(m.RETIRED)) calls = iter([copy.deepcopy(role), copy.deepcopy(role), dict(copy.deepcopy(role), token_ttl=60, allowed_redirect_uris=[u for u in role['allowed_redirect_uris'] if u not in m.RETIRED])]) with pytest.raises(m.Refused, match='readback_settings_changed'): m.prune(lambda: next(calls), lambda value: None)