Skip to content

Commit

Permalink
paving the way for custom groups, second round (#149)
Browse files Browse the repository at this point in the history
  • Loading branch information
jnussbaum authored Oct 23, 2024
1 parent 8b29742 commit 1508a4e
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 19 deletions.
3 changes: 2 additions & 1 deletion dsp_permissions_scripts/ap/ap_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 Group
from dsp_permissions_scripts.models.group_utils 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
Expand Down Expand Up @@ -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),
"forProject": proj_iri,
"hasPermissions": [
{"additionalInformation": None, "name": ap_val.value, "permissionCode": None} for ap_val in hasPermissions
Expand Down
6 changes: 5 additions & 1 deletion dsp_permissions_scripts/doap/doap_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_utils 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
Expand Down Expand Up @@ -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)
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,
Expand Down
18 changes: 15 additions & 3 deletions dsp_permissions_scripts/models/group.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
from __future__ import annotations

import re
from typing import Any

from pydantic import BaseModel
from pydantic import ConfigDict
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

KNORA_ADMIN_ONTO_NAMESPACE = "http://www.knora.org/ontology/knora-admin#"
PREFIXED_IRI_REGEX = r"^[\w-]+:[\w -]+$"
NAMES_OF_BUILTIN_GROUPS = ["SystemAdmin", "Creator", "ProjectAdmin", "ProjectMember", "KnownUser", "UnknownUser"]


class Group(BaseModel):
Expand All @@ -30,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")
Expand Down
34 changes: 28 additions & 6 deletions dsp_permissions_scripts/models/group_utils.py
Original file line number Diff line number Diff line change
@@ -1,18 +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


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
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]:
Expand All @@ -25,3 +24,26 @@ def sort_groups(groups_original: Iterable[Group]) -> list[Group]:
groups = list(groups_original)
groups.sort(key=lambda x: sort_key.index(x) if x in sort_key else _get_sort_pos_of_custom_group(x.prefixed_iri))
return groups


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}"
2 changes: 1 addition & 1 deletion dsp_permissions_scripts/oap/oap_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

from dsp_permissions_scripts.models.errors import ApiError
from dsp_permissions_scripts.models.errors import PermissionsAlreadyUpToDate
from dsp_permissions_scripts.models.group import KNORA_ADMIN_ONTO_NAMESPACE
from dsp_permissions_scripts.models.scope import PermissionScope
from dsp_permissions_scripts.oap.oap_model import ModifiedOap
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__)
Expand Down
2 changes: 1 addition & 1 deletion dsp_permissions_scripts/oap/update_iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@

from dsp_permissions_scripts.models.errors import ApiError
from dsp_permissions_scripts.models.errors import InvalidIRIError
from dsp_permissions_scripts.models.group import KNORA_ADMIN_ONTO_NAMESPACE
from dsp_permissions_scripts.models.scope import PermissionScope
from dsp_permissions_scripts.oap.oap_get import get_value_oaps
from dsp_permissions_scripts.oap.oap_set import update_permissions_for_resource
from dsp_permissions_scripts.oap.oap_set import update_permissions_for_value
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

logger = get_logger(__name__)

Expand Down
1 change: 1 addition & 0 deletions dsp_permissions_scripts/utils/helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
PACKAGE_NAME = "dsp-permissions-scripts"
KNORA_ADMIN_ONTO_NAMESPACE = "http://www.knora.org/ontology/knora-admin#"


def dereference_prefix(
Expand Down
3 changes: 2 additions & 1 deletion dsp_permissions_scripts/utils/scope_serialization.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Any

from dsp_permissions_scripts.models.group_utils import get_full_iri_from_prefixed_iri
from dsp_permissions_scripts.models.group_utils import sort_groups
from dsp_permissions_scripts.models.scope import PermissionScope

Expand Down Expand Up @@ -48,7 +49,7 @@ def create_admin_route_object_from_scope(perm_scope: PermissionScope) -> list[di
for group in groups:
scope_elements.append(
{
"additionalInformation": group.full_iri(),
"additionalInformation": get_full_iri_from_prefixed_iri(group.prefixed_iri),
"name": perm_letter,
"permissionCode": None,
}
Expand Down
2 changes: 1 addition & 1 deletion tests/test_oap_update_iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import pytest

from dsp_permissions_scripts.models.errors import InvalidIRIError
from dsp_permissions_scripts.models.group import KNORA_ADMIN_ONTO_NAMESPACE
from dsp_permissions_scripts.models.group import PROJECT_ADMIN
from dsp_permissions_scripts.models.scope import PermissionScope
from dsp_permissions_scripts.oap import update_iris
Expand All @@ -13,6 +12,7 @@
from dsp_permissions_scripts.oap.update_iris import ResourceIRIUpdater
from dsp_permissions_scripts.oap.update_iris import ValueIRIUpdater
from dsp_permissions_scripts.utils.dsp_client import DspClient
from dsp_permissions_scripts.utils.helpers import KNORA_ADMIN_ONTO_NAMESPACE


@pytest.fixture
Expand Down
6 changes: 2 additions & 4 deletions tests/test_scope_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
from pytest_unordered import unordered

from dsp_permissions_scripts.models import group
from dsp_permissions_scripts.models.group import KNORA_ADMIN_ONTO_NAMESPACE
from dsp_permissions_scripts.models.scope import PermissionScope
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
from dsp_permissions_scripts.utils.scope_serialization import create_scope_from_admin_route_object
from dsp_permissions_scripts.utils.scope_serialization import create_scope_from_string
Expand All @@ -12,15 +12,14 @@

class TestScopeSerialization:
perm_strings = (
"CR knora-admin:SystemAdmin|V knora-admin:CustomGroup",
"CR knora-admin:SystemAdmin",
"D knora-admin:ProjectAdmin|RV knora-admin:ProjectMember",
"M knora-admin:ProjectAdmin|V knora-admin:Creator,knora-admin:KnownUser|RV knora-admin:UnknownUser",
"CR knora-admin:SystemAdmin,knora-admin:ProjectAdmin|D knora-admin:Creator|RV knora-admin:UnknownUser",
)
admin_route_objects = (
[
{"name": "CR", "additionalInformation": f"{KNORA_ADMIN_ONTO_NAMESPACE}SystemAdmin", "permissionCode": None},
{"name": "V", "additionalInformation": f"{KNORA_ADMIN_ONTO_NAMESPACE}CustomGroup", "permissionCode": None},
],
[
{"name": "D", "additionalInformation": f"{KNORA_ADMIN_ONTO_NAMESPACE}ProjectAdmin", "permissionCode": None},
Expand Down Expand Up @@ -50,7 +49,6 @@ class TestScopeSerialization:
scopes = (
PermissionScope.create(
CR=[group.SYSTEM_ADMIN],
V=[group.Group(prefixed_iri="knora-admin:CustomGroup")],
),
PermissionScope.create(
D=[group.PROJECT_ADMIN],
Expand Down

0 comments on commit 1508a4e

Please sign in to comment.