1 | #### Example use case: object permission check wrapper for view classes
|
---|
2 |
|
---|
3 | # This can be wrapped at a class level to provide a simple @permissions(perms_list)
|
---|
4 | # decorator for class views that can be used to check request user for
|
---|
5 | # permissions on the objects returned by the view
|
---|
6 |
|
---|
7 | def func_permissions(*perms):
|
---|
8 | """ Class function decorator to check user for object permissions
|
---|
9 | User must have all the permissions listed to get access.
|
---|
10 | """
|
---|
11 | def decorator(view_func):
|
---|
12 | @wraps(view_func, assigned=available_attrs(view_func))
|
---|
13 | def _inner(request=None, *args, **kwargs):
|
---|
14 | """ when decorating a class view_func is get_context_data
|
---|
15 | NB: requires dispatch decorator to set request.user in kwargs
|
---|
16 | """
|
---|
17 | obj_list = kwargs.get('object_list', [])
|
---|
18 | context = view_func(**kwargs)
|
---|
19 | if not obj_list:
|
---|
20 | obj = context.get('subobject',
|
---|
21 | context.get('object', None))
|
---|
22 | if obj:
|
---|
23 | obj_list = [obj, ]
|
---|
24 | user = kwargs.get('user', context.get('user', None))
|
---|
25 | if not user:
|
---|
26 | raise Denied("""No user has been passed in kwargs or context
|
---|
27 | to test %s permissions""" % str(perms))
|
---|
28 | if not obj_list:
|
---|
29 | raise Denied("""There is no object supplied in the request
|
---|
30 | to test %s permissions""" % str(perms))
|
---|
31 | for codename in perms:
|
---|
32 | for obj in obj_list:
|
---|
33 | if not has_permission(obj, user, codename):
|
---|
34 | raise Denied("""User '%s' doesn't have permission
|
---|
35 | '%s' for object '%s' (%s)"""
|
---|
36 | % (user, codename, obj, obj.__class__.__name__))
|
---|
37 | return view_func(*args, **kwargs)
|
---|
38 | return _inner
|
---|
39 | return decorator
|
---|
40 |
|
---|
41 | ############## Monkey patch view classes to pass kwargs for decorators #####
|
---|
42 |
|
---|
43 | def processformview_get(self, request, *args, **kwargs):
|
---|
44 | form_class = self.get_form_class()
|
---|
45 | form = self.get_form(form_class)
|
---|
46 | kwargs['form'] = form
|
---|
47 | context = self.get_context_data(**kwargs)
|
---|
48 | return self.render_to_response(context)
|
---|
49 |
|
---|
50 | def baselistview_get(self, request, *args, **kwargs):
|
---|
51 | self.object_list = self.get_queryset()
|
---|
52 | allow_empty = self.get_allow_empty()
|
---|
53 | if not allow_empty and len(self.object_list) == 0:
|
---|
54 | raise Http404(_(u"Empty list and '%(class_name)s.allow_empty' is False.")
|
---|
55 | % {'class_name': self.__class__.__name__})
|
---|
56 | kwargs['object_list'] = self.object_list
|
---|
57 | context = self.get_context_data(**kwargs)
|
---|
58 | return self.render_to_response(context)
|
---|
59 |
|
---|
60 | def basedetailview_get(self, request, *args, **kwargs):
|
---|
61 | self.object = self.get_object()
|
---|
62 | kwargs['object'] = self.object
|
---|
63 | context = self.get_context_data(**kwargs)
|
---|
64 | return self.render_to_response(context)
|
---|
65 |
|
---|
66 | def basedatelistview_get(self, request, *args, **kwargs):
|
---|
67 | self.date_list, self.object_list, extra_context = self.get_dated_items()
|
---|
68 | kwargs['object_list'] = self.object_list
|
---|
69 | kwargs['date_list'] = self.date_list
|
---|
70 | context = self.get_context_data(**kwargs)
|
---|
71 | context.update(extra_context)
|
---|
72 | return self.render_to_response(context)
|
---|
73 |
|
---|
74 | from django.views.generic.edit import ProcessFormView
|
---|
75 | ProcessFormView.get = processformview_get
|
---|
76 | from django.views.generic.list import BaseListView
|
---|
77 | BaseListView.get = baselistview_get
|
---|
78 | from django.views.generic.detail import BaseDetailView
|
---|
79 | BaseDetailView.get = basedetailview_get
|
---|
80 | from django.views.generic.dates import BaseDateListView
|
---|
81 | BaseDateListView.get = basedatelistview_get
|
---|
82 |
|
---|
83 |
|
---|