Skip to content

Commit

Permalink
Merge pull request #41 from oarepo/krist/post-communities-merge-fixes
Browse files Browse the repository at this point in the history
Krist/post communities merge fixes
  • Loading branch information
mesemus authored Aug 15, 2024
2 parents d6e9003 + c6c126e commit 21f5267
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 46 deletions.
5 changes: 4 additions & 1 deletion oarepo_requests/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
AutoAcceptComponent,
RequestIdentityComponent,
)

try:
import oarepo_workflows # noqa
import oarepo_workflows # noqa

from oarepo_requests.actions.components import WorkflowTransitionComponent

workflow_action_components = [WorkflowTransitionComponent]
except ImportError:
workflow_action_components = []
Expand Down
18 changes: 17 additions & 1 deletion oarepo_requests/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,20 @@ def __init__(self, request_type, workflow):
@property
def description(self):
"""Exception's description."""
return f"Request type {self.request_type} not in workflow {self.workflow}."
return f"Request type {self.request_type} not in workflow {self.workflow}."


class ReceiverUnreferencable(Exception):
def __init__(self, request_type, record, **kwargs):
self.request_type = request_type
self.record = record
self.kwargs = kwargs

@property
def description(self):
"""Exception's description."""
message = f"Receiver for request type {self.request_type} is required but wasn't successfully referenced on record {self.record['id']}."
if self.kwargs:
message += "\n Additional keyword arguments:"
message += f"\n{', '.join(self.kwargs)}"
return message
6 changes: 4 additions & 2 deletions oarepo_requests/receiver.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from oarepo_requests.errors import RequestTypeNotInWorkflow
from oarepo_requests.errors import ReceiverUnreferencable, RequestTypeNotInWorkflow


def default_workflow_receiver_function(record=None, request_type=None, **kwargs):
from oarepo_workflows.proxies import current_oarepo_workflows

workflow_id = current_oarepo_workflows.get_workflow_from_record(record)
if not workflow_id:
return None
return None # exception?

try:

Expand All @@ -20,4 +20,6 @@ def default_workflow_receiver_function(record=None, request_type=None, **kwargs)
receiver = request.reference_receivers(
record=record, request_type=request_type, **kwargs
)
if not request_type.receiver_can_be_none and not receiver:
raise ReceiverUnreferencable(request_type=request_type, record=record, **kwargs)
return receiver
69 changes: 46 additions & 23 deletions oarepo_requests/services/permissions/generators.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from invenio_records_permissions.generators import Generator, ConditionalGenerator
from flask_principal import Identity
from invenio_records_permissions.generators import ConditionalGenerator, Generator
from invenio_records_resources.references.entity_resolvers import EntityProxy
from invenio_requests.proxies import current_requests
from invenio_search.engine import dsl

from oarepo_requests.services.permissions.identity import request_active
from oarepo_workflows.requests.policy import RecipientGeneratorMixin
from flask_principal import Identity

from invenio_requests.proxies import current_requests
from invenio_records_resources.references.entity_resolvers import EntityProxy
from oarepo_requests.services.permissions.identity import request_active


class RequestActive(Generator):
Expand All @@ -18,8 +17,20 @@ def query_filter(self, identity=None, **kwargs):
return dsl.Q("match_none")


class IfRequestType(ConditionalGenerator):
def __init__(self, request_types, then_):
super().__init__(then_, else_=[])
if not isinstance(request_types, (list, tuple)):
request_types = [request_types]
self.request_types = request_types

def _condition(self, request_type, **kwargs):
return request_type.type_id in self.request_types


try:
from oarepo_workflows import WorkflowPermission
from oarepo_workflows.errors import InvalidWorkflowError, MissingWorkflowError
from oarepo_workflows.proxies import current_oarepo_workflows

class CreatorsFromWorkflow(WorkflowPermission):
Expand All @@ -29,34 +40,34 @@ def needs(self, record=None, request_type=None, **kwargs):
workflow_request = current_oarepo_workflows.get_workflow(
record
).requests()[request_type.type_id]
except KeyError:
return workflow_request.needs(
request_type=request_type, record=record, **kwargs
)
except (MissingWorkflowError, InvalidWorkflowError):
return []
return workflow_request.needs(
request_type=request_type, record=record, **kwargs
)

def excludes(self, record=None, request_type=None, **kwargs):
try:
workflow_request = current_oarepo_workflows.get_workflow(
record
).requests()[request_type.type_id]
except KeyError:
return workflow_request.excludes(
request_type=request_type, record=record, **kwargs
)
except (MissingWorkflowError, InvalidWorkflowError):
return []
return workflow_request.excludes(
request_type=request_type, record=record, **kwargs
)

# not tested
def query_filter(self, record=None, request_type=None, **kwargs):
try:
workflow_request = current_oarepo_workflows.get_workflow(
record
).requests()[request_type.type_id]
except KeyError:
return workflow_request.query_filters(
request_type=request_type, record=record, **kwargs
)
except (MissingWorkflowError, InvalidWorkflowError):
return dsl.Q("match_none")
return workflow_request.query_filters(
request_type=request_type, record=record, **kwargs
)

except ImportError:
pass
Expand All @@ -78,12 +89,18 @@ def _condition(self, *, request_type, creator, **kwargs):
else:
if not isinstance(creator, EntityProxy):
# convert to entityproxy
creator = current_requests.entity_resolvers_registry.reference_entity(creator)
creator = current_requests.entity_resolvers_registry.reference_entity(
creator
)
needs = creator.get_needs()

for condition in self.requesters:
condition_needs = set(condition.needs(request_type=request_type, creator=creator, **kwargs))
condition_excludes = set(condition.excludes(request_type=request_type, creator=creator, **kwargs))
condition_needs = set(
condition.needs(request_type=request_type, creator=creator, **kwargs)
)
condition_excludes = set(
condition.excludes(request_type=request_type, creator=creator, **kwargs)
)

if not condition_needs.intersection(needs):
continue
Expand All @@ -96,9 +113,15 @@ def reference_receivers(self, record=None, request_type=None, **kwargs):
ret = []
for gen in self._generators(record=record, request_type=request_type, **kwargs):
if isinstance(gen, RecipientGeneratorMixin):
ret.extend(gen.reference_receivers(record=record, request_type=request_type, **kwargs))
ret.extend(
gen.reference_receivers(
record=record, request_type=request_type, **kwargs
)
)
return ret

def query_filter(self, **kwargs):
"""Search filters."""
raise NotImplementedError("Please use IfRequestedBy only in recipients, not elsewhere.")
raise NotImplementedError(
"Please use IfRequestedBy only in recipients, not elsewhere."
)
8 changes: 6 additions & 2 deletions oarepo_requests/services/permissions/workflow_policies.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from invenio_records_permissions.generators import SystemProcess
from invenio_requests.services.permissions import (
PermissionPolicy as RequestsPermissionPolicy,
PermissionPolicy as InvenioRequestsPermissionPolicy,
)
from oarepo_workflows import DefaultWorkflowPermissionPolicy

from oarepo_requests.services.permissions.generators import (
CreatorsFromWorkflow,
IfRequestType,
RequestActive,
)

Expand All @@ -16,8 +17,11 @@ class DefaultWithRequestsWorkflowPermissionPolicy(DefaultWorkflowPermissionPolic
can_edit = [RequestActive()]


class CreatorsFromWorkflowPermissionPolicy(RequestsPermissionPolicy):
class CreatorsFromWorkflowPermissionPolicy(InvenioRequestsPermissionPolicy):
can_create = [
SystemProcess(),
CreatorsFromWorkflow(),
IfRequestType(
["community-invitation"], InvenioRequestsPermissionPolicy.can_create
),
]
7 changes: 5 additions & 2 deletions oarepo_requests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

def allowed_request_types_for_record(record):
try:
from oarepo_workflows.proxies import current_oarepo_workflows
from oarepo_workflows.errors import MissingWorkflowError
from oarepo_workflows.proxies import current_oarepo_workflows

try:
workflow_requests = current_oarepo_workflows.get_workflow(record).requests()
except MissingWorkflowError:
Expand All @@ -26,7 +27,9 @@ def allowed_request_types_for_record(record):
# log?
return ret
for request_name, request_type in request_types.items():
allowed_type_keys = set(request_type.allowed_topic_ref_types)
allowed_type_keys = set(
request_type.allowed_topic_ref_types
) # allowed topic types does not work correctly - delete published allows community and documents_file_draft
if record_ref in allowed_type_keys:
if not workflow_requests or hasattr(workflow_requests, request_name):
ret[request_name] = request_type
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = oarepo-requests
version = 2.0.2
version = 2.0.3
description =
authors = Ronald Krist <[email protected]>
readme = README.md
Expand Down
18 changes: 10 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
)
from oarepo_workflows.base import Workflow
from oarepo_workflows.requests import RecipientGeneratorMixin

from oarepo_requests.services.permissions.generators import IfRequestedBy
from thesis.proxies import current_service
from thesis.records.api import ThesisDraft

Expand All @@ -36,6 +34,7 @@
OARepoSubmitAction,
)
from oarepo_requests.receiver import default_workflow_receiver_function
from oarepo_requests.services.permissions.generators import IfRequestedBy
from oarepo_requests.services.permissions.workflow_policies import (
DefaultWithRequestsWorkflowPermissionPolicy,
)
Expand Down Expand Up @@ -115,11 +114,9 @@ class RequestsWithApprove(WorkflowRequestPolicy):
class RequestsWithCT(WorkflowRequestPolicy):
conditional_recipient_rt = WorkflowRequest(
requesters=[AnyUser()],
recipients=[IfRequestedBy(
UserGenerator(1),
[UserGenerator(2)],
[UserGenerator(3)]
)],
recipients=[
IfRequestedBy(UserGenerator(1), [UserGenerator(2)], [UserGenerator(3)])
],
)


Expand Down Expand Up @@ -227,6 +224,7 @@ def ret_data(record_id):

return ret_data


@pytest.fixture()
def conditional_recipient_request_data_function():
def ret_data(record_id):
Expand All @@ -237,6 +235,7 @@ def ret_data(record_id):

return ret_data


@pytest.fixture()
def edit_record_data_function():
def ret_data(record_id):
Expand Down Expand Up @@ -358,7 +357,10 @@ def app_config(app_config):
app_config["OAREPO_REQUESTS_DEFAULT_RECEIVER"] = default_workflow_receiver_function

app_config["WORKFLOWS"] = WORKFLOWS
app_config["REQUESTS_REGISTERED_TYPES"] = [ApproveRequestType(), ConditionalRecipientRequestType()]
app_config["REQUESTS_REGISTERED_TYPES"] = [
ApproveRequestType(),
ConditionalRecipientRequestType(),
]
return app_config


Expand Down
9 changes: 3 additions & 6 deletions tests/test_requests/test_conditional_recipient.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import pytest

from oarepo_requests.errors import OpenRequestAlreadyExists

from .utils import link_api2testclient


def test_conditional_receiver_creator_matches(
Expand All @@ -17,7 +14,7 @@ def test_conditional_receiver_creator_matches(
# user[0] is not a creator, user[2] is receiver

creator = users[0]
assert creator.id == '1'
assert creator.id == "1"

creator_client = logged_client(creator)

Expand All @@ -29,7 +26,7 @@ def test_conditional_receiver_creator_matches(
)

assert resp_request_create.status_code == 201
assert resp_request_create.json["receiver"] == {"user": '2'}
assert resp_request_create.json["receiver"] == {"user": "2"}


def test_conditional_receiver_creator_does_not_match(
Expand All @@ -56,4 +53,4 @@ def test_conditional_receiver_creator_does_not_match(
)

assert resp_request_create.status_code == 201
assert resp_request_create.json["receiver"] == {"user": '3'}
assert resp_request_create.json["receiver"] == {"user": "3"}

0 comments on commit 21f5267

Please sign in to comment.