1
|
|
|
""" |
2
|
|
|
Decorator module for permission |
3
|
|
|
""" |
4
|
|
|
import inspect |
5
|
|
|
from django.db.models import Model |
6
|
|
|
|
7
|
|
|
|
8
|
|
|
__all__ = ['permission_required'] |
9
|
|
|
|
10
|
|
|
|
11
|
|
|
def permission_required(perm, queryset_or_model=None, |
12
|
|
|
login_url=None, raise_exception=False): |
13
|
|
|
""" |
14
|
|
|
Permission check decorator for classbased/functional generic view |
15
|
|
|
|
16
|
|
|
This decorator works as class, method or function decorator without any |
17
|
|
|
modification. |
18
|
|
|
DO NOT use ``method_decorator`` or whatever while this decorator will use |
19
|
|
|
``self`` argument for method of classbased generic view. |
20
|
|
|
|
21
|
|
|
Parameters |
22
|
|
|
---------- |
23
|
|
|
perm : string |
24
|
|
|
A permission string |
25
|
|
|
queryset_or_model : queryset or model |
26
|
|
|
A queryset or model for finding object. |
27
|
|
|
With classbased generic view, ``None`` for using view default queryset. |
28
|
|
|
When the view does not define ``get_queryset``, ``queryset``, |
29
|
|
|
``get_object``, or ``object`` then ``obj=None`` is used to check |
30
|
|
|
permission. |
31
|
|
|
With functional generic view, ``None`` for using passed queryset. |
32
|
|
|
When non queryset was passed then ``obj=None`` is used to check |
33
|
|
|
permission. |
34
|
|
|
|
35
|
|
|
Examples |
36
|
|
|
-------- |
37
|
|
|
>>> # As class decorator |
38
|
|
|
>>> @permission_required('auth.change_user') |
39
|
|
|
>>> class UpdateAuthUserView(UpdateView): |
40
|
|
|
... pass |
41
|
|
|
>>> # As method decorator |
42
|
|
|
>>> class UpdateAuthUserView(UpdateView): |
43
|
|
|
... @permission_required('auth.change_user') |
44
|
|
|
... def dispatch(self, request, *args, **kwargs): |
45
|
|
|
... pass |
46
|
|
|
>>> # As function decorator |
47
|
|
|
>>> @permission_required('auth.change_user') |
48
|
|
|
>>> def update_auth_user(request, *args, **kwargs): |
49
|
|
|
... pass |
50
|
|
|
|
51
|
|
|
.. Note:: |
52
|
|
|
Classbased generic view is recommended while you can regulate the queryset |
53
|
|
|
with ``get_queryset()`` method. |
54
|
|
|
Detecting object from passed kwargs may not work correctly. |
55
|
|
|
""" |
56
|
|
|
# convert model to queryset |
57
|
|
|
if queryset_or_model and issubclass(queryset_or_model, Model): |
58
|
|
|
queryset_or_model = queryset_or_model._default_manager.all() |
59
|
|
|
|
60
|
|
|
def wrapper(class_or_method): |
61
|
|
|
if inspect.isclass(class_or_method): |
62
|
|
|
from permission.decorators.classbase import \ |
63
|
|
|
permission_required as decorator |
64
|
|
|
else: |
65
|
|
|
# method_permission_required can handle method or function |
66
|
|
|
# correctly. |
67
|
|
|
from permission.decorators.methodbase import \ |
68
|
|
|
permission_required as decorator |
69
|
|
|
return decorator(perm, queryset_or_model, |
70
|
|
|
login_url, raise_exception)(class_or_method) |
71
|
|
|
return wrapper |
72
|
|
|
|