Files
govoplan-views/tests/test_authorization.py
T

118 lines
3.8 KiB
Python

from __future__ import annotations
import unittest
from types import SimpleNamespace
from unittest.mock import patch
from fastapi import HTTPException
from govoplan_core.auth import ApiPrincipal
from govoplan_core.core.access import PrincipalRef
from govoplan_core.core.modules import ModuleManifest
from govoplan_core.core.views import ViewSurface
from govoplan_views.backend.router import (
_catalogue,
_require_definition_read,
_require_definition_write,
)
def principal(
*,
account_id: str = "account-1",
scopes: tuple[str, ...],
group_ids: tuple[str, ...] = (),
) -> ApiPrincipal:
return ApiPrincipal(
principal=PrincipalRef(
account_id=account_id,
membership_id="membership-1",
tenant_id="tenant-1",
scopes=frozenset(scopes),
group_ids=frozenset(group_ids),
),
account=object(),
user=object(),
)
class ViewDefinitionAuthorizationTests(unittest.TestCase):
def test_personal_writer_cannot_edit_another_accounts_view(self) -> None:
actor = principal(scopes=("views:personal_definition:write",))
_require_definition_write(actor, "user", "account-1")
with self.assertRaises(HTTPException) as caught:
_require_definition_write(actor, "user", "account-2")
self.assertEqual(403, caught.exception.status_code)
def test_group_reader_is_limited_to_current_memberships(self) -> None:
actor = principal(
scopes=("views:group_definition:read",),
group_ids=("group-1",),
)
_require_definition_read(actor, "group", "group-1")
with self.assertRaises(HTTPException) as caught:
_require_definition_read(actor, "group", "group-2")
self.assertEqual(403, caught.exception.status_code)
def test_tenant_manager_can_manage_owned_views(self) -> None:
actor = principal(scopes=("views:definition:write",))
_require_definition_write(actor, "group", "group-2")
_require_definition_write(actor, "user", "account-2")
def test_catalogue_excludes_surfaces_of_tenant_unavailable_modules(self) -> None:
actor = principal(scopes=("views:definition:read",))
registry = SimpleNamespace(
manifests=lambda: (
ModuleManifest(id="access", name="Access", version="1"),
ModuleManifest(id="views", name="Views", version="1"),
ModuleManifest(id="files", name="Files", version="1"),
),
view_surfaces=lambda: (
ViewSurface(
id="views.module",
module_id="views",
kind="module",
label="Views",
),
ViewSurface(
id="files.module",
module_id="files",
kind="module",
label="Files",
),
),
)
tenant = SimpleNamespace(
settings={
"module_entitlements": {
"schema_version": 1,
"revision": 1,
"system_policy": {
"available_modules": ["access", "views"],
"forced_modules": ["access"],
},
"tenant_selection": {
"enabled_modules": ["views"],
},
}
}
)
session = SimpleNamespace(get=lambda model, tenant_id: tenant)
with patch(
"govoplan_views.backend.router.get_registry",
return_value=registry,
):
catalogue = _catalogue(session, actor)
self.assertEqual(["views.module"], [surface.id for surface in catalogue])
if __name__ == "__main__":
unittest.main()