Skip to content

Commit

Permalink
Merge branch 'main' into wip/DEV-3894-dont-modify-deleted-values
Browse files Browse the repository at this point in the history
  • Loading branch information
jnussbaum authored Jul 19, 2024
2 parents f64959f + e9c759d commit 8e558a1
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 73 deletions.
3 changes: 2 additions & 1 deletion dsp_permissions_scripts/ap/ap_get.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
Expand All @@ -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"],
Expand Down
7 changes: 6 additions & 1 deletion dsp_permissions_scripts/doap/doap_get.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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"),
),
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 @@ -6,14 +6,18 @@
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__)


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:
Expand Down
17 changes: 7 additions & 10 deletions dsp_permissions_scripts/models/group.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from __future__ import annotations

import re

from pydantic import BaseModel
from pydantic import ConfigDict
from pydantic import model_validator
Expand All @@ -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")
5 changes: 3 additions & 2 deletions dsp_permissions_scripts/oap/oap_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
Expand Down Expand Up @@ -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,
)
Expand All @@ -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:
Expand Down
23 changes: 2 additions & 21 deletions dsp_permissions_scripts/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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


Expand Down
7 changes: 3 additions & 4 deletions dsp_permissions_scripts/utils/scope_serialization.py
Original file line number Diff line number Diff line change
@@ -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


Expand All @@ -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)


Expand All @@ -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:
Expand Down
8 changes: 6 additions & 2 deletions testdata/APs_1234_serialized.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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"
Expand Down
14 changes: 7 additions & 7 deletions tests/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 6 additions & 6 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
]
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion tests/test_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
20 changes: 3 additions & 17 deletions tests/test_scope_serialization.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Any

import pytest
from pytest_unordered import unordered

Expand Down Expand Up @@ -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},
Expand Down Expand Up @@ -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__":
Expand Down

0 comments on commit 8e558a1

Please sign in to comment.