0

I have been trying to find a solution for this for hours. I have already gone through many SO posts like this, this and this. I am using django-guardian to implement object level permissions in my django app. I am trying to implement permission_required decorator dynamically. The idea is to create another decorator which can switch between permission required decorators and then pass view function to respective permission_required decorator.

urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', Test.as_view()),
    url(r'(?P<handle>[-\w]+)/(?P<method>[-\w]+)/(?P<id>[-\w]+)/$', Test.as_view(), name='handler'),
]

Views.py

class Test(View):
    @decorator_switch
    def get(self, request, *args, **kwargs):
        return HttpResponse('Test View')

decorator_switch

from api.mappings.permission_mappings import perm_mappings

def decorator_switch(func):

def wrapper(instance, request, *args, **kwargs):
    print(kwargs)
    permission_decorator = \
        perm_mappings.get('handles').get(kwargs.get('handle')).get('actions').get(kwargs.get('method'))
    return permission_decorator(func)(request)(args)(kwargs)
return wrapper

permission_mappings

from django.contrib.auth.decorators import permission_required as django_perm_req
from api.decorators.guardian_perm_req import permission_required as guardian_perm_req
from pyteam.models import Team

perm_mappings = {
    'handles': {
        'team': {
            'actions':  {
                'get': guardian_perm_req('pyteam.retrieve_team', (Team, 'id', 'id')),
                'create': django_perm_req('pyteams.add_team', raise_exception=True),
                'update': guardian_perm_req('pyteam.change_team', (Team, 'id', 'id')),
                'delete': guardian_perm_req('pyteam.delete_team', (Team, 'id', 'id'))
                }
            }
        }
    }

After this I opened url http://localhost:8000/team/get/1/ But I got an exception

GuardianError at /team/get/1/

Argument id was not passed into view function

I checked in kwargs of views as well as kwargs of decorator of decorator switch for id in kwargs and I found it. Then I checked wrapper function of guardian_perm_req but def _wrapped_view(request, *args, **kwargs): of def decorator(view_func): was not getting url kwargs which caused this issue.

As decorators and basically functions, I tried calling and returning view functions from decorator switch itself.

return permission_decorator(func(instance, request, args, kwargs))

But as expected clickjacking middleware raised an exception on this

AttributeError at /team/get/1/

'function' object has no attribute 'get'

Any help is greatly appreciated.

TIA

Community
  • 1
  • 1
cutteeth
  • 2,148
  • 3
  • 25
  • 45
  • 1
    Dis you tried `return permission_decorator(func)(instance, request, *args, **kwargs)` ? – itzMEonTV Apr 30 '17 at 06:08
  • @L_S my bad, I didn't try that. This fixed my issue. Please post an answer also that I can mark same as correct answer. Thanks a lot :) – cutteeth Apr 30 '17 at 06:24

1 Answers1

1

Try this

return permission_decorator(func)(instance, request, *args, **kwargs)
itzMEonTV
  • 19,851
  • 4
  • 39
  • 49