App Engine Python SDK version 1.7.4 (2)
[gae.git] / python / lib / django_1_4 / django / contrib / auth / models.py
blob4e1584970cf4c8f5bc44eb9907dcb4db339b58d3
1 import urllib
3 from django.core.exceptions import ImproperlyConfigured
4 from django.core.mail import send_mail
5 from django.db import models
6 from django.db.models.manager import EmptyManager
7 from django.utils.crypto import get_random_string
8 from django.utils.encoding import smart_str
9 from django.utils.translation import ugettext_lazy as _
10 from django.utils import timezone
12 from django.contrib import auth
13 # UNUSABLE_PASSWORD is still imported here for backwards compatibility
14 from django.contrib.auth.hashers import (
15 check_password, make_password, is_password_usable, UNUSABLE_PASSWORD)
16 from django.contrib.auth.signals import user_logged_in
17 from django.contrib.contenttypes.models import ContentType
20 def update_last_login(sender, user, **kwargs):
21 """
22 A signal receiver which updates the last_login date for
23 the user logging in.
24 """
25 user.last_login = timezone.now()
26 user.save()
27 user_logged_in.connect(update_last_login)
30 class SiteProfileNotAvailable(Exception):
31 pass
34 class PermissionManager(models.Manager):
35 def get_by_natural_key(self, codename, app_label, model):
36 return self.get(
37 codename=codename,
38 content_type=ContentType.objects.get_by_natural_key(app_label,
39 model),
43 class Permission(models.Model):
44 """
45 The permissions system provides a way to assign permissions to specific
46 users and groups of users.
48 The permission system is used by the Django admin site, but may also be
49 useful in your own code. The Django admin site uses permissions as follows:
51 - The "add" permission limits the user's ability to view the "add" form
52 and add an object.
53 - The "change" permission limits a user's ability to view the change
54 list, view the "change" form and change an object.
55 - The "delete" permission limits the ability to delete an object.
57 Permissions are set globally per type of object, not per specific object
58 instance. It is possible to say "Mary may change news stories," but it's
59 not currently possible to say "Mary may change news stories, but only the
60 ones she created herself" or "Mary may only change news stories that have a
61 certain status or publication date."
63 Three basic permissions -- add, change and delete -- are automatically
64 created for each Django model.
65 """
66 name = models.CharField(_('name'), max_length=50)
67 content_type = models.ForeignKey(ContentType)
68 codename = models.CharField(_('codename'), max_length=100)
69 objects = PermissionManager()
71 class Meta:
72 verbose_name = _('permission')
73 verbose_name_plural = _('permissions')
74 unique_together = (('content_type', 'codename'),)
75 ordering = ('content_type__app_label', 'content_type__model',
76 'codename')
78 def __unicode__(self):
79 return u"%s | %s | %s" % (
80 unicode(self.content_type.app_label),
81 unicode(self.content_type),
82 unicode(self.name))
84 def natural_key(self):
85 return (self.codename,) + self.content_type.natural_key()
86 natural_key.dependencies = ['contenttypes.contenttype']
89 class GroupManager(models.Manager):
90 """
91 The manager for the auth's Group model.
92 """
93 def get_by_natural_key(self, name):
94 return self.get(name=name)
96 class Group(models.Model):
97 """
98 Groups are a generic way of categorizing users to apply permissions, or
99 some other label, to those users. A user can belong to any number of
100 groups.
102 A user in a group automatically has all the permissions granted to that
103 group. For example, if the group Site editors has the permission
104 can_edit_home_page, any user in that group will have that permission.
106 Beyond permissions, groups are a convenient way to categorize users to
107 apply some label, or extended functionality, to them. For example, you
108 could create a group 'Special users', and you could write code that would
109 do special things to those users -- such as giving them access to a
110 members-only portion of your site, or sending them members-only email
111 messages.
113 name = models.CharField(_('name'), max_length=80, unique=True)
114 permissions = models.ManyToManyField(Permission,
115 verbose_name=_('permissions'), blank=True)
117 objects = GroupManager()
119 class Meta:
120 verbose_name = _('group')
121 verbose_name_plural = _('groups')
123 def __unicode__(self):
124 return self.name
126 def natural_key(self):
127 return (self.name,)
130 class UserManager(models.Manager):
132 @classmethod
133 def normalize_email(cls, email):
135 Normalize the address by lowercasing the domain part of the email
136 address.
138 email = email or ''
139 try:
140 email_name, domain_part = email.strip().rsplit('@', 1)
141 except ValueError:
142 pass
143 else:
144 email = '@'.join([email_name, domain_part.lower()])
145 return email
147 def create_user(self, username, email=None, password=None):
149 Creates and saves a User with the given username, email and password.
151 now = timezone.now()
152 if not username:
153 raise ValueError('The given username must be set')
154 email = UserManager.normalize_email(email)
155 user = self.model(username=username, email=email,
156 is_staff=False, is_active=True, is_superuser=False,
157 last_login=now, date_joined=now)
159 user.set_password(password)
160 user.save(using=self._db)
161 return user
163 def create_superuser(self, username, email, password):
164 u = self.create_user(username, email, password)
165 u.is_staff = True
166 u.is_active = True
167 u.is_superuser = True
168 u.save(using=self._db)
169 return u
171 def make_random_password(self, length=10,
172 allowed_chars='abcdefghjkmnpqrstuvwxyz'
173 'ABCDEFGHJKLMNPQRSTUVWXYZ'
174 '23456789'):
176 Generates a random password with the given length and given
177 allowed_chars. Note that the default value of allowed_chars does not
178 have "I" or "O" or letters and digits that look similar -- just to
179 avoid confusion.
181 return get_random_string(length, allowed_chars)
183 def get_by_natural_key(self, username):
184 return self.get(username=username)
187 # A few helper functions for common logic between User and AnonymousUser.
188 def _user_get_all_permissions(user, obj):
189 permissions = set()
190 for backend in auth.get_backends():
191 if hasattr(backend, "get_all_permissions"):
192 if obj is not None:
193 permissions.update(backend.get_all_permissions(user, obj))
194 else:
195 permissions.update(backend.get_all_permissions(user))
196 return permissions
199 def _user_has_perm(user, perm, obj):
200 anon = user.is_anonymous()
201 active = user.is_active
202 for backend in auth.get_backends():
203 if anon or active or backend.supports_inactive_user:
204 if hasattr(backend, "has_perm"):
205 if obj is not None:
206 if backend.has_perm(user, perm, obj):
207 return True
208 else:
209 if backend.has_perm(user, perm):
210 return True
211 return False
214 def _user_has_module_perms(user, app_label):
215 anon = user.is_anonymous()
216 active = user.is_active
217 for backend in auth.get_backends():
218 if anon or active or backend.supports_inactive_user:
219 if hasattr(backend, "has_module_perms"):
220 if backend.has_module_perms(user, app_label):
221 return True
222 return False
225 class User(models.Model):
227 Users within the Django authentication system are represented by this
228 model.
230 Username and password are required. Other fields are optional.
232 username = models.CharField(_('username'), max_length=30, unique=True,
233 help_text=_('Required. 30 characters or fewer. Letters, numbers and '
234 '@/./+/-/_ characters'))
235 first_name = models.CharField(_('first name'), max_length=30, blank=True)
236 last_name = models.CharField(_('last name'), max_length=30, blank=True)
237 email = models.EmailField(_('e-mail address'), blank=True)
238 password = models.CharField(_('password'), max_length=128)
239 is_staff = models.BooleanField(_('staff status'), default=False,
240 help_text=_('Designates whether the user can log into this admin '
241 'site.'))
242 is_active = models.BooleanField(_('active'), default=True,
243 help_text=_('Designates whether this user should be treated as '
244 'active. Unselect this instead of deleting accounts.'))
245 is_superuser = models.BooleanField(_('superuser status'), default=False,
246 help_text=_('Designates that this user has all permissions without '
247 'explicitly assigning them.'))
248 last_login = models.DateTimeField(_('last login'), default=timezone.now)
249 date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
250 groups = models.ManyToManyField(Group, verbose_name=_('groups'),
251 blank=True, help_text=_('The groups this user belongs to. A user will '
252 'get all permissions granted to each of '
253 'his/her group.'))
254 user_permissions = models.ManyToManyField(Permission,
255 verbose_name=_('user permissions'), blank=True,
256 help_text='Specific permissions for this user.')
257 objects = UserManager()
259 class Meta:
260 verbose_name = _('user')
261 verbose_name_plural = _('users')
263 def __unicode__(self):
264 return self.username
266 def natural_key(self):
267 return (self.username,)
269 def get_absolute_url(self):
270 return "/users/%s/" % urllib.quote(smart_str(self.username))
272 def is_anonymous(self):
274 Always returns False. This is a way of comparing User objects to
275 anonymous users.
277 return False
279 def is_authenticated(self):
281 Always return True. This is a way to tell if the user has been
282 authenticated in templates.
284 return True
286 def get_full_name(self):
288 Returns the first_name plus the last_name, with a space in between.
290 full_name = u'%s %s' % (self.first_name, self.last_name)
291 return full_name.strip()
293 def set_password(self, raw_password):
294 self.password = make_password(raw_password)
296 def check_password(self, raw_password):
298 Returns a boolean of whether the raw_password was correct. Handles
299 hashing formats behind the scenes.
301 def setter(raw_password):
302 self.set_password(raw_password)
303 self.save()
304 return check_password(raw_password, self.password, setter)
306 def set_unusable_password(self):
307 # Sets a value that will never be a valid hash
308 self.password = make_password(None)
310 def has_usable_password(self):
311 return is_password_usable(self.password)
313 def get_group_permissions(self, obj=None):
315 Returns a list of permission strings that this user has through his/her
316 groups. This method queries all available auth backends. If an object
317 is passed in, only permissions matching this object are returned.
319 permissions = set()
320 for backend in auth.get_backends():
321 if hasattr(backend, "get_group_permissions"):
322 if obj is not None:
323 permissions.update(backend.get_group_permissions(self,
324 obj))
325 else:
326 permissions.update(backend.get_group_permissions(self))
327 return permissions
329 def get_all_permissions(self, obj=None):
330 return _user_get_all_permissions(self, obj)
332 def has_perm(self, perm, obj=None):
334 Returns True if the user has the specified permission. This method
335 queries all available auth backends, but returns immediately if any
336 backend returns True. Thus, a user who has permission from a single
337 auth backend is assumed to have permission in general. If an object is
338 provided, permissions for this specific object are checked.
341 # Active superusers have all permissions.
342 if self.is_active and self.is_superuser:
343 return True
345 # Otherwise we need to check the backends.
346 return _user_has_perm(self, perm, obj)
348 def has_perms(self, perm_list, obj=None):
350 Returns True if the user has each of the specified permissions. If
351 object is passed, it checks if the user has all required perms for this
352 object.
354 for perm in perm_list:
355 if not self.has_perm(perm, obj):
356 return False
357 return True
359 def has_module_perms(self, app_label):
361 Returns True if the user has any permissions in the given app label.
362 Uses pretty much the same logic as has_perm, above.
364 # Active superusers have all permissions.
365 if self.is_active and self.is_superuser:
366 return True
368 return _user_has_module_perms(self, app_label)
370 def email_user(self, subject, message, from_email=None):
372 Sends an email to this User.
374 send_mail(subject, message, from_email, [self.email])
376 def get_profile(self):
378 Returns site-specific profile for this user. Raises
379 SiteProfileNotAvailable if this site does not allow profiles.
381 if not hasattr(self, '_profile_cache'):
382 from django.conf import settings
383 if not getattr(settings, 'AUTH_PROFILE_MODULE', False):
384 raise SiteProfileNotAvailable(
385 'You need to set AUTH_PROFILE_MODULE in your project '
386 'settings')
387 try:
388 app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
389 except ValueError:
390 raise SiteProfileNotAvailable(
391 'app_label and model_name should be separated by a dot in '
392 'the AUTH_PROFILE_MODULE setting')
393 try:
394 model = models.get_model(app_label, model_name)
395 if model is None:
396 raise SiteProfileNotAvailable(
397 'Unable to load the profile model, check '
398 'AUTH_PROFILE_MODULE in your project settings')
399 self._profile_cache = model._default_manager.using(
400 self._state.db).get(user__id__exact=self.id)
401 self._profile_cache.user = self
402 except (ImportError, ImproperlyConfigured):
403 raise SiteProfileNotAvailable
404 return self._profile_cache
407 class AnonymousUser(object):
408 id = None
409 username = ''
410 is_staff = False
411 is_active = False
412 is_superuser = False
413 _groups = EmptyManager()
414 _user_permissions = EmptyManager()
416 def __init__(self):
417 pass
419 def __unicode__(self):
420 return 'AnonymousUser'
422 def __str__(self):
423 return unicode(self).encode('utf-8')
425 def __eq__(self, other):
426 return isinstance(other, self.__class__)
428 def __ne__(self, other):
429 return not self.__eq__(other)
431 def __hash__(self):
432 return 1 # instances always return the same hash value
434 def save(self):
435 raise NotImplementedError
437 def delete(self):
438 raise NotImplementedError
440 def set_password(self, raw_password):
441 raise NotImplementedError
443 def check_password(self, raw_password):
444 raise NotImplementedError
446 def _get_groups(self):
447 return self._groups
448 groups = property(_get_groups)
450 def _get_user_permissions(self):
451 return self._user_permissions
452 user_permissions = property(_get_user_permissions)
454 def get_group_permissions(self, obj=None):
455 return set()
457 def get_all_permissions(self, obj=None):
458 return _user_get_all_permissions(self, obj=obj)
460 def has_perm(self, perm, obj=None):
461 return _user_has_perm(self, perm, obj=obj)
463 def has_perms(self, perm_list, obj=None):
464 for perm in perm_list:
465 if not self.has_perm(perm, obj):
466 return False
467 return True
469 def has_module_perms(self, module):
470 return _user_has_module_perms(self, module)
472 def is_anonymous(self):
473 return True
475 def is_authenticated(self):
476 return False