diff --git a/dsp_permissions_scripts/ap/ap_get.py b/dsp_permissions_scripts/ap/ap_get.py index 95022c09..81af338a 100644 --- a/dsp_permissions_scripts/ap/ap_get.py +++ b/dsp_permissions_scripts/ap/ap_get.py @@ -7,6 +7,7 @@ from dsp_permissions_scripts.models.group import Group from dsp_permissions_scripts.utils.dsp_client import DspClient from dsp_permissions_scripts.utils.get_logger import get_logger +from dsp_permissions_scripts.utils.helpers import KNORA_ADMIN_ONTO_NAMESPACE from dsp_permissions_scripts.utils.project import get_project_iri_and_onto_iris_by_shortcode logger = get_logger(__name__) @@ -15,7 +16,7 @@ def create_ap_from_admin_route_object(permission: dict[str, Any]) -> Ap: """Deserializes a AP from JSON as returned by /admin/permissions/ap/{project_iri}""" ap = Ap( - forGroup=Group(val=permission["forGroup"]), + forGroup=Group(val=permission["forGroup"].replace(KNORA_ADMIN_ONTO_NAMESPACE, "knora-admin:")), forProject=permission["forProject"], hasPermissions=frozenset(ApValue(p["name"]) for p in permission["hasPermissions"]), iri=permission["iri"], diff --git a/dsp_permissions_scripts/doap/doap_get.py b/dsp_permissions_scripts/doap/doap_get.py index 97d3e813..6f35f3ce 100644 --- a/dsp_permissions_scripts/doap/doap_get.py +++ b/dsp_permissions_scripts/doap/doap_get.py @@ -8,6 +8,7 @@ from dsp_permissions_scripts.models.group import Group from dsp_permissions_scripts.utils.dsp_client import DspClient from dsp_permissions_scripts.utils.get_logger import get_logger +from dsp_permissions_scripts.utils.helpers import KNORA_ADMIN_ONTO_NAMESPACE from dsp_permissions_scripts.utils.project import get_project_iri_and_onto_iris_by_shortcode from dsp_permissions_scripts.utils.scope_serialization import create_scope_from_admin_route_object @@ -49,10 +50,14 @@ def _get_all_doaps_of_project(project_iri: str, dsp_client: DspClient) -> list[D def create_doap_from_admin_route_response(permission: dict[str, Any]) -> Doap: """Deserializes a DOAP from JSON as returned by /admin/permissions/doap/{project_iri}""" scope = create_scope_from_admin_route_object(permission["hasPermissions"]) + if permission.get("forGroup"): + relative_group_iri = permission["forGroup"].replace(KNORA_ADMIN_ONTO_NAMESPACE, "knora-admin:") + else: + relative_group_iri = None doap = Doap( target=DoapTarget( project=permission["forProject"], - group=Group(val=permission["forGroup"]) if permission.get("forGroup") else None, + group=Group(val=relative_group_iri) if relative_group_iri else None, resource_class=permission.get("forResourceClass"), property=permission.get("forProperty"), ), diff --git a/dsp_permissions_scripts/doap/doap_set.py b/dsp_permissions_scripts/doap/doap_set.py index f6047e78..dcd74aab 100644 --- a/dsp_permissions_scripts/doap/doap_set.py +++ b/dsp_permissions_scripts/doap/doap_set.py @@ -6,6 +6,7 @@ from dsp_permissions_scripts.models.scope import PermissionScope from dsp_permissions_scripts.utils.dsp_client import DspClient from dsp_permissions_scripts.utils.get_logger import get_logger +from dsp_permissions_scripts.utils.helpers import KNORA_ADMIN_ONTO_NAMESPACE from dsp_permissions_scripts.utils.scope_serialization import create_admin_route_object_from_scope logger = get_logger(__name__) @@ -13,7 +14,10 @@ def _update_doap_scope_on_server(doap_iri: str, scope: PermissionScope, dsp_client: DspClient) -> Doap: iri = quote_plus(doap_iri, safe="") - payload = {"hasPermissions": create_admin_route_object_from_scope(scope)} + payload = { + "hasPermissions": create_admin_route_object_from_scope(scope), + "context": {"knora-admin": KNORA_ADMIN_ONTO_NAMESPACE}, + } try: response = dsp_client.put(f"/admin/permissions/{iri}/hasPermissions", data=payload) except ApiError as err: diff --git a/dsp_permissions_scripts/models/group.py b/dsp_permissions_scripts/models/group.py index ec917ac7..6374e99d 100644 --- a/dsp_permissions_scripts/models/group.py +++ b/dsp_permissions_scripts/models/group.py @@ -1,7 +1,5 @@ from __future__ import annotations -import re - from pydantic import BaseModel from pydantic import ConfigDict from pydantic import model_validator @@ -16,15 +14,14 @@ class Group(BaseModel): @model_validator(mode="after") def _check_regex(self) -> Group: - common_part = re.escape("http://www.knora.org/ontology/knora-admin#") - if not re.search(f"{common_part}.+", self.val): + if not self.val.startswith("knora-admin:"): raise InvalidGroupError(f"{self.val} is not a valid group IRI") return self -UNKNOWN_USER = Group(val="http://www.knora.org/ontology/knora-admin#UnknownUser") -KNOWN_USER = Group(val="http://www.knora.org/ontology/knora-admin#KnownUser") -PROJECT_MEMBER = Group(val="http://www.knora.org/ontology/knora-admin#ProjectMember") -PROJECT_ADMIN = Group(val="http://www.knora.org/ontology/knora-admin#ProjectAdmin") -CREATOR = Group(val="http://www.knora.org/ontology/knora-admin#Creator") -SYSTEM_ADMIN = Group(val="http://www.knora.org/ontology/knora-admin#SystemAdmin") +UNKNOWN_USER = Group(val="knora-admin:UnknownUser") +KNOWN_USER = Group(val="knora-admin:KnownUser") +PROJECT_MEMBER = Group(val="knora-admin:ProjectMember") +PROJECT_ADMIN = Group(val="knora-admin:ProjectAdmin") +CREATOR = Group(val="knora-admin:Creator") +SYSTEM_ADMIN = Group(val="knora-admin:SystemAdmin") diff --git a/dsp_permissions_scripts/oap/oap_set.py b/dsp_permissions_scripts/oap/oap_set.py index 9da374a9..c365af7b 100644 --- a/dsp_permissions_scripts/oap/oap_set.py +++ b/dsp_permissions_scripts/oap/oap_set.py @@ -11,6 +11,7 @@ from dsp_permissions_scripts.oap.oap_model import ValueOap from dsp_permissions_scripts.utils.dsp_client import DspClient from dsp_permissions_scripts.utils.get_logger import get_logger +from dsp_permissions_scripts.utils.helpers import KNORA_ADMIN_ONTO_NAMESPACE from dsp_permissions_scripts.utils.scope_serialization import create_string_from_scope logger = get_logger(__name__) @@ -86,7 +87,7 @@ def _update_batch(batch: tuple[ResourceOap | ValueOap, ...], dsp_client: DspClie resource_iri=oap.resource_iri, lmd=resource.get("knora-api:lastModificationDate"), resource_type=resource["@type"], - context=resource["@context"], + context=resource["@context"] | {"knora-admin": KNORA_ADMIN_ONTO_NAMESPACE}, scope=oap.scope, dsp_client=dsp_client, ) @@ -99,7 +100,7 @@ def _update_batch(batch: tuple[ResourceOap | ValueOap, ...], dsp_client: DspClie resource_iri=oap.resource_iri, value=oap, resource_type=resource["@type"], - context=resource["@context"], + context=resource["@context"] | {"knora-admin": KNORA_ADMIN_ONTO_NAMESPACE}, dsp_client=dsp_client, ) except ApiError as err: diff --git a/dsp_permissions_scripts/utils/helpers.py b/dsp_permissions_scripts/utils/helpers.py index 742594a3..a41abc6d 100644 --- a/dsp_permissions_scripts/utils/helpers.py +++ b/dsp_permissions_scripts/utils/helpers.py @@ -3,6 +3,7 @@ from dsp_permissions_scripts.models import group PACKAGE_NAME = "dsp-permissions-scripts" +KNORA_ADMIN_ONTO_NAMESPACE = "http://www.knora.org/ontology/knora-admin#" def dereference_prefix( @@ -24,29 +25,9 @@ def dereference_prefix( return context[namespace_prefix] + localname -def shorten_iri_by_prefixing( - iri: str, - context: dict[str, str], -) -> str: - """ - Transforms a full IRI into its shortened form, using the namespace prefix from the provided context. - - Args: - iri: an full IRI, e.g. "http://www.knora.org/ontology/knora-admin#Creator" - context: The context to use take the namespace prefix from - - Returns: - The prefixed short form of the IRI, e.g. "knora-admin:Creator" - """ - for namespace_prefix, full_iri in context.items(): - if iri.startswith(full_iri): - return f"{namespace_prefix}:{iri[len(full_iri):]}" - raise ValueError(f"Could not find a prefix for IRI {iri}") - - def _get_sort_pos_of_custom_group(group: str) -> int: alphabet = list("abcdefghijklmnopqrstuvwxyz") - relevant_letter = group.replace("http://www.knora.org/ontology/knora-admin#", "")[0] + relevant_letter = group.replace("knora-admin:", "")[0] return alphabet.index(relevant_letter.lower()) + 99 # must be higher than the highest index of the builtin groups diff --git a/dsp_permissions_scripts/utils/scope_serialization.py b/dsp_permissions_scripts/utils/scope_serialization.py index 49feb052..52a295fd 100644 --- a/dsp_permissions_scripts/utils/scope_serialization.py +++ b/dsp_permissions_scripts/utils/scope_serialization.py @@ -1,6 +1,7 @@ from typing import Any from dsp_permissions_scripts.models.scope import PermissionScope +from dsp_permissions_scripts.utils.helpers import KNORA_ADMIN_ONTO_NAMESPACE from dsp_permissions_scripts.utils.helpers import sort_groups @@ -21,8 +22,7 @@ def create_scope_from_string(permission_string: str) -> PermissionScope: for scope in scopes: perm_letter, groups_as_str = scope.split(" ") groups = groups_as_str.split(",") - groups = [g.replace("knora-admin:", "http://www.knora.org/ontology/knora-admin#") for g in groups] - kwargs[perm_letter] = groups + kwargs[perm_letter] = [g.replace(KNORA_ADMIN_ONTO_NAMESPACE, "knora-admin:") for g in groups] return PermissionScope.from_dict(kwargs) @@ -31,8 +31,7 @@ def create_scope_from_admin_route_object(admin_route_object: list[dict[str, Any] kwargs: dict[str, list[str]] = {} for obj in admin_route_object: attr_name: str = obj["name"] - group: str = obj["additionalInformation"] - group = group.replace("knora-admin:", "http://www.knora.org/ontology/knora-admin#") + group: str = obj["additionalInformation"].replace(KNORA_ADMIN_ONTO_NAMESPACE, "knora-admin:") if attr_name in kwargs: kwargs[attr_name].append(group) else: diff --git a/testdata/APs_1234_serialized.json b/testdata/APs_1234_serialized.json index bca5a793..9ba50f9f 100644 --- a/testdata/APs_1234_serialized.json +++ b/testdata/APs_1234_serialized.json @@ -1,7 +1,9 @@ { "Project 1234 has 2 APs": [ { - "forGroup": {"val": "http://www.knora.org/ontology/knora-admin#ProjectAdmin"}, + "forGroup": { + "val": "knora-admin:ProjectAdmin" + }, "forProject": "http://rdfh.ch/projects/MsOaiQkcQ7-QPxsYBKckfQ", "hasPermissions": [ "ProjectAdminRightsAllPermission", @@ -10,7 +12,9 @@ "iri": "http://rdfh.ch/ap-1" }, { - "forGroup": {"val": "http://www.knora.org/ontology/knora-admin#KnownUser"}, + "forGroup": { + "val": "knora-admin:KnownUser" + }, "forProject": "http://rdfh.ch/projects/MsOaiQkcQ7-QPxsYBKckfQ", "hasPermissions": [ "ProjectResourceCreateRestrictedPermission" diff --git a/tests/test_group.py b/tests/test_group.py index 83f35947..4436a802 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -5,16 +5,16 @@ def test_builtin_groups() -> None: - assert group.UNKNOWN_USER == group.Group(val="http://www.knora.org/ontology/knora-admin#UnknownUser") - assert group.KNOWN_USER == group.Group(val="http://www.knora.org/ontology/knora-admin#KnownUser") - assert group.PROJECT_MEMBER == group.Group(val="http://www.knora.org/ontology/knora-admin#ProjectMember") - assert group.PROJECT_ADMIN == group.Group(val="http://www.knora.org/ontology/knora-admin#ProjectAdmin") - assert group.CREATOR == group.Group(val="http://www.knora.org/ontology/knora-admin#Creator") - assert group.SYSTEM_ADMIN == group.Group(val="http://www.knora.org/ontology/knora-admin#SystemAdmin") + assert group.UNKNOWN_USER == group.Group(val="knora-admin:UnknownUser") + assert group.KNOWN_USER == group.Group(val="knora-admin:KnownUser") + assert group.PROJECT_MEMBER == group.Group(val="knora-admin:ProjectMember") + assert group.PROJECT_ADMIN == group.Group(val="knora-admin:ProjectAdmin") + assert group.CREATOR == group.Group(val="knora-admin:Creator") + assert group.SYSTEM_ADMIN == group.Group(val="knora-admin:SystemAdmin") def test_custom_group() -> None: - group_iri = "http://www.knora.org/ontology/knora-admin#my-custom-group" + group_iri = "knora-admin:my-custom-group" custom_group = group.Group(val=group_iri) assert custom_group.val == group_iri diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 19499c3c..d2c3ec92 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -6,13 +6,13 @@ def test_sort_groups() -> None: groups_original = [ - group.Group(val="http://www.knora.org/ontology/knora-admin#C_CustomGroup"), + group.Group(val="knora-admin:C_CustomGroup"), group.UNKNOWN_USER, group.PROJECT_ADMIN, group.PROJECT_MEMBER, group.CREATOR, - group.Group(val="http://www.knora.org/ontology/knora-admin#A_CustomGroup"), - group.Group(val="http://www.knora.org/ontology/knora-admin#B_CustomGroup"), + group.Group(val="knora-admin:A_CustomGroup"), + group.Group(val="knora-admin:B_CustomGroup"), group.KNOWN_USER, group.SYSTEM_ADMIN, ] @@ -23,9 +23,9 @@ def test_sort_groups() -> None: group.PROJECT_MEMBER, group.KNOWN_USER, group.UNKNOWN_USER, - group.Group(val="http://www.knora.org/ontology/knora-admin#A_CustomGroup"), - group.Group(val="http://www.knora.org/ontology/knora-admin#B_CustomGroup"), - group.Group(val="http://www.knora.org/ontology/knora-admin#C_CustomGroup"), + group.Group(val="knora-admin:A_CustomGroup"), + group.Group(val="knora-admin:B_CustomGroup"), + group.Group(val="knora-admin:C_CustomGroup"), ] groups_returned = sort_groups(groups_original) assert groups_returned == groups_expected diff --git a/tests/test_scope.py b/tests/test_scope.py index d5658427..88e7309b 100644 --- a/tests/test_scope.py +++ b/tests/test_scope.py @@ -85,7 +85,7 @@ def test_add_same_group_to_same_permission(self) -> None: CR={group.PROJECT_ADMIN}, V={group.UNKNOWN_USER, group.KNOWN_USER}, ) - rgx = "Group 'val='http://www.knora.org/ontology/knora-admin#ProjectAdmin'' is already in permission 'CR'" + rgx = "Group 'val='knora-admin:ProjectAdmin'' is already in permission 'CR'" with pytest.raises(ValueError, match=re.escape(rgx)): _ = scope.add("CR", group.PROJECT_ADMIN) diff --git a/tests/test_scope_serialization.py b/tests/test_scope_serialization.py index c8faa35c..c0e95911 100644 --- a/tests/test_scope_serialization.py +++ b/tests/test_scope_serialization.py @@ -1,5 +1,3 @@ -from typing import Any - import pytest from pytest_unordered import unordered @@ -43,7 +41,7 @@ class TestScopeSerialization: scopes = ( PermissionScope.create( CR=[group.SYSTEM_ADMIN], - V=[group.Group(val="http://www.knora.org/ontology/knora-admin#CustomGroup")], + V=[group.Group(val="knora-admin:CustomGroup")], ), PermissionScope.create( D={group.PROJECT_ADMIN}, @@ -72,24 +70,12 @@ def test_create_scope_from_admin_route_object(self) -> None: def test_create_string_from_scope(self) -> None: for perm_string, scope in zip(self.perm_strings, self.scopes): - perm_string_full = self._resolve_prefixes_of_perm_string(perm_string) - assert create_string_from_scope(scope) == perm_string_full, f"Failed with permission string '{perm_string}'" + assert create_string_from_scope(scope) == perm_string, f"Failed with permission string '{perm_string}'" def test_create_admin_route_object_from_scope(self) -> None: for admin_route_object, scope, index in zip(self.admin_route_objects, self.scopes, range(len(self.scopes))): - admin_route_object_full = self._resolve_prefixes_of_admin_route_object(admin_route_object) returned = create_admin_route_object_from_scope(scope) - assert unordered(returned) == admin_route_object_full, f"Failed with admin group object no. {index}" - - def _resolve_prefixes_of_admin_route_object(self, admin_route_object: list[dict[str, Any]]) -> list[dict[str, Any]]: - for obj in admin_route_object: - obj["additionalInformation"] = obj["additionalInformation"].replace( - "knora-admin:", "http://www.knora.org/ontology/knora-admin#" - ) - return admin_route_object - - def _resolve_prefixes_of_perm_string(self, perm_string: str) -> str: - return perm_string.replace("knora-admin:", "http://www.knora.org/ontology/knora-admin#") + assert unordered(returned) == admin_route_object, f"Failed with admin group object no. {index}" if __name__ == "__main__":