Move transition ACLs filtering from the form to the model.

This way it is usable from many places without duplication.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
Roberto Rosario
2017-02-23 23:39:31 -04:00
parent cca5a44dc1
commit dda2bfd7a8
2 changed files with 41 additions and 28 deletions
+3 -23
View File
@@ -40,29 +40,9 @@ class WorkflowInstanceTransitionForm(forms.Form):
user = kwargs.pop('user') user = kwargs.pop('user')
workflow_instance = kwargs.pop('workflow_instance') workflow_instance = kwargs.pop('workflow_instance')
super(WorkflowInstanceTransitionForm, self).__init__(*args, **kwargs) super(WorkflowInstanceTransitionForm, self).__init__(*args, **kwargs)
queryset = workflow_instance.get_transition_choices().all() self.fields[
'transition'
try: ].queryset = workflow_instance.get_transition_choices(_user=user)
Permission.check_permissions(
requester=user, permissions=(permission_workflow_transition,)
)
except PermissionDenied:
try:
# Check for ACL access to the workflow, if true, allow all
# transition options.
AccessControlList.objects.check_access(
permissions=permission_workflow_transition, user=user,
obj=workflow_instance.workflow
)
except PermissionDenied:
# If not ACL access to the workflow, filter transition options
# by each transition ACL access
queryset = AccessControlList.objects.filter_by_access(
permission=permission_workflow_transition, user=user,
queryset=queryset
)
self.fields['transition'].queryset = queryset
transition = forms.ModelChoiceField( transition = forms.ModelChoiceField(
label=_('Transition'), queryset=WorkflowTransition.objects.none() label=_('Transition'), queryset=WorkflowTransition.objects.none()
+38 -5
View File
@@ -1,17 +1,20 @@
from __future__ import unicode_literals from __future__ import absolute_import, unicode_literals
import logging import logging
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import PermissionDenied, ValidationError
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db import IntegrityError, models from django.db import IntegrityError, models
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from acls.models import AccessControlList
from documents.models import Document, DocumentType from documents.models import Document, DocumentType
from permissions import Permission
from .managers import WorkflowManager from .managers import WorkflowManager
from .permissions import permission_workflow_transition
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -166,11 +169,41 @@ class WorkflowInstance(models.Model):
except AttributeError: except AttributeError:
return None return None
def get_transition_choices(self): def get_transition_choices(self, _user=None):
current_state = self.get_current_state() current_state = self.get_current_state()
if current_state: if current_state:
return current_state.origin_transitions.all() queryset = current_state.origin_transitions.all()
if _user:
try:
Permission.check_permissions(
requester=_user, permissions=(
permission_workflow_transition,
)
)
except PermissionDenied:
try:
"""
Check for ACL access to the workflow, if true, allow
all transition options.
"""
AccessControlList.objects.check_access(
permissions=permission_workflow_transition,
user=_user, obj=self.workflow
)
except PermissionDenied:
"""
If not ACL access to the workflow, filter transition
options by each transition ACL access
"""
queryset = AccessControlList.objects.filter_by_access(
permission=permission_workflow_transition,
user=_user, queryset=queryset
)
return queryset
else: else:
""" """
This happens when a workflow has no initial state and a document This happens when a workflow has no initial state and a document
@@ -209,5 +242,5 @@ class WorkflowInstanceLogEntry(models.Model):
verbose_name_plural = _('Workflow instance log entries') verbose_name_plural = _('Workflow instance log entries')
def clean(self): def clean(self):
if self.transition not in self.workflow_instance.get_transition_choices(): if self.transition not in self.workflow_instance.get_transition_choices(_user=self.user):
raise ValidationError(_('Not a valid transition choice.')) raise ValidationError(_('Not a valid transition choice.'))