64 lines
3.2 KiB
Python
64 lines
3.2 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from govoplan_access.backend.permissions import catalog as access_catalog
|
|
from govoplan_core.security import permissions as core_permissions
|
|
from govoplan_core.security.scope_aliases import LEGACY_SCOPE_ALIASES
|
|
|
|
|
|
class PermissionCatalogContractTests(unittest.TestCase):
|
|
def test_access_reuses_core_legacy_scope_aliases(self) -> None:
|
|
self.assertIs(access_catalog.LEGACY_SCOPE_ALIASES, LEGACY_SCOPE_ALIASES)
|
|
self.assertIs(core_permissions.LEGACY_SCOPE_ALIASES, LEGACY_SCOPE_ALIASES)
|
|
|
|
def test_legacy_alias_grants_match_in_core_and_access(self) -> None:
|
|
for legacy_scope, aliases in LEGACY_SCOPE_ALIASES.items():
|
|
for alias in aliases:
|
|
self.assertTrue(core_permissions.scope_grants(legacy_scope, alias))
|
|
self.assertTrue(access_catalog.scope_grants(legacy_scope, alias))
|
|
|
|
def test_access_legacy_catalog_includes_non_access_platform_scopes(self) -> None:
|
|
scopes = {permission.scope for permission in access_catalog.permission_catalog(include_legacy=True)}
|
|
self.assertIn("campaign:queue", scopes)
|
|
self.assertIn("files:upload", scopes)
|
|
self.assertIn("mail_servers:test", scopes)
|
|
|
|
def test_expand_scopes_preserves_explicit_canonical_scope_with_legacy_alias(self) -> None:
|
|
scopes = access_catalog.expand_scopes(("files:file:read",))
|
|
|
|
self.assertIn("files:file:read", scopes)
|
|
self.assertIn("files:read", scopes)
|
|
|
|
def test_api_key_intersection_excludes_canonical_and_legacy_system_scopes(self) -> None:
|
|
for scope in ("access:system_credential:write", "access:tenant:create", "system:tenants:create"):
|
|
with self.subTest(scope=scope):
|
|
self.assertEqual([], access_catalog.intersect_api_key_scopes([scope], [scope]))
|
|
|
|
def test_api_key_module_wildcards_expand_only_to_concrete_tenant_scopes(self) -> None:
|
|
scopes = access_catalog.intersect_api_key_scopes(["access:*"], ["access:*"])
|
|
self.assertIn("access:membership:read", scopes)
|
|
self.assertNotIn("access:*", scopes)
|
|
self.assertFalse(access_catalog.scopes_grant(scopes, "access:system_credential:write"))
|
|
catalog = access_catalog.permission_map()
|
|
self.assertTrue(all(catalog[scope].level == "tenant" for scope in scopes if scope in catalog))
|
|
|
|
def test_api_key_intersection_preserves_unknown_concrete_module_grants(self) -> None:
|
|
self.assertEqual(
|
|
["optional-module:record:read"],
|
|
access_catalog.intersect_api_key_scopes(["optional-module:record:read"], ["optional-module:record:read"]),
|
|
)
|
|
|
|
def test_api_key_intersection_preserves_concrete_tenant_compatibility_aliases(self) -> None:
|
|
scopes = access_catalog.intersect_api_key_scopes(["files:read"], ["files:file:read"])
|
|
self.assertIn("files:read", scopes)
|
|
self.assertIn("files:file:read", scopes)
|
|
self.assertTrue(access_catalog.scopes_grant(scopes, "files:file:read"))
|
|
|
|
def test_api_key_intersection_does_not_retain_unknown_wildcards(self) -> None:
|
|
self.assertEqual([], access_catalog.intersect_api_key_scopes(["optional-module:*"], ["optional-module:*"]))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|