0

I need to check different types of permissions for different types of actions from request user. For example get permission only need [IsAuthenticated] but when user request perform_create method. I want to implement another permission that is CanCreateProject permissions.py

class CanCreateProject(permissions.BasePermission):  
  def has_object_permission(self, request, view, obj):
    if request.user.is_superuser:
        return True
    else:
      return request.user.profile_limitation.can_create_project
    

views.py

class ProjectView(ModelViewSet):
  serializer_class = ProjectSerializer
  permission_classes = [IsAuthenticated]

  def get_queryset(self):
    queryset = Project.objects.all()
    organization = self.request.user.organization
    query_set = queryset.filter(organization=organization)    
    return query_set
  
  def perform_create(self, serializer):
    
    self.permission_classes = [CanCreateProject] ## here

    project = self.request.data["project_name"]
    path = self.request.data["project_name"]
    organization = self.request.data["organization"]
    serializer.save(project_name=project, project_path=path, organization=organization)

How can I run the CanCreateProject method only for perform_create method is requested.

firefly
  • 876
  • 2
  • 15
  • 42

1 Answers1

2

Override the get_permissions(...) method

class ProjectView(ModelViewSet):
    serializer_class = ProjectSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = Project.objects.all()
        organization = self.request.user.organization
        query_set = queryset.filter(organization=organization)
        return query_set

    def get_permissions(self):
        if self.action == 'create':
            composed_perm = IsAuthenticated & CanCreateProject
            return [composed_perm()]

        return super().get_permissions()

    # def perform_create(self, serializer):
    #     self.permission_classes = [CanCreateProject]  ## here
    # 
    #     project = self.request.data["project_name"]
    #     path = self.request.data["project_name"]
    #     organization = self.request.data["organization"]
    #     serializer.save(project_name=project, project_path=path,
    #                     organization=organization)

Notes:

Update-1

You should implement the has_permission(..) method of the Permission class, not has_object_permission(...) method

from rest_framework import permissions


class CanCreateProject(permissions.BasePermission):
    def has_permission(self, request, view):
        if request.user.is_superuser:
            return True
        else:
            return request.user.profile_limitation.can_create_project
JPG
  • 82,442
  • 19
  • 127
  • 206
  • thank you for the answer. so, I just need to put inside of `perform_create` into `if self.action == 'create'` – firefly Oct 14 '20 at 05:03
  • Eh... I don't understand. My answer will work as-is – JPG Oct 14 '20 at 05:04
  • sorry for the before comment is unclear, in the end it's not checking the permission. just creating project without a permission. it's like `get_permission()` is not overridden – firefly Oct 14 '20 at 05:16
  • The `perform_create()` will get called ***only*** if the ***self.action is `create`*** (I hope the given view is a ***complete one***). – JPG Oct 14 '20 at 05:19
  • @yepsolutely Check the **`Update-1`** section of my answer. It seems you named the method incorrectly. – JPG Oct 14 '20 at 05:22
  • of course I imported the permissions, if I didn't, I get an error for that. and yes, gave the **complete**. view. In the end it's still creating without checking the permission. I also implemented a `print("called")` inside the `CanCreateProject` but after I request a create it does not written on the terminal. `get_permission` not calling `CanCreateProject` method it's just creating directly. – firefly Oct 14 '20 at 05:31
  • Sorry that in my `update-1` section had a typo. Check it out (in short, change `has_object_permission` to **`has_permission`**) – JPG Oct 14 '20 at 05:38
  • 2
    thank you it's working now. I guess I need to check difference between `has_permission` and `has_object_permission` By the way you should remove the `obj` from **has_permission()** class, it doesn't take one. Thanks again. – firefly Oct 14 '20 at 05:43