61 Three basic permissions -- add, change and delete -- are automatically created for each Django model. |
64 Three basic permissions -- add, change and delete -- are automatically created for each Django model. |
62 """ |
65 """ |
63 name = models.CharField(_('name'), max_length=50) |
66 name = models.CharField(_('name'), max_length=50) |
64 content_type = models.ForeignKey(ContentType) |
67 content_type = models.ForeignKey(ContentType) |
65 codename = models.CharField(_('codename'), max_length=100) |
68 codename = models.CharField(_('codename'), max_length=100) |
|
69 objects = PermissionManager() |
66 |
70 |
67 class Meta: |
71 class Meta: |
68 verbose_name = _('permission') |
72 verbose_name = _('permission') |
69 verbose_name_plural = _('permissions') |
73 verbose_name_plural = _('permissions') |
70 unique_together = (('content_type', 'codename'),) |
74 unique_together = (('content_type', 'codename'),) |
71 ordering = ('content_type__app_label', 'codename') |
75 ordering = ('content_type__app_label', 'content_type__model', 'codename') |
72 |
76 |
73 def __unicode__(self): |
77 def __unicode__(self): |
74 return u"%s | %s | %s" % ( |
78 return u"%s | %s | %s" % ( |
75 unicode(self.content_type.app_label), |
79 unicode(self.content_type.app_label), |
76 unicode(self.content_type), |
80 unicode(self.content_type), |
77 unicode(self.name)) |
81 unicode(self.name)) |
78 |
82 |
|
83 def natural_key(self): |
|
84 return (self.codename,) + self.content_type.natural_key() |
|
85 natural_key.dependencies = ['contenttypes.contenttype'] |
|
86 |
79 class Group(models.Model): |
87 class Group(models.Model): |
80 """Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups. |
88 """Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups. |
81 |
89 |
82 A user in a group automatically has all the permissions granted to that group. For example, if the group Site editors has the permission can_edit_home_page, any user in that group will have that permission. |
90 A user in a group automatically has all the permissions granted to that group. For example, if the group Site editors has the permission can_edit_home_page, any user in that group will have that permission. |
83 |
91 |
93 def __unicode__(self): |
101 def __unicode__(self): |
94 return self.name |
102 return self.name |
95 |
103 |
96 class UserManager(models.Manager): |
104 class UserManager(models.Manager): |
97 def create_user(self, username, email, password=None): |
105 def create_user(self, username, email, password=None): |
98 "Creates and saves a User with the given username, e-mail and password." |
106 """ |
|
107 Creates and saves a User with the given username, e-mail and password. |
|
108 """ |
|
109 |
99 now = datetime.datetime.now() |
110 now = datetime.datetime.now() |
100 user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now) |
111 |
|
112 # Normalize the address by lowercasing the domain part of the email |
|
113 # address. |
|
114 try: |
|
115 email_name, domain_part = email.strip().split('@', 1) |
|
116 except ValueError: |
|
117 pass |
|
118 else: |
|
119 email = '@'.join([email_name, domain_part.lower()]) |
|
120 |
|
121 user = self.model(username=username, email=email, is_staff=False, |
|
122 is_active=True, is_superuser=False, last_login=now, |
|
123 date_joined=now) |
|
124 |
101 if password: |
125 if password: |
102 user.set_password(password) |
126 user.set_password(password) |
103 else: |
127 else: |
104 user.set_unusable_password() |
128 user.set_unusable_password() |
105 user.save() |
129 user.save(using=self._db) |
106 return user |
130 return user |
107 |
131 |
108 def create_superuser(self, username, email, password): |
132 def create_superuser(self, username, email, password): |
109 u = self.create_user(username, email, password) |
133 u = self.create_user(username, email, password) |
110 u.is_staff = True |
134 u.is_staff = True |
111 u.is_active = True |
135 u.is_active = True |
112 u.is_superuser = True |
136 u.is_superuser = True |
113 u.save() |
137 u.save(using=self._db) |
114 return u |
138 return u |
115 |
139 |
116 def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'): |
140 def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'): |
117 "Generates a random password with the given length and given allowed_chars" |
141 "Generates a random password with the given length and given allowed_chars" |
118 # Note that default value of allowed_chars does not have "I" or letters |
142 # Note that default value of allowed_chars does not have "I" or letters |
119 # that look like it -- just to avoid confusion. |
143 # that look like it -- just to avoid confusion. |
120 from random import choice |
144 from random import choice |
121 return ''.join([choice(allowed_chars) for i in range(length)]) |
145 return ''.join([choice(allowed_chars) for i in range(length)]) |
122 |
146 |
|
147 |
|
148 # A few helper functions for common logic between User and AnonymousUser. |
|
149 def _user_get_all_permissions(user, obj): |
|
150 permissions = set() |
|
151 anon = user.is_anonymous() |
|
152 for backend in auth.get_backends(): |
|
153 if not anon or backend.supports_anonymous_user: |
|
154 if hasattr(backend, "get_all_permissions"): |
|
155 if obj is not None: |
|
156 if backend.supports_object_permissions: |
|
157 permissions.update( |
|
158 backend.get_all_permissions(user, obj) |
|
159 ) |
|
160 else: |
|
161 permissions.update(backend.get_all_permissions(user)) |
|
162 return permissions |
|
163 |
|
164 |
|
165 def _user_has_perm(user, perm, obj): |
|
166 anon = user.is_anonymous() |
|
167 for backend in auth.get_backends(): |
|
168 if not anon or backend.supports_anonymous_user: |
|
169 if hasattr(backend, "has_perm"): |
|
170 if obj is not None: |
|
171 if (backend.supports_object_permissions and |
|
172 backend.has_perm(user, perm, obj)): |
|
173 return True |
|
174 else: |
|
175 if backend.has_perm(user, perm): |
|
176 return True |
|
177 return False |
|
178 |
|
179 |
|
180 def _user_has_module_perms(user, app_label): |
|
181 anon = user.is_anonymous() |
|
182 for backend in auth.get_backends(): |
|
183 if not anon or backend.supports_anonymous_user: |
|
184 if hasattr(backend, "has_module_perms"): |
|
185 if backend.has_module_perms(user, app_label): |
|
186 return True |
|
187 return False |
|
188 |
|
189 |
123 class User(models.Model): |
190 class User(models.Model): |
124 """Users within the Django authentication system are represented by this model. |
191 """ |
|
192 Users within the Django authentication system are represented by this model. |
125 |
193 |
126 Username and password are required. Other fields are optional. |
194 Username and password are required. Other fields are optional. |
127 """ |
195 """ |
128 username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores).")) |
196 username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters")) |
129 first_name = models.CharField(_('first name'), max_length=30, blank=True) |
197 first_name = models.CharField(_('first name'), max_length=30, blank=True) |
130 last_name = models.CharField(_('last name'), max_length=30, blank=True) |
198 last_name = models.CharField(_('last name'), max_length=30, blank=True) |
131 email = models.EmailField(_('e-mail address'), blank=True) |
199 email = models.EmailField(_('e-mail address'), blank=True) |
132 password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>.")) |
200 password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>.")) |
133 is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site.")) |
201 is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site.")) |
192 self.password = UNUSABLE_PASSWORD |
265 self.password = UNUSABLE_PASSWORD |
193 |
266 |
194 def has_usable_password(self): |
267 def has_usable_password(self): |
195 return self.password != UNUSABLE_PASSWORD |
268 return self.password != UNUSABLE_PASSWORD |
196 |
269 |
197 def get_group_permissions(self): |
270 def get_group_permissions(self, obj=None): |
198 """ |
271 """ |
199 Returns a list of permission strings that this user has through |
272 Returns a list of permission strings that this user has through |
200 his/her groups. This method queries all available auth backends. |
273 his/her groups. This method queries all available auth backends. |
|
274 If an object is passed in, only permissions matching this object |
|
275 are returned. |
201 """ |
276 """ |
202 permissions = set() |
277 permissions = set() |
203 for backend in auth.get_backends(): |
278 for backend in auth.get_backends(): |
204 if hasattr(backend, "get_group_permissions"): |
279 if hasattr(backend, "get_group_permissions"): |
205 permissions.update(backend.get_group_permissions(self)) |
280 if obj is not None: |
|
281 if backend.supports_object_permissions: |
|
282 permissions.update( |
|
283 backend.get_group_permissions(self, obj) |
|
284 ) |
|
285 else: |
|
286 permissions.update(backend.get_group_permissions(self)) |
206 return permissions |
287 return permissions |
207 |
288 |
208 def get_all_permissions(self): |
289 def get_all_permissions(self, obj=None): |
209 permissions = set() |
290 return _user_get_all_permissions(self, obj) |
210 for backend in auth.get_backends(): |
291 |
211 if hasattr(backend, "get_all_permissions"): |
292 def has_perm(self, perm, obj=None): |
212 permissions.update(backend.get_all_permissions(self)) |
|
213 return permissions |
|
214 |
|
215 def has_perm(self, perm): |
|
216 """ |
293 """ |
217 Returns True if the user has the specified permission. This method |
294 Returns True if the user has the specified permission. This method |
218 queries all available auth backends, but returns immediately if any |
295 queries all available auth backends, but returns immediately if any |
219 backend returns True. Thus, a user who has permission from a single |
296 backend returns True. Thus, a user who has permission from a single |
220 auth backend is assumed to have permission in general. |
297 auth backend is assumed to have permission in general. If an object |
|
298 is provided, permissions for this specific object are checked. |
221 """ |
299 """ |
222 # Inactive users have no permissions. |
300 # Inactive users have no permissions. |
223 if not self.is_active: |
301 if not self.is_active: |
224 return False |
302 return False |
225 |
303 |
226 # Superusers have all permissions. |
304 # Superusers have all permissions. |
227 if self.is_superuser: |
305 if self.is_superuser: |
228 return True |
306 return True |
229 |
307 |
230 # Otherwise we need to check the backends. |
308 # Otherwise we need to check the backends. |
231 for backend in auth.get_backends(): |
309 return _user_has_perm(self, perm, obj) |
232 if hasattr(backend, "has_perm"): |
310 |
233 if backend.has_perm(self, perm): |
311 def has_perms(self, perm_list, obj=None): |
234 return True |
312 """ |
235 return False |
313 Returns True if the user has each of the specified permissions. |
236 |
314 If object is passed, it checks if the user has all required perms |
237 def has_perms(self, perm_list): |
315 for this object. |
238 """Returns True if the user has each of the specified permissions.""" |
316 """ |
239 for perm in perm_list: |
317 for perm in perm_list: |
240 if not self.has_perm(perm): |
318 if not self.has_perm(perm, obj): |
241 return False |
319 return False |
242 return True |
320 return True |
243 |
321 |
244 def has_module_perms(self, app_label): |
322 def has_module_perms(self, app_label): |
245 """ |
323 """ |
276 SiteProfileNotAvailable if this site does not allow profiles. |
350 SiteProfileNotAvailable if this site does not allow profiles. |
277 """ |
351 """ |
278 if not hasattr(self, '_profile_cache'): |
352 if not hasattr(self, '_profile_cache'): |
279 from django.conf import settings |
353 from django.conf import settings |
280 if not getattr(settings, 'AUTH_PROFILE_MODULE', False): |
354 if not getattr(settings, 'AUTH_PROFILE_MODULE', False): |
281 raise SiteProfileNotAvailable |
355 raise SiteProfileNotAvailable('You need to set AUTH_PROFILE_MO' |
|
356 'DULE in your project settings') |
282 try: |
357 try: |
283 app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.') |
358 app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.') |
|
359 except ValueError: |
|
360 raise SiteProfileNotAvailable('app_label and model_name should' |
|
361 ' be separated by a dot in the AUTH_PROFILE_MODULE set' |
|
362 'ting') |
|
363 |
|
364 try: |
284 model = models.get_model(app_label, model_name) |
365 model = models.get_model(app_label, model_name) |
285 self._profile_cache = model._default_manager.get(user__id__exact=self.id) |
366 if model is None: |
|
367 raise SiteProfileNotAvailable('Unable to load the profile ' |
|
368 'model, check AUTH_PROFILE_MODULE in your project sett' |
|
369 'ings') |
|
370 self._profile_cache = model._default_manager.using(self._state.db).get(user__id__exact=self.id) |
286 self._profile_cache.user = self |
371 self._profile_cache.user = self |
287 except (ImportError, ImproperlyConfigured): |
372 except (ImportError, ImproperlyConfigured): |
288 raise SiteProfileNotAvailable |
373 raise SiteProfileNotAvailable |
289 return self._profile_cache |
374 return self._profile_cache |
|
375 |
|
376 def _get_message_set(self): |
|
377 import warnings |
|
378 warnings.warn('The user messaging API is deprecated. Please update' |
|
379 ' your code to use the new messages framework.', |
|
380 category=PendingDeprecationWarning) |
|
381 return self._message_set |
|
382 message_set = property(_get_message_set) |
290 |
383 |
291 class Message(models.Model): |
384 class Message(models.Model): |
292 """ |
385 """ |
293 The message system is a lightweight way to queue messages for given |
386 The message system is a lightweight way to queue messages for given |
294 users. A message is associated with a User instance (so it is only |
387 users. A message is associated with a User instance (so it is only |
295 applicable for registered users). There's no concept of expiration or |
388 applicable for registered users). There's no concept of expiration or |
296 timestamps. Messages are created by the Django admin after successful |
389 timestamps. Messages are created by the Django admin after successful |
297 actions. For example, "The poll Foo was created successfully." is a |
390 actions. For example, "The poll Foo was created successfully." is a |
298 message. |
391 message. |
299 """ |
392 """ |
300 user = models.ForeignKey(User) |
393 user = models.ForeignKey(User, related_name='_message_set') |
301 message = models.TextField(_('message')) |
394 message = models.TextField(_('message')) |
302 |
395 |
303 def __unicode__(self): |
396 def __unicode__(self): |
304 return self.message |
397 return self.message |
305 |
398 |
348 |
441 |
349 def _get_user_permissions(self): |
442 def _get_user_permissions(self): |
350 return self._user_permissions |
443 return self._user_permissions |
351 user_permissions = property(_get_user_permissions) |
444 user_permissions = property(_get_user_permissions) |
352 |
445 |
353 def has_perm(self, perm): |
446 def get_group_permissions(self, obj=None): |
354 return False |
447 return set() |
355 |
448 |
356 def has_perms(self, perm_list): |
449 def get_all_permissions(self, obj=None): |
357 return False |
450 return _user_get_all_permissions(self, obj=obj) |
|
451 |
|
452 def has_perm(self, perm, obj=None): |
|
453 return _user_has_perm(self, perm, obj=obj) |
|
454 |
|
455 def has_perms(self, perm_list, obj=None): |
|
456 for perm in perm_list: |
|
457 if not self.has_perm(perm, obj): |
|
458 return False |
|
459 return True |
358 |
460 |
359 def has_module_perms(self, module): |
461 def has_module_perms(self, module): |
360 return False |
462 return _user_has_module_perms(self, module) |
361 |
463 |
362 def get_and_delete_messages(self): |
464 def get_and_delete_messages(self): |
363 return [] |
465 return [] |
364 |
466 |
365 def is_anonymous(self): |
467 def is_anonymous(self): |