From 414170c528863c7a794b16720338cded4bbce385 Mon Sep 17 00:00:00 2001 From: Johannes Nussbaum Date: Tue, 22 Oct 2024 13:05:36 +0200 Subject: [PATCH] - replace Group.full_iri() by get_full_iri_from_prefixed_iri() - remove Group ABC --- dsp_permissions_scripts/ap/ap_set.py | 3 +- dsp_permissions_scripts/doap/doap_set.py | 6 ++- dsp_permissions_scripts/models/group.py | 47 ++++++++----------- .../utils/scope_serialization.py | 4 +- tests/test_group.py | 13 ++--- tests/test_scope_serialization.py | 2 +- 6 files changed, 36 insertions(+), 39 deletions(-) diff --git a/dsp_permissions_scripts/ap/ap_set.py b/dsp_permissions_scripts/ap/ap_set.py index f5408ed..c25cd59 100644 --- a/dsp_permissions_scripts/ap/ap_set.py +++ b/dsp_permissions_scripts/ap/ap_set.py @@ -7,6 +7,7 @@ from dsp_permissions_scripts.ap.ap_model import ApValue from dsp_permissions_scripts.models.errors import ApiError from dsp_permissions_scripts.models.group import GroupType +from dsp_permissions_scripts.models.group import get_full_iri_from_prefixed_iri from dsp_permissions_scripts.utils.dsp_client import DspClient from dsp_permissions_scripts.utils.get_logger import get_logger from dsp_permissions_scripts.utils.project import get_project_iri_and_onto_iris_by_shortcode @@ -49,7 +50,7 @@ def create_new_ap_on_server( ) -> Ap | None: proj_iri, _ = get_project_iri_and_onto_iris_by_shortcode(shortcode, dsp_client) payload = { - "forGroup": forGroup.full_iri(), + "forGroup": get_full_iri_from_prefixed_iri(forGroup.prefixed_iri, dsp_client), "forProject": proj_iri, "hasPermissions": [ {"additionalInformation": None, "name": ap_val.value, "permissionCode": None} for ap_val in hasPermissions diff --git a/dsp_permissions_scripts/doap/doap_set.py b/dsp_permissions_scripts/doap/doap_set.py index 0784678..191ac13 100644 --- a/dsp_permissions_scripts/doap/doap_set.py +++ b/dsp_permissions_scripts/doap/doap_set.py @@ -5,6 +5,7 @@ from dsp_permissions_scripts.doap.doap_model import NewEntityDoapTarget from dsp_permissions_scripts.doap.doap_model import NewGroupDoapTarget from dsp_permissions_scripts.models.errors import ApiError +from dsp_permissions_scripts.models.group import get_full_iri_from_prefixed_iri 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 @@ -47,8 +48,11 @@ def create_new_doap_on_server( dsp_client: DspClient, ) -> Doap | None: proj_iri, _ = get_project_iri_and_onto_iris_by_shortcode(shortcode, dsp_client) + forGroup = None + if isinstance(target, NewGroupDoapTarget): + forGroup = get_full_iri_from_prefixed_iri(target.group.prefixed_iri, dsp_client) payload = { - "forGroup": target.group.full_iri() if isinstance(target, NewGroupDoapTarget) else None, + "forGroup": forGroup, "forProject": proj_iri, "forProperty": target.property if isinstance(target, NewEntityDoapTarget) else None, "forResourceClass": target.resource_class if isinstance(target, NewEntityDoapTarget) else None, diff --git a/dsp_permissions_scripts/models/group.py b/dsp_permissions_scripts/models/group.py index 2221029..1006ca9 100644 --- a/dsp_permissions_scripts/models/group.py +++ b/dsp_permissions_scripts/models/group.py @@ -1,8 +1,6 @@ from __future__ import annotations import re -from abc import ABC -from abc import abstractmethod from typing import Any from typing import Iterable from typing import Self @@ -22,7 +20,7 @@ NAMES_OF_BUILTIN_GROUPS = ["SystemAdmin", "Creator", "ProjectAdmin", "ProjectMember", "KnownUser", "UnknownUser"] KNORA_ADMIN_ONTO_NAMESPACE = "http://www.knora.org/ontology/knora-admin#" -PREFIXED_IRI_REGEX = r"^[\w-]+:[\w-]+$" +PREFIXED_IRI_REGEX = r"^[\w-]+:[\w -]+$" def is_prefixed_group_iri(iri: str) -> bool: @@ -49,6 +47,21 @@ def get_prefixed_iri_from_full_iri(full_iri: str, dsp_client: DspClient) -> str: raise InvalidIRIError(f"Could not transform full IRI {full_iri} to prefixed IRI") +def get_full_iri_from_prefixed_iri(prefixed_iri: str, dsp_client: DspClient) -> str: + shortname, groupname = prefixed_iri.split(":") + if shortname == "knora-admin": + return prefixed_iri.replace("knora-admin:", KNORA_ADMIN_ONTO_NAMESPACE) + all_groups = dsp_client.get("/admin/groups")["groups"] + proj_groups = [grp for grp in all_groups if grp["project"]["shortname"] == shortname] + if not (group := [grp for grp in proj_groups if grp["name"] == groupname]): + raise InvalidGroupError( + f"{prefixed_iri} is not a valid group. " + f"Available groups: {', '.join([grp['name'] for grp in proj_groups])}" + ) + full_iri: str = group[0]["id"] + return full_iri + + def group_builder(prefixed_iri: str) -> BuiltinGroup | CustomGroup: if prefixed_iri.startswith("knora-admin:"): return BuiltinGroup(prefixed_iri=prefixed_iri) @@ -58,14 +71,7 @@ def group_builder(prefixed_iri: str) -> BuiltinGroup | CustomGroup: raise InvalidGroupError(f"{prefixed_iri} is not a valid group IRI") -class Group(BaseModel, ABC): - prefixed_iri: str - - @abstractmethod - def full_iri(self, *args: Any) -> str: ... - - -class BuiltinGroup(Group): +class BuiltinGroup(BaseModel): model_config = ConfigDict(frozen=True) prefixed_iri: str @@ -78,11 +84,8 @@ def _check_regex(self) -> Self: raise InvalidGroupError(f"{self.prefixed_iri} is not a valid group IRI") return self - def full_iri(self) -> str: - return self.prefixed_iri.replace("knora-admin:", KNORA_ADMIN_ONTO_NAMESPACE) - -class CustomGroup(Group): +class CustomGroup(BaseModel): model_config = ConfigDict(frozen=True) prefixed_iri: str @@ -95,18 +98,6 @@ def _check_regex(self) -> Self: raise InvalidGroupError(f"{self.prefixed_iri} is not a custom group") return self - def full_iri(self, dsp_client: DspClient) -> str: - shortname, groupname = self.prefixed_iri.split(":") - all_groups = dsp_client.get("/admin/groups")["groups"] - proj_groups = [grp for grp in all_groups if grp["project"]["shortname"] == shortname] - if not (group := [grp for grp in proj_groups if grp["name"] == groupname]): - raise InvalidGroupError( - f"{self.prefixed_iri} is not a valid group. " - f"Available groups: {', '.join([grp['name'] for grp in proj_groups])}" - ) - full_iri: str = group[0]["id"] - return full_iri - def group_discriminator(v: Any) -> str: if isinstance(v, dict): @@ -130,7 +121,7 @@ def _get_sort_pos_of_custom_group(prefixed_iri: str) -> int: return alphabet.index(relevant_letter.lower()) + 99 # must be higher than the highest index of the builtin groups -def sort_groups(groups_original: Iterable[Group]) -> list[Group]: +def sort_groups(groups_original: Iterable[GroupType]) -> list[GroupType]: """ Sorts groups: - First according to their power (most powerful first - only applicable for built-in groups) diff --git a/dsp_permissions_scripts/utils/scope_serialization.py b/dsp_permissions_scripts/utils/scope_serialization.py index adc86c1..f4ed118 100644 --- a/dsp_permissions_scripts/utils/scope_serialization.py +++ b/dsp_permissions_scripts/utils/scope_serialization.py @@ -1,6 +1,6 @@ from typing import Any -from dsp_permissions_scripts.models.group import BuiltinGroup +from dsp_permissions_scripts.models.group import get_full_iri_from_prefixed_iri from dsp_permissions_scripts.models.group import sort_groups from dsp_permissions_scripts.models.scope import PermissionScope from dsp_permissions_scripts.utils.dsp_client import DspClient @@ -52,7 +52,7 @@ def create_admin_route_object_from_scope( for perm_letter in perm_scope.model_fields: groups = perm_scope.get(perm_letter) for group in groups: - full_iri = group.full_iri() if isinstance(group, BuiltinGroup) else group.full_iri(dsp_client) + full_iri = get_full_iri_from_prefixed_iri(group.prefixed_iri, dsp_client) scope_elements.append( { "additionalInformation": full_iri, diff --git a/tests/test_group.py b/tests/test_group.py index 09a08cc..6026c7f 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -14,6 +14,7 @@ from dsp_permissions_scripts.models.group import UNKNOWN_USER from dsp_permissions_scripts.models.group import BuiltinGroup from dsp_permissions_scripts.models.group import CustomGroup +from dsp_permissions_scripts.models.group import get_full_iri_from_prefixed_iri from dsp_permissions_scripts.models.group import get_prefixed_iri_from_full_iri from dsp_permissions_scripts.models.group import group_builder from dsp_permissions_scripts.models.group import is_prefixed_group_iri @@ -84,6 +85,12 @@ def test_get_prefixed_iri_from_full_iri_invalid_group(dsp_client_with_2_groups: get_prefixed_iri_from_full_iri("http://rdfh.ch/groups/0123/8-5f7B639_79ef6a043baW", dsp_client_with_2_groups) +@pytest.mark.parametrize("group_name", NAMES_OF_BUILTIN_GROUPS) +def test_get_full_iri_from_prefixed_iri(group_name: str) -> None: + res = get_full_iri_from_prefixed_iri(f"knora-admin:{group_name}", DspClient("foo")) + assert res == f"{KNORA_ADMIN_ONTO_NAMESPACE}{group_name}" + + @pytest.mark.parametrize("group_name", NAMES_OF_BUILTIN_GROUPS) def test_builtin_group_from_prefixed_iri(group_name: str) -> None: builtin_group = BuiltinGroup(prefixed_iri=f"knora-admin:{group_name}") @@ -110,12 +117,6 @@ def test_builtin_group_invalid_name() -> None: BuiltinGroup(prefixed_iri=f"knora-admin:{inv}") -@pytest.mark.parametrize("group_name", NAMES_OF_BUILTIN_GROUPS) -def test_builtin_group_generate_full_iri(group_name: str) -> None: - generated_full_iri = BuiltinGroup(prefixed_iri=f"knora-admin:{group_name}").full_iri() - assert generated_full_iri == f"{KNORA_ADMIN_ONTO_NAMESPACE}{group_name}" - - @pytest.mark.parametrize("prefixed_iri", ["my-shortname:my-custom-group", "ANYTHING:Thing Searcher"]) def test_custom_group(prefixed_iri: str) -> None: custom_group = CustomGroup(prefixed_iri=prefixed_iri) diff --git a/tests/test_scope_serialization.py b/tests/test_scope_serialization.py index fca0189..0aee995 100644 --- a/tests/test_scope_serialization.py +++ b/tests/test_scope_serialization.py @@ -110,7 +110,7 @@ def test_create_string_from_scope(self) -> None: def test_create_admin_route_object_from_scope(self) -> None: get_response = { - "groups": [{"name": CUSTOM_GROUP_NAME, "id": CUSTOM_GROUP_FULL_IRI, "project": {"shortcode": SHORTCODE}}] + "groups": [{"name": CUSTOM_GROUP_NAME, "id": CUSTOM_GROUP_FULL_IRI, "project": {"shortname": SHORTNAME}}] } dsp_client_mock = Mock(spec=DspClient, get=Mock(return_value=get_response)) for admin_route_object, scope, index in zip(self.admin_route_objects, self.scopes, range(len(self.scopes))):