Skip to content

Commit

Permalink
Copy all the authorization rules while cycling
Browse files Browse the repository at this point in the history
  • Loading branch information
javrasya committed Sep 7, 2019
1 parent 17f7b99 commit d44e984
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 7 deletions.
4 changes: 3 additions & 1 deletion river/core/instanceworkflowobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def _re_create_cycled_path(self, from_state):
while not cycle_ended:
for old_approval in approvals:
if old_approval.enabled:
TransitionApproval.objects.get_or_create(
cycled_approval, _ = TransitionApproval.objects.get_or_create(
source_state=old_approval.source_state,
destination_state=old_approval.destination_state,
workflow=old_approval.workflow,
Expand All @@ -186,6 +186,8 @@ def _re_create_cycled_path(self, from_state):
status=PENDING,
meta=old_approval.meta
)
cycled_approval.permissions.set(old_approval.permissions.all())
cycled_approval.groups.set(old_approval.groups.all())
approvals = TransitionApproval.objects.filter(
workflow_object=self.workflow_object,
workflow=self.class_workflow.workflow,
Expand Down
80 changes: 74 additions & 6 deletions river/tests/core/test__instance_api.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from hamcrest import assert_that, equal_to, has_item, has_property, raises, calling, has_length, is_not
from hamcrest import assert_that, equal_to, has_item, has_property, raises, calling, has_length, is_not, all_of

from river.models import TransitionApproval
from river.models import TransitionApproval, PENDING
from river.models.factories import UserObjectFactory, StateObjectFactory, TransitionApprovalMetaFactory, PermissionObjectFactory, WorkflowFactory
from river.tests.matchers import has_permission
from river.tests.models import BasicTestModel
from river.tests.models.factories import BasicTestModelObjectFactory
from river.utils.exceptions import RiverException
Expand Down Expand Up @@ -309,31 +310,32 @@ def test_shouldAllowCyclicTransitions(self):
off_the_cycle_state = StateObjectFactory(label="off_the_cycle_state")

workflow = WorkflowFactory(initial_state=cycle_state_1, content_type=self.content_type, field_name="my_field")
TransitionApprovalMetaFactory.create(

meta_1 = TransitionApprovalMetaFactory.create(
workflow=workflow,
source_state=cycle_state_1,
destination_state=cycle_state_2,
priority=0,
permissions=[authorized_permission]
)

TransitionApprovalMetaFactory.create(
meta_2 = TransitionApprovalMetaFactory.create(
workflow=workflow,
source_state=cycle_state_2,
destination_state=cycle_state_3,
priority=0,
permissions=[authorized_permission]
)

TransitionApprovalMetaFactory.create(
meta_3 = TransitionApprovalMetaFactory.create(
workflow=workflow,
source_state=cycle_state_3,
destination_state=cycle_state_1,
priority=0,
permissions=[authorized_permission]
)

TransitionApprovalMetaFactory.create(
meta_4 = TransitionApprovalMetaFactory.create(
workflow=workflow,
source_state=cycle_state_3,
destination_state=off_the_cycle_state,
Expand All @@ -352,8 +354,74 @@ def test_shouldAllowCyclicTransitions(self):
approvals = TransitionApproval.objects.filter(workflow=workflow, workflow_object=workflow_object.model)
assert_that(approvals, has_length(4))

assert_that(approvals, has_item(
is_not(
all_of(
has_property("source_state", meta_1.source_state),
has_property("destination_state", meta_1.destination_state),
has_permission("permissions", has_length(1)),
has_permission("permissions", has_item(authorized_permission)),
has_property("status", PENDING),
)
)
))

assert_that(approvals, has_item(
is_not(
all_of(
has_property("source_state", meta_2.source_state),
has_property("destination_state", meta_2.destination_state),
has_permission("permissions", has_length(1)),
has_permission("permissions", has_item(authorized_permission)),
has_property("status", PENDING),
)
)
))

assert_that(approvals, has_item(
is_not(
all_of(
has_property("source_state", meta_3.source_state),
has_property("destination_state", meta_3.destination_state),
has_permission("permissions", has_length(1)),
has_permission("permissions", has_item(authorized_permission)),
has_property("status", PENDING),
)
)
))

workflow_object.model.river.my_field.approve(as_user=authorized_user, next_state=cycle_state_1)
assert_that(workflow_object.model.my_field, equal_to(cycle_state_1))

approvals = TransitionApproval.objects.filter(workflow=workflow, workflow_object=workflow_object.model)
assert_that(approvals, has_length(7))

assert_that(approvals, has_item(
all_of(
has_property("source_state", meta_1.source_state),
has_property("destination_state", meta_1.destination_state),
has_permission("permissions", has_length(1)),
has_permission("permissions", has_item(authorized_permission)),
has_property("status", PENDING),
)
))

assert_that(approvals, has_item(
all_of(
has_property("source_state", meta_2.source_state),
has_property("destination_state", meta_2.destination_state),
has_permission("permissions", has_length(1)),
has_permission("permissions", has_item(authorized_permission)),
has_property("status", PENDING),
)
))

assert_that(approvals, has_item(
all_of(
has_property("source_state", meta_3.source_state),
has_property("destination_state", meta_3.destination_state),
has_permission("permissions", has_length(1)),
has_permission("permissions", has_item(authorized_permission)),
has_property("status", PENDING),
)
))
28 changes: 28 additions & 0 deletions river/tests/matchers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from hamcrest.core.base_matcher import BaseMatcher
from hamcrest.core.helpers.wrap_matcher import wrap_matcher


def has_permission(name, match):
return HasPermissions(name, wrap_matcher(match))


class HasPermissions(BaseMatcher):
def __init__(self, permission_property_name, value_matcher):
self.permission_property_name = permission_property_name
self.value_matcher = value_matcher

def describe_to(self, description):
description.append_text("an object with a permission'") \
.append_text(self.permission_property_name) \
.append_text("' matching ") \
.append_description_of(self.value_matcher)

def _matches(self, item):
if item is None:
return False

if not hasattr(item, self.permission_property_name):
return False

permission_field = getattr(item, self.permission_property_name)
return self.value_matcher.matches(permission_field.all())

0 comments on commit d44e984

Please sign in to comment.