1 | Index: django/contrib/auth/backends.py
|
---|
2 | ===================================================================
|
---|
3 | --- django/contrib/auth/backends.py (revision 6184)
|
---|
4 | +++ django/contrib/auth/backends.py (working copy)
|
---|
5 | @@ -1,3 +1,4 @@
|
---|
6 | +from django.db import connection, models
|
---|
7 | from django.contrib.auth.models import User
|
---|
8 |
|
---|
9 | class ModelBackend:
|
---|
10 | @@ -14,6 +15,51 @@
|
---|
11 | except User.DoesNotExist:
|
---|
12 | return None
|
---|
13 |
|
---|
14 | + def get_group_permissions(self, user_obj):
|
---|
15 | + "Returns a list of permission strings that this user has through his/her groups."
|
---|
16 | + if not hasattr(user_obj, '_group_perm_cache'):
|
---|
17 | + cursor = connection.cursor()
|
---|
18 | + # The SQL below works out to the following, after DB quoting:
|
---|
19 | + # cursor.execute("""
|
---|
20 | + # SELECT ct."app_label", p."codename"
|
---|
21 | + # FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct
|
---|
22 | + # WHERE p."id" = gp."permission_id"
|
---|
23 | + # AND gp."group_id" = ug."group_id"
|
---|
24 | + # AND ct."id" = p."content_type_id"
|
---|
25 | + # AND ug."user_id" = %s, [self.id])
|
---|
26 | + qn = connection.ops.quote_name
|
---|
27 | + sql = """
|
---|
28 | + SELECT ct.%s, p.%s
|
---|
29 | + FROM %s p, %s gp, %s ug, %s ct
|
---|
30 | + WHERE p.%s = gp.%s
|
---|
31 | + AND gp.%s = ug.%s
|
---|
32 | + AND ct.%s = p.%s
|
---|
33 | + AND ug.%s = %%s""" % (
|
---|
34 | + qn('app_label'), qn('codename'),
|
---|
35 | + qn('auth_permission'), qn('auth_group_permissions'),
|
---|
36 | + qn('auth_user_groups'), qn('django_content_type'),
|
---|
37 | + qn('id'), qn('permission_id'),
|
---|
38 | + qn('group_id'), qn('group_id'),
|
---|
39 | + qn('id'), qn('content_type_id'),
|
---|
40 | + qn('user_id'),)
|
---|
41 | + cursor.execute(sql, [user_obj.id])
|
---|
42 | + user_obj._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
|
---|
43 | + return user_obj._group_perm_cache
|
---|
44 | +
|
---|
45 | + def get_all_permissions(self, user_obj):
|
---|
46 | + if not hasattr(user_obj, '_perm_cache'):
|
---|
47 | + user_obj._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related()])
|
---|
48 | + user_obj._perm_cache.update(self.get_group_permissions(user_obj))
|
---|
49 | + return user_obj._perm_cache
|
---|
50 | +
|
---|
51 | + def has_perm(self, user_obj, perm):
|
---|
52 | + return perm in self.get_all_permissions(user_obj)
|
---|
53 | +
|
---|
54 | + def has_module_perms(self, user_obj, app_label):
|
---|
55 | + return bool(len([p for p in self.get_all_permissions(user_obj) if p[:p.index('.')] == app_label]))
|
---|
56 | +
|
---|
57 | +
|
---|
58 | +
|
---|
59 | def get_user(self, user_id):
|
---|
60 | try:
|
---|
61 | return User.objects.get(pk=user_id)
|
---|
62 | Index: django/contrib/auth/models.py
|
---|
63 | ===================================================================
|
---|
64 | --- django/contrib/auth/models.py (revision 6184)
|
---|
65 | +++ django/contrib/auth/models.py (working copy)
|
---|
66 | @@ -1,3 +1,4 @@
|
---|
67 | +from django.contrib.auth import get_backends
|
---|
68 | from django.core import validators
|
---|
69 | from django.core.exceptions import ImproperlyConfigured
|
---|
70 | from django.db import connection, models
|
---|
71 | @@ -177,49 +178,41 @@
|
---|
72 | return self.password != UNUSABLE_PASSWORD
|
---|
73 |
|
---|
74 | def get_group_permissions(self):
|
---|
75 | - "Returns a list of permission strings that this user has through his/her groups."
|
---|
76 | - if not hasattr(self, '_group_perm_cache'):
|
---|
77 | - cursor = connection.cursor()
|
---|
78 | - # The SQL below works out to the following, after DB quoting:
|
---|
79 | - # cursor.execute("""
|
---|
80 | - # SELECT ct."app_label", p."codename"
|
---|
81 | - # FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct
|
---|
82 | - # WHERE p."id" = gp."permission_id"
|
---|
83 | - # AND gp."group_id" = ug."group_id"
|
---|
84 | - # AND ct."id" = p."content_type_id"
|
---|
85 | - # AND ug."user_id" = %s, [self.id])
|
---|
86 | - qn = connection.ops.quote_name
|
---|
87 | - sql = """
|
---|
88 | - SELECT ct.%s, p.%s
|
---|
89 | - FROM %s p, %s gp, %s ug, %s ct
|
---|
90 | - WHERE p.%s = gp.%s
|
---|
91 | - AND gp.%s = ug.%s
|
---|
92 | - AND ct.%s = p.%s
|
---|
93 | - AND ug.%s = %%s""" % (
|
---|
94 | - qn('app_label'), qn('codename'),
|
---|
95 | - qn('auth_permission'), qn('auth_group_permissions'),
|
---|
96 | - qn('auth_user_groups'), qn('django_content_type'),
|
---|
97 | - qn('id'), qn('permission_id'),
|
---|
98 | - qn('group_id'), qn('group_id'),
|
---|
99 | - qn('id'), qn('content_type_id'),
|
---|
100 | - qn('user_id'),)
|
---|
101 | - cursor.execute(sql, [self.id])
|
---|
102 | - self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
|
---|
103 | - return self._group_perm_cache
|
---|
104 | + """
|
---|
105 | + Returns a list of permission strings that this user has through his/her groups.
|
---|
106 | + This method queries the available backends.
|
---|
107 | + """
|
---|
108 | + group_permissions = set([])
|
---|
109 | + for backend in get_backends():
|
---|
110 | + # Backend does not support this method, so skip it
|
---|
111 | + if not hasattr(backend, "get_group_permissions"): continue
|
---|
112 | + group_permissions.update(backend.get_group_permissions(self))
|
---|
113 | + return group_permissions
|
---|
114 |
|
---|
115 | def get_all_permissions(self):
|
---|
116 | - if not hasattr(self, '_perm_cache'):
|
---|
117 | - self._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.select_related()])
|
---|
118 | - self._perm_cache.update(self.get_group_permissions())
|
---|
119 | - return self._perm_cache
|
---|
120 | + permissions = set([])
|
---|
121 | + for backend in get_backends():
|
---|
122 | + # Backend does not support this method, so skip it
|
---|
123 | + if not hasattr(backend, "get_all_permissions"): continue
|
---|
124 | + permissions.update(backend.get_all_permissions(self))
|
---|
125 | + return permissions
|
---|
126 |
|
---|
127 | def has_perm(self, perm):
|
---|
128 | - "Returns True if the user has the specified permission."
|
---|
129 | + """
|
---|
130 | + Returns True if the user has the specified permission.
|
---|
131 | + This method queries the available backends and stops on
|
---|
132 | + the first "True".
|
---|
133 | + """
|
---|
134 | if not self.is_active:
|
---|
135 | return False
|
---|
136 | if self.is_superuser:
|
---|
137 | return True
|
---|
138 | - return perm in self.get_all_permissions()
|
---|
139 | + for backend in get_backends():
|
---|
140 | + # Backend does not support this method, so skip it
|
---|
141 | + if not hasattr(backend, "has_perm"): continue
|
---|
142 | + if backend.has_perm(self, perm):
|
---|
143 | + return True
|
---|
144 | + return False
|
---|
145 |
|
---|
146 | def has_perms(self, perm_list):
|
---|
147 | "Returns True if the user has each of the specified permissions."
|
---|
148 | @@ -229,12 +222,21 @@
|
---|
149 | return True
|
---|
150 |
|
---|
151 | def has_module_perms(self, app_label):
|
---|
152 | - "Returns True if the user has any permissions in the given app label."
|
---|
153 | + """
|
---|
154 | + Returns True if the user has any permissions in the given app label.
|
---|
155 | + This method queries the available backends and stops on
|
---|
156 | + the first "True".
|
---|
157 | + """
|
---|
158 | if not self.is_active:
|
---|
159 | return False
|
---|
160 | if self.is_superuser:
|
---|
161 | return True
|
---|
162 | - return bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == app_label]))
|
---|
163 | + for backend in get_backends():
|
---|
164 | + # Backend does not support this method, so skip it
|
---|
165 | + if not hasattr(backend, "has_module_perms"): continue
|
---|
166 | + if backend.has_module_perms(self, app_label):
|
---|
167 | + return True
|
---|
168 | + return False
|
---|
169 |
|
---|
170 | def get_and_delete_messages(self):
|
---|
171 | messages = []
|
---|
172 | Index: docs/authentication.txt
|
---|
173 | ===================================================================
|
---|
174 | --- docs/authentication.txt (revision 6184)
|
---|
175 | +++ docs/authentication.txt (working copy)
|
---|
176 | @@ -1041,3 +1041,26 @@
|
---|
177 | return User.objects.get(pk=user_id)
|
---|
178 | except User.DoesNotExist:
|
---|
179 | return None
|
---|
180 | +
|
---|
181 | +Optionally the Backend allows you to specify any of the permission methods of
|
---|
182 | +the ``User`` object (except from ``has_perms`` which calls ``has_perm`` for each
|
---|
183 | +perm in the list, and ``has_perm`` can be specified in the backend).
|
---|
184 | +This will allow your backend to handle the permissions, if one backend return
|
---|
185 | +``True`` in a permission check, the user will have the permission.
|
---|
186 | +
|
---|
187 | +Here is an sample implementation for ``has_perm`` extending the above exmaple::
|
---|
188 | +
|
---|
189 | + # The permission functions all take the user_obj as first (besides the self of
|
---|
190 | + # the backend, of course) argument and the rest
|
---|
191 | + # is as you would call it with ``User.*``
|
---|
192 | + def has_perm(self, user_obj, perm):
|
---|
193 | + # we give the user admin the right to do everything.
|
---|
194 | + if user_obj.username == "admin":
|
---|
195 | + return True
|
---|
196 | + else:
|
---|
197 | + return False
|
---|
198 | +
|
---|
199 | +A full implementation can be found in ``django/contrib/auth/backends.py`` _, which is the
|
---|
200 | +default backend and queries the ``auth_permission``-table most of the time.
|
---|
201 | +
|
---|
202 | +.. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py
|
---|