Skip to content

Commit

Permalink
permissions: Allow record reviewers to also read/update request
Browse files Browse the repository at this point in the history
  • Loading branch information
rekt-hard committed Sep 30, 2024
1 parent 595f733 commit 8184203
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 24 deletions.
40 changes: 32 additions & 8 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,31 @@ Since we only want to change the behaviour of these community submission request

.. code-block:: python
from invenio_curations.requests.curation import CurationRequest
from invenio_curations.services.generators import (
IfCurationRequestAccepted,
IfRequestTypes,
RequestTopicGenerators,
)
from invenio_rdm_records.requests import CommunitySubmission
from invenio_rdm_records.services.permissions import (
RDMRequestsPermissionPolicy,
RDMRecordPermissionPolicy,
)
from invenio_rdm_records.requests import CommunityInclusion, CommunitySubmission
from invenio_rdm_records.services.permissions import RDMRequestsPermissionPolicy
from invenio_requests.services.generators import Creator, Receiver, Status
class CurationRDMRequestsPermissionPolicy(RDMRequestsPermissionPolicy):
"""Customized permission policy for sane handling of curation requests."""
rdm_policy = RDMRecordPermissionPolicy
curation_request_record_review = IfRequestTypes(
[CurationRequest],
then_=[RequestTopicGenerators(generators=rdm_policy.can_review)],
else_=[],
)
# Only allow community-submission requests to be accepted after
# the rdm-curation request has been accepted
can_action_accept = [
Expand All @@ -167,18 +181,28 @@ Since we only want to change the behaviour of these community submission request
]
# Update can read and can comment with new states
can_read = RDMRequestsPermissionPolicy.can_read + [
Status(
["review", "critiqued", "resubmitted"],
[Creator(), Receiver()],
),
can_read = [
IfRequestTypes(
[CurationRequest],
then_=[
Creator(),
Receiver(),
RequestTopicGenerators(generators=rdm_policy.can_review),
],
else_=RDMRequestsPermissionPolicy.can_read,
)
]
can_create_comment = can_read
# Add new actions
can_action_review = RDMRequestsPermissionPolicy.can_action_accept
can_action_critique = RDMRequestsPermissionPolicy.can_action_accept
can_action_resubmit = RDMRequestsPermissionPolicy.can_action_submit
can_action_submit = RDMRequestsPermissionPolicy.can_action_submit + [
curation_request_record_review
]
can_action_resubmit = can_action_submit
REQUESTS_PERMISSION_POLICY = CurationRDMRequestsPermissionPolicy
Expand Down
4 changes: 2 additions & 2 deletions invenio_curations/services/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from invenio_curations.services import facets

from .permissions import CurationPermissionPolicy
from .permissions import CurationRDMRequestsPermissionPolicy


class CurationsSearchOptions(RequestSearchOptions):
Expand Down Expand Up @@ -43,7 +43,7 @@ class CurationsServiceConfig(RecordServiceConfig, ConfiguratorMixin):

# common configuration
permission_policy_cls = FromConfig(
"REQUESTS_PERMISSION_POLICY", default=CurationPermissionPolicy
"REQUESTS_PERMISSION_POLICY", default=CurationRDMRequestsPermissionPolicy
)
# TODO: update search options?
search = CurationsSearchOptions
32 changes: 32 additions & 0 deletions invenio_curations/services/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

"""Curations related generators."""

from itertools import chain
from flask_principal import RoleNeed
from invenio_access.permissions import system_identity
from invenio_records_permissions.generators import ConditionalGenerator, Generator
Expand Down Expand Up @@ -60,6 +61,37 @@ def _condition(self, request=None, **kwargs):
return False


class RequestTopicGenerators(Generator):
"""Request-oriented generator forwarding the request topic to the provided generators.
Knowing what a request topic is, it is possible to perform checks on the topic itself.
Helpful to allow record managers access to a request as well.
"""

def __init__(self, generators=None, **kwargs):
self._generators = generators or set()
super().__init__()

def needs(self, request=None, **kwargs):
"""Set of Needs granting permission."""
if request is None:
return set()

# popping as we will set this ourselves
kwargs.pop("record")

# we could also do: return request.topic.get_needs() but get_needs is not implemented on the RDM Record Proxy
# we could also
# - subclass the rdm record entity resolver
# - implement the get_needs() for our use case
# - register the new resolver for `record` entities in invenio.cfg
needs = [
g.needs(record=request.topic.resolve(), **kwargs) for g in self._generators
]
return set(chain.from_iterable(needs))



class CurationModerators(Generator):
"""Permission generator that allows users with the `moderation` role."""

Expand Down
71 changes: 58 additions & 13 deletions invenio_curations/services/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,67 @@

"""Curations permissions."""

from invenio_requests.services.generators import Creator, Receiver, Status
from invenio_requests.services.permissions import (
PermissionPolicy as RequestPermissionPolicy,
from invenio_curations.requests.curation import CurationRequest
from invenio_curations.services.generators import (
IfCurationRequestAccepted,
IfRequestTypes,
RequestTopicGenerators,
)
from invenio_rdm_records.requests import CommunitySubmission
from invenio_rdm_records.services.permissions import (
RDMRequestsPermissionPolicy,
RDMRecordPermissionPolicy,
)
from invenio_requests.services.generators import Creator, Receiver, Status


class CurationPermissionPolicy(RequestPermissionPolicy):
"""Permission policy for curations."""
class CurationRDMRequestsPermissionPolicy(RDMRequestsPermissionPolicy):
"""Customized permission policy for sane handling of curation requests."""

can_read = RequestPermissionPolicy.can_read + [
Status(
["review", "critiqued", "resubmitted"],
[Creator(), Receiver()],
),
# specifying the RDM policy as we use the `can_review` permission for viewing a request.
# if needs for viewing request.topic record can be resolved otherwise, it would be great (maybe through EntityNeeds/EntityGrants as is done for Creator/Receiver)
rdm_policy = RDMRecordPermissionPolicy
curation_request_record_review = IfRequestTypes(
[CurationRequest],
then_=[RequestTopicGenerators(generators=rdm_policy.can_review)],
else_=[],
)

# Only allow community-submission requests to be accepted after
# the rdm-curation request has been accepted
can_action_accept = [
IfRequestTypes(
request_types=[
CommunitySubmission,
],
then_=[
IfCurationRequestAccepted(
then_=RDMRequestsPermissionPolicy.can_action_accept, else_=[]
)
],
else_=RDMRequestsPermissionPolicy.can_action_accept,
)
]

# Update can read and can comment with new states
can_read = [
IfRequestTypes(
[CurationRequest],
then_=[
Creator(),
Receiver(),
RequestTopicGenerators(generators=rdm_policy.can_review),
],
else_=RDMRequestsPermissionPolicy.can_read,
)
]

can_create_comment = can_read
can_action_review = RequestPermissionPolicy.can_action_accept
can_action_critique = RequestPermissionPolicy.can_action_accept
can_action_resubmit = RequestPermissionPolicy.can_action_cancel

# Add new actions
can_action_review = RDMRequestsPermissionPolicy.can_action_accept
can_action_critique = RDMRequestsPermissionPolicy.can_action_accept
can_action_submit = RDMRequestsPermissionPolicy.can_action_submit + [
curation_request_record_review
]
can_action_resubmit = can_action_submit
3 changes: 2 additions & 1 deletion invenio_curations/services/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ def create(self, identity, data=None, uow=None, **kwargs):
),
}

if self.get_review(identity, topic):
# using system identity to ensure a request is fetched, if it exists. Even if the user would not have access.
if self.get_review(system_identity, topic):
raise OpenRecordCurationRequestAlreadyExists()

if data:
Expand Down

0 comments on commit 8184203

Please sign in to comment.