Support allowed() in workflows.Step
There are cases where we want to display workflow Step conditionally. Change-Id: I71ae3ed270d9472190430ac5b4a34682ce3b3f29 Closes-Bug: #1683262
This commit is contained in:
@@ -82,6 +82,14 @@ class AdminAction(workflows.Action):
|
|||||||
permissions = ("horizon.test",)
|
permissions = ("horizon.test",)
|
||||||
|
|
||||||
|
|
||||||
|
class TestDisabledAction(workflows.Action):
|
||||||
|
disabled_id = forms.CharField(label="Disabled")
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = "Test Action Disabled"
|
||||||
|
slug = "test_action_disabled"
|
||||||
|
|
||||||
|
|
||||||
class AdminForbiddenAction(workflows.Action):
|
class AdminForbiddenAction(workflows.Action):
|
||||||
admin_id = forms.CharField(label="Admin forbidden")
|
admin_id = forms.CharField(label="Admin forbidden")
|
||||||
|
|
||||||
@@ -121,6 +129,14 @@ class AdminStep(workflows.Step):
|
|||||||
before = TestStepTwo
|
before = TestStepTwo
|
||||||
|
|
||||||
|
|
||||||
|
class TestDisabledStep(workflows.Step):
|
||||||
|
action_class = TestDisabledAction
|
||||||
|
contributes = ("disabled_id",)
|
||||||
|
|
||||||
|
def allowed(self, request):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class AdminForbiddenStep(workflows.Step):
|
class AdminForbiddenStep(workflows.Step):
|
||||||
action_class = AdminForbiddenAction
|
action_class = AdminForbiddenAction
|
||||||
|
|
||||||
@@ -312,6 +328,15 @@ class WorkflowsTests(test.TestCase):
|
|||||||
'<AdminStep: admin_action>',
|
'<AdminStep: admin_action>',
|
||||||
'<TestStepTwo: test_action_two>'])
|
'<TestStepTwo: test_action_two>'])
|
||||||
|
|
||||||
|
def test_has_allowed(self):
|
||||||
|
TestWorkflow.register(TestDisabledStep)
|
||||||
|
flow = TestWorkflow(self.request)
|
||||||
|
# Check TestDisabledStep is not included
|
||||||
|
# even though TestDisabledStep is registered.
|
||||||
|
self.assertQuerysetEqual(flow.steps,
|
||||||
|
['<TestStepOne: test_action_one>',
|
||||||
|
'<TestStepTwo: test_action_two>'])
|
||||||
|
|
||||||
def test_step_is_hidden_on_policy(self):
|
def test_step_is_hidden_on_policy(self):
|
||||||
self.policy_patcher.stop()
|
self.policy_patcher.stop()
|
||||||
|
|
||||||
|
@@ -465,6 +465,16 @@ class Step(object):
|
|||||||
"""Returns True if action contains any required fields."""
|
"""Returns True if action contains any required fields."""
|
||||||
return any(field.required for field in self.action.fields.values())
|
return any(field.required for field in self.action.fields.values())
|
||||||
|
|
||||||
|
def allowed(self, request):
|
||||||
|
"""Determines whether or not the step is displayed.
|
||||||
|
|
||||||
|
Step instances can override this method to specify conditions under
|
||||||
|
which this tab should not be shown at all by returning ``False``.
|
||||||
|
|
||||||
|
The default behavior is to return ``True`` for all cases.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class WorkflowMetaclass(type):
|
class WorkflowMetaclass(type):
|
||||||
def __new__(mcs, name, bases, attrs):
|
def __new__(mcs, name, bases, attrs):
|
||||||
@@ -694,7 +704,8 @@ class Workflow(html.HTMLElement):
|
|||||||
for step_class in ordered_step_classes:
|
for step_class in ordered_step_classes:
|
||||||
cls = self._registry[step_class]
|
cls = self._registry[step_class]
|
||||||
if (has_permissions(self.request.user, cls) and
|
if (has_permissions(self.request.user, cls) and
|
||||||
policy.check(cls.policy_rules, self.request)):
|
policy.check(cls.policy_rules, self.request) and
|
||||||
|
cls.allowed(self.request)):
|
||||||
self._ordered_steps.append(cls)
|
self._ordered_steps.append(cls)
|
||||||
|
|
||||||
def _order_steps(self):
|
def _order_steps(self):
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Horizon workflow Step now support allowed() method to determine
|
||||||
|
the step should be displayed conditionally.
|
||||||
|
The workflow Step class already support policy check and permission
|
||||||
|
mechanism to decide the step should be displayed, but allowed() is used
|
||||||
|
to support more complex or dynamic condition.
|
Reference in New Issue
Block a user