예제 #1
0
    def test_unpriviledged_access_prohibited(self):
        self.assertFalse(has_transition_perm(self.model.publish, self.unpriviledged))
        self.assertFalse(has_transition_perm(self.model.remove, self.unpriviledged))

        transitions = self.model.get_available_user_state_transitions(self.unpriviledged)
        self.assertEquals(set(['moderate']),
                          set(transition.name for transition in transitions))
예제 #2
0
    def test_proviledged_access_succed(self):
        self.assertTrue(has_transition_perm(self.model.publish, self.priviledged))
        self.assertTrue(has_transition_perm(self.model.remove, self.priviledged))

        transitions = self.model.get_available_user_state_transitions(self.priviledged)
        self.assertEquals(set(['publish', 'remove', 'moderate']),
                          set(transition.name for transition in transitions))
예제 #3
0
    def test_proviledged_access_succed(self):
        self.assertTrue(has_transition_perm(self.model.publish, self.priviledged))
        self.assertTrue(has_transition_perm(self.model.remove, self.priviledged))

        transitions = self.model.get_available_user_state_transitions(self.priviledged)
        self.assertEquals(set(['publish', 'remove', 'moderate']),
                          set(transition.name for transition in transitions))
예제 #4
0
    def get_context_data(self, **kwargs):
        context = super(TaskDetailView, self).get_context_data(**kwargs)
        task = self.object

        if self.request.user.has_perm('indigo_api.change_task'):
            context['change_task_permission'] = True

        if has_transition_perm(task.submit, self):
            context['submit_task_permission'] = True

        if has_transition_perm(task.reopen, self):
            context['reopen_task_permission'] = True

        if has_transition_perm(task.unsubmit, self):
            context['unsubmit_task_permission'] = True

        if has_transition_perm(task.close, self):
            context['close_task_permission'] = True

        context['possible_workflows'] = Workflow.objects.unclosed().filter(
            country=task.country, locality=task.locality).all()

        Task.decorate_potential_assignees([task], self.country)

        return context
예제 #5
0
    def test_unpriviledged_access_prohibited(self):
        self.assertFalse(has_transition_perm(self.model.publish, self.unpriviledged))
        self.assertFalse(has_transition_perm(self.model.remove, self.unpriviledged))

        transitions = self.model.get_available_user_state_transitions(self.unpriviledged)
        self.assertEquals(set(['moderate']),
                          set(transition.name for transition in transitions))
예제 #6
0
    def test_cancel_permissions(self):
        application = ApplicationFactory.create(
            owner=self.resident,
            shift=self.shift,
            state=ApplicationStateEnum.APPROVED)

        # Resident can cancel approved application
        self.assertTrue(
            has_transition_perm(application.cancel, self.resident.user_ptr))

        # Scheduler can cancel approved applications
        self.assertTrue(
            has_transition_perm(application.cancel, self.scheduler.user_ptr))

        application = ApplicationFactory.create(
            owner=self.resident,
            shift=self.shift,
            state=ApplicationStateEnum.CONFIRMED)

        # Resident can cancel confirmed application
        self.assertTrue(
            has_transition_perm(application.cancel, self.resident.user_ptr))

        # Scheduler can cancel confirmed applications
        self.assertTrue(
            has_transition_perm(application.cancel, self.scheduler.user_ptr))
예제 #7
0
 def set_transition_permissions(self, user):
     self.can_submit = has_transition_perm(self.submit, user)
     self.can_accept = has_transition_perm(self.accept, user)
     self.can_reject = has_transition_perm(self.reject, user)
     self.can_appeal = has_transition_perm(self.appeal, user)
     self.can_pay = has_transition_perm(self.pay, user)
     self.can_edit = self.requested_by == user and self.is_editable
     self.button_comment = "Edit" if self.can_edit else "Review"
예제 #8
0
    def test_reject_permissions(self):
        application = ApplicationFactory.create(owner=self.resident,
                                                shift=self.shift)

        # Resident can't reject application
        self.assertFalse(
            has_transition_perm(application.reject, self.resident.user_ptr))

        # Scheduler can reject own shift's applications
        self.assertTrue(
            has_transition_perm(application.reject, self.scheduler.user_ptr))
예제 #9
0
    def decorate_permissions(cls, tasks, view):
        for task in tasks:
            task.change_task_permission = view.request.user.has_perm(
                'indigo_api.change_task')
            task.submit_task_permission = has_transition_perm(
                task.submit, view)
            task.reopen_task_permission = has_transition_perm(
                task.reopen, view)
            task.unsubmit_task_permission = has_transition_perm(
                task.unsubmit, view)
            task.close_task_permission = has_transition_perm(task.close, view)

        return tasks
예제 #10
0
    def test_reject_permission(self):
        resident = ResidentFactory.create(
            state=ResidentStateEnum.PROFILE_FILLED)

        # Scheduler (not account manager) can't approve resident
        scheduler = SchedulerFactory.create()

        self.assertFalse(has_transition_perm(
            resident.reject, scheduler))

        # Account manager can approve resident
        self.assertTrue(has_transition_perm(
            resident.reject, self.account_manager))
예제 #11
0
 def check_transition_permission(self, transition, user):
     try:
         if not can_proceed(transition) or not has_transition_perm(
                 transition, user):
             raise PermissionDenied
     except CoreValidationError as exc:
         raise ValidationError(dict([error for error in exc]))
예제 #12
0
    def post(self, request, *args, **kwargs):
        task = self.get_object()
        user = self.request.user
        task.updated_by_user = user

        if task.customised:
            # redirect to custom close url, if necessary
            if self.change == 'close' and task.customised.close_url():
                return redirect(task.customised.close_url())

        for change, verb in Task.VERBS.items():
            if self.change == change:
                state_change = getattr(task, change)
                if not has_transition_perm(state_change, self):
                    raise PermissionDenied

                state_change(user)

                if change == 'submit':
                    verb = 'submitted for review'
                if change == 'unsubmit':
                    verb = 'returned with changes requested'
                messages.success(request, "Task '%s' has been %s" % (task.title, verb))

        task.save()

        return redirect(self.get_redirect_url())
    def transition_action(self, request, *args, **kwargs):
        instance = self.get_object()
        transition_method = getattr(instance, transition_name)

        if not can_proceed(transition_method, self.request.user):
            raise exceptions.ValidationError(
                {'detail': _('Conditions not met')})

        if not has_transition_perm(transition_method, self.request.user):
            raise exceptions.PermissionDenied

        if hasattr(self, 'get_{0}_kwargs'.format(transition_name)):
            transition_kwargs = getattr(
                self, 'get_{0}_kwargs'.format(transition_name))()
        else:
            transition_kwargs = {}

        if 'by' in inspect.signature(transition_method).parameters.keys(
        ) and 'by' not in transition_kwargs:
            transition_kwargs['by'] = self.request.user

        transition_method(**transition_kwargs)

        if self.save_after_transition:
            instance.save()

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        serializer = self.get_serializer(instance)
        return Response(serializer.data)
예제 #14
0
 def post(self, request, **kwargs):
     if 'transition' in request.POST:
         with transaction.atomic():
             self.object = self.get_object(
                 self.get_queryset().select_for_update())
             if request.POST.get(
                     'transition') in self.available_transitions:
                 transition = getattr(self.object,
                                      request.POST['transition'])
                 if not has_transition_perm(transition, request.user):
                     raise PermissionDenied
                 transition_kwargs = self.get_transition_kwargs(
                     request.POST['transition']) or {}
                 transition(**transition_kwargs)
                 self.object.save()
                 return redirect(
                     request.POST.get('next')
                     or self.request.build_absolute_uri())
             else:
                 return HttpResponseBadRequest()
     else:
         try:
             method = super().post
         except AttributeError:
             return HttpResponseBadRequest()
         else:
             return method(request, **kwargs)
예제 #15
0
    def get(self, request, *args, **kwargs):
        action = request.GET.get('action', None)
        pk = request.GET.get('pk', None)

        if pk is None or action is None:
            raise Http404()

        record = self.model.objects.filter(pk=pk).first()
        action = getattr(record, 'set_' + action)

        # check if user has permission to execute the method
        if not has_transition_perm(action, request.user):
            messages.warning(request, "Permission Denied")

        else:
            # try to transition and catchese if not allowed
            try:
                action(by=request.user)
                record.state_date = dt.datetime.now()
                record.save()

            except TransitionNotAllowed:
                messages.warning(request, "Transition Not Allowed")

        return redirect(
            reverse(self.url_redirect_workflow_table) + '?pk=%s' % pk)
예제 #16
0
    def get(self, request, *args, **kwargs):
        action = request.GET.get('action', None)
        pk = request.GET.get('pk', None)

        if pk is None or action is None:
            raise Http404()

        record = self.model.objects.filter(pk=pk).first()
        action = getattr(record, 'set_' + action)

        # check if user has permission to execute the method
        if not can_proceed(action):
            if action.__name__ == 'set_verify_invoices':
                messages.warning(request,
                                 "Task Must Be Work in Progress or Higher")
            else:
                messages.warning(request, "Transistion is not Allowed")

        elif not has_transition_perm(action, request.user):
            messages.warning(request, "Permission Denied")

        else:
            action(by=request.user)
            record.save()

        return redirect(
            reverse(self.url_redirect_workflow_table) + '?pk=%s' % pk)
예제 #17
0
    def get_context_data(self, **kwargs):
        context = super(TaskEditView, self).get_context_data(**kwargs)

        work = None
        task = self.object
        if task.work:
            work = json.dumps(
                WorkSerializer(instance=task.work,
                               context={
                                   'request': self.request
                               }).data)
        context['work_json'] = work

        document = None
        if task.document:
            document = json.dumps(
                DocumentSerializer(instance=task.document,
                                   context={
                                       'request': self.request
                                   }).data)
        context['document_json'] = document

        context['task_labels'] = TaskLabel.objects.all()
        context['place_workflows'] = self.place.workflows.filter(closed=False)

        if has_transition_perm(task.cancel, self):
            context['cancel_task_permission'] = True

        return context
예제 #18
0
    def test_complete_permissions(self):
        self.shift.date_start = timezone.now() - timedelta(hours=2)
        self.shift.date_end = timezone.now() - timedelta(hours=1)
        self.shift.save()
        application = ApplicationFactory.create(
            owner=self.resident,
            shift=self.shift,
            state=ApplicationStateEnum.CONFIRMED)

        # Resident can't complete confirmed application
        self.assertFalse(
            has_transition_perm(application.complete, self.resident.user_ptr))

        # Scheduler can complete confirmed applications
        self.assertTrue(
            has_transition_perm(application.complete, self.scheduler.user_ptr))
예제 #19
0
    def transition(self, request, *args, **kwargs):
        """
        Change status of FSM controlled object
        """
        action = kwargs.get('action', False)
        instance = self.get_object()
        instance_action = getattr(instance, action, None)
        if not instance_action or not hasattr(instance_action, '_django_fsm'):
            raise Http404

        try:
            if not can_proceed(instance_action) or not has_transition_perm(
                    instance_action, request.user):
                raise PermissionDenied
        except CoreValidationError as ex:
            raise ValidationError(dict([error for error in ex]))

        fsm_meta = instance_action._django_fsm
        field_name = fsm_meta.field if isinstance(
            fsm_meta.field, six.string_types) else fsm_meta.field.name
        transition_serializer = fsm_meta.get_transition(
            getattr(instance, field_name)).custom.get('serializer')
        if transition_serializer:
            serializer = transition_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            instance_action(**serializer.validated_data)
        else:
            instance_action()

        instance.save()

        return self.retrieve(request, *args, **kwargs)
예제 #20
0
    def test_approve_permissions(self):
        application = ApplicationFactory.create(owner=self.resident,
                                                shift=self.shift)

        # Resident can't approve application
        self.assertFalse(
            has_transition_perm(application.approve, self.resident.user_ptr))

        # Scheduler can accept own shift's applications
        self.assertTrue(
            has_transition_perm(application.approve, self.scheduler.user_ptr))

        another_application = ApplicationFactory.create()
        # Scheduler can't approve now own shift's applications
        self.assertFalse(
            has_transition_perm(another_application.approve,
                                self.scheduler.user_ptr))
예제 #21
0
    def save(self, *args, **kwargs):
        meeting = super().save(commit=False, *args, **kwargs)

        if has_transition_perm(meeting.reserve, self.protege):
            meeting.reserve(reserved_by=self.protege)
            meeting = meeting.save()

        return meeting
예제 #22
0
def user_has_transition_perm(user, obj_type_name, obj_id, perm_func_name):
    if (obj_type_name == 'manuscript'):
        obj = Manuscript.objects.get(id=int(obj_id))
    elif (obj_type_name == 'submission'):
        obj = Submission.objects.get(id=int(obj_id))

    perm_func = getattr(obj, perm_func_name)

    return has_transition_perm(perm_func, user)
예제 #23
0
파일: views.py 프로젝트: agmm/horas
    def post(self, *args, **kwargs):
        meeting = self.get_object()

        if not has_transition_perm(meeting.confirm, self.request.user):
            raise PermissionDenied

        meeting.confirm(confirmed_by=self.request.user)
        meeting.save()

        return HttpResponseRedirect(self.get_success_url())
예제 #24
0
    def test_blacklisted_return(self):
        order = Order.objects.create(customer="Abusive Returner",
                                     address="1 main street",
                                     item="blue lightsaber",
                                     price=100)

        order.ship()
        order.save()

        self.assertFalse(
            has_transition_perm(order.receive_return, order.customer))
예제 #25
0
파일: tasks.py 프로젝트: nmmanas/indigo
    def get_context_data(self, **kwargs):
        context = super(TaskDetailView, self).get_context_data(**kwargs)
        task = self.object

        if self.request.user.has_perm('indigo_api.change_task'):
            context['change_task_permission'] = True

        if has_transition_perm(task.submit, self):
            context['submit_task_permission'] = True

        if has_transition_perm(task.reopen, self):
            context['reopen_task_permission'] = True

        if has_transition_perm(task.unsubmit, self):
            context['unsubmit_task_permission'] = True

        if has_transition_perm(task.close, self):
            context['close_task_permission'] = True

        return context
def transition(request, uuid):
    doc = get_object_or_404(Document, uuid=uuid)
    is_document_editor(request, doc)
    try:
        transition = getattr(doc, request.data['transition'])
        if not has_transition_perm(transition, request.user):
            raise PermissionDenied
        transition()
        doc.save()
        return Response({"message": "Success",
                         "document": DocumentInfoSerializer(doc, context={'user': request.user}).data})
    except RuntimeError as e:
        return Response({"message": e.message, "args": e.args}, status=400)
예제 #27
0
    def inner_func(self, request, pk=None):
        object = self.get_object()
        transition_method = getattr(object, transition_name)
        if not has_transition_perm(transition_method, request.user):
            raise PermissionDenied
        if not object.can_transition(request.user, transition_method):
            raise PermissionDenied
        transition_method(by=request.user)

        if self.save_after_transition:
            object.save()

        serializer = self.get_serializer(object)
        return Response(serializer.data)
    def inner_func(self, request, pk=None):
        object = self.get_object()
        transition_method = getattr(object, transition_name)
        if not has_transition_perm(transition_method, request.user):
            raise PermissionDenied
        if not object.can_transition(request.user, transition_method):
            raise PermissionDenied
        transition_method(by=request.user)

        if self.save_after_transition:
            object.save()

        serializer = self.get_serializer(object)
        return Response(serializer.data)
예제 #29
0
 def fn(self, request, **kwargs):
     args = self.get_serializer(data=request.data)
     args.is_valid(raise_exception=True)
     obj = self.get_object()
     transition = getattr(obj, name)
     if can_proceed(transition) and\
        has_transition_perm(transition, request.user):
         try:
             transition(**args.validated_data)
         except TransitionNotAllowed as err:
             raise ValidationError(str(err))
         obj.save()
         return Response(status=204)
     else:
         raise ValidationError(
             "You cant perform '{}' transition".format(name))
예제 #30
0
    def post(self, request, *args, **kwargs):
        task = self.get_object()
        user = self.request.user
        task.updated_by_user = user
        task_content_type = ContentType.objects.get_for_model(task)
        comment_text = request.POST.get('comment', None)

        if task.customised:
            # redirect to custom close url, if necessary
            if self.change == 'close' and task.customised.close_url():
                return redirect(task.customised.close_url())

        for change, verb in Task.VERBS.items():
            if self.change == change:
                state_change = getattr(task, change)
                if not has_transition_perm(state_change, self):
                    raise PermissionDenied

                if comment_text:
                    comment = Comment(user=user,
                                      object_pk=task.id,
                                      user_name=user.get_full_name()
                                      or user.username,
                                      user_email=user.email,
                                      comment=comment_text,
                                      content_type=task_content_type,
                                      site_id=get_current_site(request).id)

                    state_change(user, comment=comment.comment)
                    # save the comment here so that it appears after the action
                    comment.submit_date = now()
                    comment.save()

                else:
                    state_change(user)

                if change == 'submit':
                    verb = 'submitted for review'
                if change == 'unsubmit':
                    verb = 'returned with changes requested'
                messages.success(request,
                                 "Task '%s' has been %s" % (task.title, verb))

        task.save()

        return redirect(self.get_redirect_url())
예제 #31
0
def task_view(request, task_status_id=None):
    task_status = get_object_or_404(TaskStatus, pk=task_status_id)
    if request.method == 'POST':
        form = SendTaskBackForm(request.POST)
        if form.is_valid():
            task_status.comment = form.cleaned_data['comment']
            task_status.response = form.cleaned_data['response']
            task_status.save()
            return redirect('send_task_back', task_status_id=task_status_id)
    task = task_status.task
    can_be_sent = (can_proceed(task_status.send)
                   and has_transition_perm(task_status.send, request.user))
    review_mode = (task_status.state == 'RVW' and request.user.is_superuser)
    context = {
        'task': task,
        'task_status': task_status,
        'can_be_sent': can_be_sent,
        'review_mode': review_mode,
        'user': request.user
    }
    if review_mode:
        form = SendTaskBackForm()
        context['form'] = form
    return render(request, "task.html", context)
예제 #32
0
 def test_permission_instance_method(self):
     self.assertFalse(has_transition_perm(self.model.restore, self.unpriviledged))
     self.assertTrue(has_transition_perm(self.model.restore, self.staff))
 def test_object_only_other_access_prohibited(self):
     self.assertFalse(has_transition_perm(self.model.publish, self.unprivileged))
예제 #34
0
 def set_transition_permissions(self, user):
     self.can_accept = has_transition_perm(self.accept, user)
     self.can_reject = has_transition_perm(self.reject, user)
     self.can_suspend = has_transition_perm(self.suspend, user)
     self.can_restore = has_transition_perm(self.restore, user)
     self.can_terminate = has_transition_perm(self.terminate, user)
예제 #35
0
 def change_state(self, state, user):
     state_method = getattr(self, state)
     if can_proceed(state_method) and has_transition_perm(
             state_method, user):
         state_method()
         self.save()
예제 #36
0
    def post(self, request, *args, **kwargs):
        task = self.get_object()
        user = self.request.user
        task.updated_by_user = user

        potential_changes = {
            'submit': 'submitted',
            'cancel': 'cancelled',
            'reopen': 'reopened',
            'unsubmit': 'unsubmitted',
            'close': 'closed',
        }

        for change, verb in potential_changes.items():
            if self.change == change:
                state_change = getattr(task, change)
                if not has_transition_perm(state_change, self):
                    raise PermissionDenied
                state_change(user)
                if verb == 'submitted':
                    task.last_assigned_to = task.assigned_to
                    task.assigned_to = None
                    action.send(user,
                                verb=verb,
                                action_object=task,
                                place_code=task.place.place_code)
                    messages.success(
                        request, u"Task '%s' has been submitted for review" %
                        task.title)
                elif verb == 'unsubmitted' and task.last_assigned_to:
                    assignee = task.last_assigned_to
                    task.assigned_to = assignee
                    if user.id == assignee.id:
                        action.send(user,
                                    verb='unsubmitted and picked up',
                                    action_object=task,
                                    place_code=task.place.place_code)
                        messages.success(
                            request,
                            u"You have unsubmitted and picked up the task '%s'"
                            % task.title)
                    else:
                        action.send(user,
                                    verb='unsubmitted and reassigned',
                                    action_object=task,
                                    target=assignee,
                                    place_code=task.place.place_code)
                        messages.success(
                            request,
                            u"Task '%s' has been unsubmitted and reassigned" %
                            task.title)

                else:
                    if verb == 'closed' or verb == 'cancelled':
                        task.assigned_to = None
                    action.send(user,
                                verb=verb,
                                action_object=task,
                                place_code=task.place.place_code)
                    messages.success(
                        request, u"Task '%s' has been %s" % (task.title, verb))

        task.save()

        return redirect('task_detail',
                        place=self.kwargs['place'],
                        pk=self.kwargs['pk'])
예제 #37
0
파일: views.py 프로젝트: unicef/etools
 def check_transition_permission(self, transition, user):
     try:
         if not can_proceed(transition) or not has_transition_perm(transition, user):
             raise PermissionDenied
     except CoreValidationError as exc:
         raise ValidationError(dict([error for error in exc]))
 def test_object_only_access_success(self):
     self.assertTrue(has_transition_perm(self.model.publish, self.privileged))
     self.model.publish()