Django viewflow custom permissions

249 Views Asked by At

Probably something simple. I am trying to follow the cookbook example on the following link https://github.com/viewflow/cookbook/tree/master/guardian. With the exception of a couple of unrelated differences between the example and my own code (I am not using frontend and am using custom views). Everything else works as expected. I do not understand what I am getting wrong on the permissions side of things.

I am getting a "403 forbidden" error whenever a user other than the one that started the process tries to interact with the flow. This happens irrespective of the assigned user's assigned permissions - is this the expected behavior or should I open a ticket on Github?

While I am trying to understand if viewflow can support what I am trying to accomplish - I would like to leave apply the permissions checking on my own views (rather than the built in checks). I saw that there was a pull request https://github.com/viewflow/viewflow/issues/252 - however, I do not understand how to implement it.

Any help would be appreciated! Been stuck on this for quite a while

The permissions are defined in a custom user class

accounts/models.py

class Department(models.Model):
    name = models.CharField(unique=True, max_length=250)
    description = models.TextField(blank=True)

    objects = managers.DepartmentManager()

    class Meta:
        permissions = [
            ('can_accept_bill', 'Can accept department bill'),
            ('can_validate_bill', 'Can validate department bill'),
            ('can_set_bill_paydate', 'Can set payment date for department bill'),
            ('can_pay_bill', 'Can pay department bill'),

flows.py

class OrderFlow(Flow):

    process_class = models.OrderProccess
    task_class = models.OrderTask
    lock_impl = select_for_update_lock

    start = (
        flow.Start(
            views.StartView)
        .Permission(auto_create=True)
        .Next(this.approve_budget)
    )

    approve_budget = (
        flow.View(
            views.BudgetApprovalView)
#        .Permission(auto_create=True)
        .Permission(
            'order.can_accept_bill',
            obj= lambda act: act.process.order.department
        )
        .Assign(lambda act: act.process.created_by)
        .Next(this.check_budget_approval)
    )

    check_budget_approval = (
        flow.If(
            cond=lambda act: act.process.order.budgetholder_approved
        )
        .Then(this.approve_finance)
        .Else(this.approve_budget)
    )

    approve_finance = (
        flow.View(
            views.FinanceApprovalView)
        .Permission(auto_create=True)
        .Assign(lambda act: act.process.created_by)
        .Next(this.check_finance_approval)
    )

models.py

class Order(models.Model):
    department = models.ForeignKey(account_models.Department, on_delete=models.CASCADE)
    description = models.CharField(max_length=30)
    project = models.ForeignKey(project_models.Project, on_delete=models.CASCADE)

# other unrelated code

class OrderProccess(Process):
    order = models.ForeignKey(Order, blank=True, null=True, on_delete=models.CASCADE)


class OrderTask(Task):
    class Meta:
        proxy = True

views.py

class StartView(StartFlowMixin, generic.UpdateView):
    model = models.Order
    form_class = forms.OrderForm

    def get_object(self):
        return self.activation.process.order

# other form handling code

class OrderView(FlowMixin, generic.UpdateView):

    def get_object(self):
        return self.activation.process.order

class BudgetApprovalView(FlowMixin, generic.UpdateView):
    form_class = forms.BudgetHolderApproval

    def get_object(self):
0

There are 0 best solutions below