Michael
Michael

Reputation: 335

Create custom permission classes

I have designed my own RBAC system for my Django app. Unlike the original Django's role-based that uses only permissions, content_types, groups, and users table, I designed mine so that it includes a model for defined operations (i.e. read, write, print), the objects (i.e. Post, Events, Documents), the roles (Writer Level 1, Events Manager) and the necessary relationships i.e. my own permissions table which takes in the object reference and a matching operation reference (i.e. Post | add).

My problem now is I am not quite sure how to implement this in DRF. When I use permission_class = (DjangoObjectPermissions,) and someone sends a 'POST' request to the Post model/table, we all know Django will check if the user has Can add post permission. I want to do this as well but I want Django to refer to my RBAC models/tables.

I want to write my own permission classes in my permissions.py but I might need a bit hint on how to implement this.

I've read you can create custom permissions, but I am not sure if that also means you can enforce your own RBAC tables with it.

Upvotes: 1

Views: 2701

Answers (2)

Michael
Michael

Reputation: 335

Alright after checking rest_frameworks' permissions.py, I think I can enforce my own permission class behavior this way:

  1. Create a custom permission class that subclasses rest_framework.permissions.BasePermission
  2. override has_object_permission() method
  3. Inside the method, write a logic that maps the requesting user into my custom RBAC models to check whether or not he has given the appropriate permission
  4. Return the appropriate boolean

Upvotes: 3

JPG
JPG

Reputation: 88659

According to the DRF Permissions doc

As with DjangoModelPermissions, this permission must only be applied to views that have a .queryset property or .get_queryset() method. Authorization will only be granted if the user is authenticated and has the relevant per-object permissions and relevant model permissions assigned.

So, you should define either queryset attribute or get_queryset(...) method in your view class.

Example:

class MyViewClass(viewsets.ModelViewSet):
    queryset = SomeModel.objects.all()
    ...
    ...
    ...

    def get_queryset(self):
        return SomeModel.objects.filter(some_field='foo')

    ...
    ...
    ...

The permissions to a User or groups can be controlled via Django's Admin site as well as Django shell

Upvotes: 1

Related Questions