from __future__ import annotations from collections.abc import Iterable from govoplan_access.backend.permissions.evaluator import expand_scopes, scopes_grant from govoplan_core.core.modules import PermissionDefinition class PermissionRegistry: def __init__(self, permissions: Iterable[PermissionDefinition] = ()) -> None: self._catalog: dict[str, PermissionDefinition] = {} for permission in permissions: self.register(permission) @property def catalog(self) -> dict[str, PermissionDefinition]: return dict(self._catalog) def register(self, permission: PermissionDefinition) -> None: if permission.scope in self._catalog: raise ValueError(f"Duplicate permission scope: {permission.scope}") self._catalog[permission.scope] = permission def has(self, scope: str) -> bool: return scope in self._catalog def grants(self, scopes: Iterable[str], required: str) -> bool: return scopes_grant(scopes, required, catalog=self._catalog) def expand(self, scopes: Iterable[str], *, include_unknown: bool = False) -> list[str]: return expand_scopes(scopes, catalog=self._catalog, include_unknown=include_unknown) def validate_known(self, scopes: Iterable[str]) -> list[str]: unknown = sorted(scope for scope in scopes if scope not in self._catalog and not scope.endswith(":*") and scope not in {"*", "tenant:*", "system:*"}) if unknown: raise ValueError("Unknown permission scope(s): " + ", ".join(unknown)) return sorted(set(scopes))