From d92a139220d0ce6fd044db32d75670185c71923a Mon Sep 17 00:00:00 2001 From: Johannes Nussbaum <39048939+jnussbaum@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:41:07 +0100 Subject: [PATCH] chore: waypaver for next PR (#155) --- dsp_permissions_scripts/ap/ap_model.py | 3 ++ dsp_permissions_scripts/doap/doap_get.py | 2 +- dsp_permissions_scripts/doap/doap_model.py | 40 +++++++++++++++++----- dsp_permissions_scripts/doap/doap_set.py | 4 +-- dsp_permissions_scripts/models/group.py | 4 +-- dsp_permissions_scripts/models/scope.py | 2 +- dsp_permissions_scripts/oap/oap_model.py | 10 +++++- 7 files changed, 49 insertions(+), 16 deletions(-) diff --git a/dsp_permissions_scripts/ap/ap_model.py b/dsp_permissions_scripts/ap/ap_model.py index 5eaae139..9d5aff9d 100644 --- a/dsp_permissions_scripts/ap/ap_model.py +++ b/dsp_permissions_scripts/ap/ap_model.py @@ -1,6 +1,7 @@ from enum import Enum from pydantic import BaseModel +from pydantic import ConfigDict from dsp_permissions_scripts.models.group import Group @@ -23,6 +24,8 @@ class ApValue(Enum): class Ap(BaseModel): """Represents an Administrative Permission""" + model_config = ConfigDict(extra="forbid") + forGroup: Group forProject: str hasPermissions: frozenset[ApValue] diff --git a/dsp_permissions_scripts/doap/doap_get.py b/dsp_permissions_scripts/doap/doap_get.py index 934f8077..db5aad7b 100644 --- a/dsp_permissions_scripts/doap/doap_get.py +++ b/dsp_permissions_scripts/doap/doap_get.py @@ -37,7 +37,7 @@ def create_doap_from_admin_route_response(permission: dict[str, Any], dsp_client target = GroupDoapTarget(project_iri=project_iri, group=group_builder(prefixed_group_iri)) case {"forProject": project_iri, **p}: target = EntityDoapTarget( - project_iri=project_iri, resource_class=p.get("forResourceClass"), property=p.get("forProperty") + project_iri=project_iri, resclass_iri=p.get("forResourceClass"), property_iri=p.get("forProperty") ) return Doap( target=target, diff --git a/dsp_permissions_scripts/doap/doap_model.py b/dsp_permissions_scripts/doap/doap_model.py index bb8e8101..488653ef 100644 --- a/dsp_permissions_scripts/doap/doap_model.py +++ b/dsp_permissions_scripts/doap/doap_model.py @@ -3,6 +3,7 @@ from typing import Self from pydantic import BaseModel +from pydantic import ConfigDict from pydantic import model_validator from dsp_permissions_scripts.models.group import Group @@ -12,42 +13,63 @@ class Doap(BaseModel): """Model representing a DOAP, containing the target, the scope and the IRI of the DOAP.""" + model_config = ConfigDict(extra="forbid") + target: GroupDoapTarget | EntityDoapTarget scope: PermissionScope doap_iri: str class GroupDoapTarget(BaseModel): + """The group for which a DOAP is defined""" + + model_config = ConfigDict(extra="forbid") + project_iri: str group: Group class EntityDoapTarget(BaseModel): + """The resource class and/or property for which a DOAP is defined""" + + model_config = ConfigDict(extra="forbid") + project_iri: str - resource_class: str | None = None - property: str | None = None + resclass_iri: str | None = None + property_iri: str | None = None @model_validator(mode="after") def _validate(self) -> Self: - if self.resource_class is None and self.property is None: - raise ValueError("At least one of resource_class or property must be set") + if self.resclass_iri is None and self.property_iri is None: + raise ValueError("At least one of resclass_iri or property_iri must be set") return self class NewGroupDoapTarget(BaseModel): - """Represents the target of a DOAP that is yet to be created.""" + """ + The group for which a DOAP is defined, if the DOAP is yet to be created. + At this stage, the project IRI is not known yet. + """ + + model_config = ConfigDict(extra="forbid") group: Group class NewEntityDoapTarget(BaseModel): - """Represents the target of a DOAP that is yet to be created.""" + """ + The resource class and/or property for which a DOAP is defined, if the DOAP is yet to be created. + At this stage, neither the project IRI nor the full IRIs of the class/prop are known yet. + So the class/prop must be defined by their prefixed name (onto:name). + """ + + model_config = ConfigDict(extra="forbid") - resource_class: str | None = None - property: str | None = None + prefixed_class: str | None = None + prefixed_prop: str | None = None @model_validator(mode="after") def _validate(self) -> Self: - if self.resource_class is None and self.property is None: + if self.prefixed_class is None and self.prefixed_prop is None: raise ValueError("At least one of resource_class or property must be set") return self diff --git a/dsp_permissions_scripts/doap/doap_set.py b/dsp_permissions_scripts/doap/doap_set.py index b7029b0b..6e85e0e8 100644 --- a/dsp_permissions_scripts/doap/doap_set.py +++ b/dsp_permissions_scripts/doap/doap_set.py @@ -54,8 +54,8 @@ def create_new_doap_on_server( payload = { "forGroup": forGroup, "forProject": proj_iri, - "forProperty": target.property if isinstance(target, NewEntityDoapTarget) else None, - "forResourceClass": target.resource_class if isinstance(target, NewEntityDoapTarget) else None, + "forProperty": target.prefixed_prop if isinstance(target, NewEntityDoapTarget) else None, + "forResourceClass": target.prefixed_class if isinstance(target, NewEntityDoapTarget) else None, "hasPermissions": create_admin_route_object_from_scope(scope, dsp_client), } try: diff --git a/dsp_permissions_scripts/models/group.py b/dsp_permissions_scripts/models/group.py index d0fb7de5..d2b6ada8 100644 --- a/dsp_permissions_scripts/models/group.py +++ b/dsp_permissions_scripts/models/group.py @@ -23,7 +23,7 @@ class BuiltinGroup(BaseModel): """Represents a DSP-builtin group, in the form 'knora-admin:ProjectAdmin'""" - model_config = ConfigDict(frozen=True) + model_config = ConfigDict(frozen=True, extra="forbid") prefixed_iri: str @@ -39,7 +39,7 @@ def _validate(self) -> Self: class CustomGroup(BaseModel): """Represents a custom group, in the form 'project-shortname:groupname'""" - model_config = ConfigDict(frozen=True) + model_config = ConfigDict(frozen=True, extra="forbid") prefixed_iri: str diff --git a/dsp_permissions_scripts/models/scope.py b/dsp_permissions_scripts/models/scope.py index 548dce90..8f42f963 100644 --- a/dsp_permissions_scripts/models/scope.py +++ b/dsp_permissions_scripts/models/scope.py @@ -23,7 +23,7 @@ class PermissionScope(BaseModel): """A scope is an object encoding the information: Which user group gets which permissions on a resource/value?""" - model_config = ConfigDict(frozen=True) + model_config = ConfigDict(frozen=True, extra="forbid") CR: frozenset[Group] = frozenset() D: frozenset[Group] = frozenset() diff --git a/dsp_permissions_scripts/oap/oap_model.py b/dsp_permissions_scripts/oap/oap_model.py index 754d2240..69411cc0 100644 --- a/dsp_permissions_scripts/oap/oap_model.py +++ b/dsp_permissions_scripts/oap/oap_model.py @@ -20,6 +20,8 @@ class Oap(BaseModel): If only the resource is of interest, value_oaps will be an empty list. """ + model_config = ConfigDict(extra="forbid") + resource_oap: ResourceOap value_oaps: list[ValueOap] @@ -30,6 +32,8 @@ class ModifiedOap(BaseModel): This model is used to represent only the modified parts of an OAP, so it can be incomplete. """ + model_config = ConfigDict(extra="forbid") + resource_oap: ResourceOap | None = None value_oaps: list[ValueOap] = Field(default_factory=list) @@ -40,6 +44,8 @@ def is_empty(self) -> bool: class ResourceOap(BaseModel): """Model representing an object access permission of a resource""" + model_config = ConfigDict(extra="forbid") + scope: PermissionScope resource_iri: str @@ -55,6 +61,8 @@ class ValueOap(BaseModel): value_type: type of the value, e.g. "knora-api:TextValue" """ + model_config = ConfigDict(extra="forbid") + scope: PermissionScope property: str value_type: str @@ -73,7 +81,7 @@ class OapRetrieveConfig(BaseModel): which can be used to resolve the ontology prefixes. """ - model_config = ConfigDict(frozen=True) + model_config = ConfigDict(frozen=True, extra="forbid") retrieve_resources: Literal["all", "specified_res_classes"] = "all" specified_res_classes: list[str] = []