rsinger86 / drf-access-policy

Declarative access policies/permissions modeled after AWS' IAM policies.
https://rsinger86.github.io/drf-access-policy/
MIT License
472 stars 50 forks source link

`view.get_object()` raises AssertionError inside condition method #69

Open jdrempel opened 3 years ago

jdrempel commented 3 years ago

Hi there.

I'm using view.get_object() as shown in the documentation but in certain cases there is an assertion failing (lookup_url_kwarg in self.kwargs) inside of get_object(). In the example I share here, it's on the list action, where the url follows the pattern: /quiz/?course=<pk>. In another case, however, it's when I use the create action on a different model.

Expected view QuizViewSet to be called with a URL keyword argument named "pk". Fix your URL conf, or set the .lookup_field attribute on the view correctly.

Here is my policy:

statements = [
  {
    'action': ['retrieve'],
    'principal': 'authenticated',
    'effect': 'allow',
    'condition_expression': 'is_in_course and accessible_if_student'
  }
]

The condition methods:

def is_in_course(self, request, view, action):
  user = request.user
  quiz = view.get_object()  # raises AssertionError on list action
  return user in course.admins.all() or user in course.instructors.all() or user in course.graders.all() \
    or user in course.students.all() or user in course.guests.all()

def accessible_if_student(self, request, view, action):
  user = request.user
  quiz = view.get_object()
  course = quiz.course

  if user in course.students.all():
    return True
  return quiz.published and user in quiz.students.all()

So clearly I'm missing the pk but I'm not exactly sure how I'm supposed to provide that. Any ideas?

helderlgoliveira commented 3 years ago

Hey buddy, have you already solved?

If not, you can create specific statements on access policy class with conditions to each action, or make a if-else statement where get_object is called according to the action, or refactor your code to remove quiz where isn't being used, among other similar solutions.