How to handle object specific permissions in django-river?

111 Views Asked by At

I have a use case for django-river where users can approve some objects (database records) in a model but not all of them. I need to check if a user can approve a transition programmatically as a user can approve an object depending on the user and depending on the properties of the object (eg: Managers can approve posts that have the category 'fiction')

django-river allows specifying groups and permissions for transitions approval meta. However, this means that if a user has permission or they are part of a group, they can approve all objects.

I investigated a possible solution which is adding custom permissions to the model I have in the Meta subclass. Example:


class BlogPost(models.Model):
    title = models.CharField(verbose_name="Title", max_length=255)
    content = models.TextField(verbose_name="Content")

    state = StateField()

    def approve_draft(self, user):
        self.river.state.approve(as_user=user, next_state=State.objects.get(slug="published"))

    class Meta:
        permissions = [
            ("approve_draft", "Approve draft"),
        ]

    def __str__(self):
        return self.title

Then I added the approve_draft permission to the transition approval meta, and checked if the user has this permission using the has_perm function on the user model.

eg:

   ...
   ...
    def has_perm(self, perm: str, obj = None) -> bool:
        if perm = "app.approve_draft":
            # I have my logic here to check if the user has permissions to approve th obj
            return True
        return super().has_perm(perm, obj)

However, I investigated django-river source code and it does not seem to execute has_perm. it executes the auth backend get_all_permissions and gets all the permissions that are assigned to the user which of course don't include the object-specific permissions that I handle in has_perm.

Any way to solve this? or should I give up on using django-river for this purpose?

0

There are 0 best solutions below