diff --git a/dsp_permissions_scripts/models/group.py b/dsp_permissions_scripts/models/group.py index 416aff7b..e6f542c1 100644 --- a/dsp_permissions_scripts/models/group.py +++ b/dsp_permissions_scripts/models/group.py @@ -1,5 +1,6 @@ from __future__ import annotations +import re from typing import Any from pydantic import BaseModel @@ -7,8 +8,12 @@ from pydantic import model_validator from dsp_permissions_scripts.models.errors import InvalidGroupError +from dsp_permissions_scripts.models.errors import InvalidIRIError from dsp_permissions_scripts.utils.helpers import KNORA_ADMIN_ONTO_NAMESPACE +PREFIXED_IRI_REGEX = r"^[\w-]+:[\w -]+$" +NAMES_OF_BUILTIN_GROUPS = ["SystemAdmin", "Creator", "ProjectAdmin", "ProjectMember", "KnownUser", "UnknownUser"] + class Group(BaseModel): model_config = ConfigDict(frozen=True) @@ -29,8 +34,16 @@ def _check_regex(self) -> Group: 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) + +def is_prefixed_group_iri(iri: str) -> bool: + if iri.startswith((KNORA_ADMIN_ONTO_NAMESPACE, "http://rdfh.ch/groups/", "knora-base:", "knora-api:")): + return False + elif iri.startswith("knora-admin:") and not iri.endswith(tuple(NAMES_OF_BUILTIN_GROUPS)): + return False + elif re.search(PREFIXED_IRI_REGEX, iri): + return True + else: + raise InvalidIRIError(f"{iri} is not a valid group IRI") UNKNOWN_USER = Group(prefixed_iri="knora-admin:UnknownUser") diff --git a/dsp_permissions_scripts/models/group_utils.py b/dsp_permissions_scripts/models/group_utils.py index bcf9c3e6..c203b9e1 100644 --- a/dsp_permissions_scripts/models/group_utils.py +++ b/dsp_permissions_scripts/models/group_utils.py @@ -1,12 +1,17 @@ from typing import Iterable +from dsp_permissions_scripts.models.errors import InvalidGroupError +from dsp_permissions_scripts.models.errors import InvalidIRIError from dsp_permissions_scripts.models.group import CREATOR from dsp_permissions_scripts.models.group import KNOWN_USER +from dsp_permissions_scripts.models.group import NAMES_OF_BUILTIN_GROUPS from dsp_permissions_scripts.models.group import PROJECT_ADMIN from dsp_permissions_scripts.models.group import PROJECT_MEMBER from dsp_permissions_scripts.models.group import SYSTEM_ADMIN from dsp_permissions_scripts.models.group import UNKNOWN_USER from dsp_permissions_scripts.models.group import Group +from dsp_permissions_scripts.models.group import is_prefixed_group_iri +from dsp_permissions_scripts.utils.helpers import KNORA_ADMIN_ONTO_NAMESPACE def sort_groups(groups_original: Iterable[Group]) -> list[Group]: @@ -25,3 +30,20 @@ def _get_sort_pos_of_custom_group(group: str) -> int: alphabet = list("abcdefghijklmnopqrstuvwxyz") 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 + + +def get_full_iri_from_prefixed_iri(prefixed_iri: str) -> str: + if not is_prefixed_group_iri(prefixed_iri): + raise InvalidIRIError(f"{prefixed_iri} is not a valid prefixed group IRI") + prefix, groupname = prefixed_iri.split(":") + if prefix == "knora-admin": + return _get_full_iri_from_builtin_group(prefix, groupname) + raise NotImplementedError( + f"Dereferencing custom group IRIs is not supported yet, hence {prefixed_iri} cannot be dereferenced" + ) + + +def _get_full_iri_from_builtin_group(prefix: str, groupname: str) -> str: + if groupname not in NAMES_OF_BUILTIN_GROUPS: + raise InvalidGroupError(f"{prefix}:{groupname} is not a valid builtin group") + return f"{KNORA_ADMIN_ONTO_NAMESPACE}{groupname}"