1
|
|
|
# coding=utf-8 |
2
|
|
|
""" |
3
|
|
|
A utilities of permission handler |
4
|
|
|
""" |
5
|
|
|
from __future__ import unicode_literals |
6
|
|
|
import inspect |
7
|
|
|
from django.core.exceptions import ImproperlyConfigured |
8
|
|
|
from permission.conf import settings |
9
|
|
|
from permission.compat import isstr |
10
|
|
|
from permission.compat import import_string |
11
|
|
|
|
12
|
|
|
|
13
|
|
|
class PermissionHandlerRegistry(object): |
14
|
|
|
""" |
15
|
|
|
A registry class of permission handler |
16
|
|
|
""" |
17
|
|
|
def __init__(self): |
18
|
|
|
self._registry = {} |
19
|
|
|
|
20
|
|
|
def register(self, model, handler=None): |
21
|
|
|
""" |
22
|
|
|
Register a permission handler to the model |
23
|
|
|
|
24
|
|
|
Parameters |
25
|
|
|
---------- |
26
|
|
|
model : django model class |
27
|
|
|
A django model class |
28
|
|
|
handler : permission handler class, string, or None |
29
|
|
|
A permission handler class or a dotted path |
30
|
|
|
|
31
|
|
|
Raises |
32
|
|
|
------ |
33
|
|
|
ImproperlyConfigured |
34
|
|
|
Raise when the model is abstract model |
35
|
|
|
KeyError |
36
|
|
|
Raise when the model is already registered in registry |
37
|
|
|
The model cannot have more than one handler. |
38
|
|
|
""" |
39
|
|
|
from permission.handlers import PermissionHandler |
40
|
|
|
if model._meta.abstract: |
41
|
|
|
raise ImproperlyConfigured( |
42
|
|
|
'The model %s is abstract, so it cannot be registered ' |
43
|
|
|
'with permission.' % model) |
44
|
|
|
if model in self._registry: |
45
|
|
|
raise KeyError("A permission handler class is already " |
46
|
|
|
"registered for '%s'" % model) |
47
|
|
|
if handler is None: |
48
|
|
|
handler = settings.PERMISSION_DEFAULT_PERMISSION_HANDLER |
49
|
|
|
if isstr(handler): |
50
|
|
|
handler = import_string(handler) |
51
|
|
|
if not inspect.isclass(handler): |
52
|
|
|
raise AttributeError( |
53
|
|
|
"`handler` attribute must be a class. " |
54
|
|
|
"An instance was specified.") |
55
|
|
|
if not issubclass(handler, PermissionHandler): |
56
|
|
|
raise AttributeError( |
57
|
|
|
"`handler` attribute must be a subclass of " |
58
|
|
|
"`permission.handlers.PermissionHandler`") |
59
|
|
|
|
60
|
|
|
# Instantiate the handler to save in the registry |
61
|
|
|
instance = handler(model) |
62
|
|
|
self._registry[model] = instance |
63
|
|
|
|
64
|
|
|
def unregister(self, model): |
65
|
|
|
""" |
66
|
|
|
Unregister a permission handler from the model |
67
|
|
|
|
68
|
|
|
Parameters |
69
|
|
|
---------- |
70
|
|
|
model : django model class |
71
|
|
|
A django model class |
72
|
|
|
|
73
|
|
|
Raises |
74
|
|
|
------ |
75
|
|
|
KeyError |
76
|
|
|
Raise when the model have not registered in registry yet. |
77
|
|
|
""" |
78
|
|
|
if model not in self._registry: |
79
|
|
|
raise KeyError("A permission handler class have not been " |
80
|
|
|
"registered for '%s' yet" % model) |
81
|
|
|
# remove from registry |
82
|
|
|
del self._registry[model] |
83
|
|
|
|
84
|
|
|
def get_handlers(self): |
85
|
|
|
""" |
86
|
|
|
Get registered handler instances |
87
|
|
|
|
88
|
|
|
Returns |
89
|
|
|
------- |
90
|
|
|
tuple |
91
|
|
|
permission handler tuple |
92
|
|
|
""" |
93
|
|
|
return tuple(self._registry.values()) |
94
|
|
|
|
95
|
|
|
registry = PermissionHandlerRegistry() |
96
|
|
|
"""Permission handler registry instance""" |
97
|
|
|
|