Permission Management

In any workflow system, managing permissions is crucial to ensure that only authorized users can view, manage, or cancel processes. Viewflow provides a robust permission management system that allows for fine-grained control over who can perform various actions within a workflow.

Basic Permission Requirements

View Permission

To interact with a process, a user must at least have the view permission for the process model. This ensures that the user can access the process and see its details.

Manage Permission

In addition to view permissions, Viewflow introduces a manage permission. This permission is required for users to perform task-specific actions and process cancellations. Without this permission, users cannot execute tasks or manage the workflow effectively.

Overriding Permissions in Flow Classes

Viewflow allows overriding permissions within the flow class. This flexibility lets you define custom permission logic based on your specific requirements.

class SampleFlow(flow.Flow):
    def has_view_permission(self, user: Any, obj: Optional[Any] = None) -> bool:
        return super().has_view_permission(user, obj)

    def has_manage_permission(self, user: Any, obj: Optional[Any] = None) -> bool:
        return super().has_manage_permission(user, obj)

Managing Task Access

In Viewflow, task access is controlled using .Permission() and .Assign() definitions. These methods allow you to specify who can perform tasks and how tasks are assigned to users.

Here’s an example of a flow class demonstrating permission management:

class MyFlow(flow.Flow):

start = (
    flow.Start(views.StartView.as_view())
    .Permission("app_label.can_start_request")
    .Next(this.task1)
)

task1 = (
    flow.View(...)
    .Assign(lambda activation: User.object.filter(...).first())
    .Next(this.task2)
)

task2 = (
    flow.View(...)
    .Permission(auto_create=True)  # Permssion "app_label.can_next_task2" would be created
    .Next(this.task3)
)

task3 = (
    flow.View(...)
    .Assign(this.task2.owner)  # A helper callable, returns a user completed task2
    .Next(this.end)
)