diff options
| author | Adrian Holovaty <adrian@holovaty.com> | 2006-05-02 01:31:56 +0000 |
|---|---|---|
| committer | Adrian Holovaty <adrian@holovaty.com> | 2006-05-02 01:31:56 +0000 |
| commit | f69cf70ed813a8cd7e1f963a14ae39103e8d5265 (patch) | |
| tree | d3b32e84cd66573b3833ddf662af020f8ef2f7a8 /django/contrib/auth/models.py | |
| parent | d5dbeaa9be359a4c794885c2e9f1b5a7e5e51fb8 (diff) | |
MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-incompatible. Please read http://code.djangoproject.com/wiki/RemovingTheMagic for upgrade instructions.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@2809 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/contrib/auth/models.py')
| -rw-r--r-- | django/contrib/auth/models.py | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py new file mode 100644 index 0000000000..cea7a694c9 --- /dev/null +++ b/django/contrib/auth/models.py @@ -0,0 +1,264 @@ +from django.core import validators +from django.db import backend, connection, models +from django.contrib.contenttypes.models import ContentType +from django.utils.translation import gettext_lazy as _ +import datetime + +SESSION_KEY = '_auth_user_id' + +class SiteProfileNotAvailable(Exception): + pass + +class Permission(models.Model): + name = models.CharField(_('name'), maxlength=50) + content_type = models.ForeignKey(ContentType) + codename = models.CharField(_('codename'), maxlength=100) + class Meta: + verbose_name = _('permission') + verbose_name_plural = _('permissions') + unique_together = (('content_type', 'codename'),) + ordering = ('content_type', 'codename') + + def __str__(self): + return "%r | %s" % (self.content_type, self.name) + +class Group(models.Model): + name = models.CharField(_('name'), maxlength=80, unique=True) + permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True, filter_interface=models.HORIZONTAL) + class Meta: + verbose_name = _('group') + verbose_name_plural = _('groups') + ordering = ('name',) + class Admin: + search_fields = ('name',) + + def __str__(self): + return self.name + +class UserManager(models.Manager): + def create_user(self, username, email, password): + "Creates and saves a User with the given username, e-mail and password." + now = datetime.datetime.now() + user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now) + user.set_password(password) + user.save() + return user + + def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'): + "Generates a random password with the given length and given allowed_chars" + # Note that default value of allowed_chars does not have "I" or letters + # that look like it -- just to avoid confusion. + from random import choice + return ''.join([choice(allowed_chars) for i in range(length)]) + +class User(models.Model): + username = models.CharField(_('username'), maxlength=30, unique=True, validator_list=[validators.isAlphaNumeric]) + first_name = models.CharField(_('first name'), maxlength=30, blank=True) + last_name = models.CharField(_('last name'), maxlength=30, blank=True) + email = models.EmailField(_('e-mail address'), blank=True) + password = models.CharField(_('password'), maxlength=128, help_text=_("Use '[algo]$[salt]$[hexdigest]'")) + is_staff = models.BooleanField(_('staff status'), help_text=_("Designates whether the user can log into this admin site.")) + is_active = models.BooleanField(_('active'), default=True) + is_superuser = models.BooleanField(_('superuser status')) + last_login = models.DateTimeField(_('last login'), default=models.LazyDate()) + date_joined = models.DateTimeField(_('date joined'), default=models.LazyDate()) + groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True, + help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in.")) + user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True, filter_interface=models.HORIZONTAL) + objects = UserManager() + class Meta: + verbose_name = _('user') + verbose_name_plural = _('users') + ordering = ('username',) + class Admin: + fields = ( + (None, {'fields': ('username', 'password')}), + (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}), + (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}), + (_('Important dates'), {'fields': ('last_login', 'date_joined')}), + (_('Groups'), {'fields': ('groups',)}), + ) + list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff') + list_filter = ('is_staff', 'is_superuser') + search_fields = ('username', 'first_name', 'last_name', 'email') + + def __str__(self): + return self.username + + def get_absolute_url(self): + return "/users/%s/" % self.username + + def is_anonymous(self): + return False + + def get_full_name(self): + full_name = '%s %s' % (self.first_name, self.last_name) + return full_name.strip() + + def set_password(self, raw_password): + import sha, random + algo = 'sha1' + salt = sha.new(str(random.random())).hexdigest()[:5] + hsh = sha.new(salt+raw_password).hexdigest() + self.password = '%s$%s$%s' % (algo, salt, hsh) + + def check_password(self, raw_password): + """ + Returns a boolean of whether the raw_password was correct. Handles + encryption formats behind the scenes. + """ + # Backwards-compatibility check. Older passwords won't include the + # algorithm or salt. + if '$' not in self.password: + import md5 + is_correct = (self.password == md5.new(raw_password).hexdigest()) + if is_correct: + # Convert the password to the new, more secure format. + self.set_password(raw_password) + self.save() + return is_correct + algo, salt, hsh = self.password.split('$') + if algo == 'md5': + import md5 + return hsh == md5.new(salt+raw_password).hexdigest() + elif algo == 'sha1': + import sha + return hsh == sha.new(salt+raw_password).hexdigest() + raise ValueError, "Got unknown password algorithm type in password." + + def get_group_permissions(self): + "Returns a list of permission strings that this user has through his/her groups." + if not hasattr(self, '_group_perm_cache'): + import sets + cursor = connection.cursor() + # The SQL below works out to the following, after DB quoting: + # cursor.execute(""" + # SELECT ct."app_label", p."codename" + # FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct + # WHERE p."id" = gp."permission_id" + # AND gp."group_id" = ug."group_id" + # AND ct."id" = p."content_type_id" + # AND ug."user_id" = %s, [self.id]) + sql = """ + SELECT ct.%s, p.%s + FROM %s p, %s gp, %s ug, %s ct + WHERE p.%s = gp.%s + AND gp.%s = ug.%s + AND ct.%s = p.%s + AND ug.%s = %%s""" % ( + backend.quote_name('app_label'), backend.quote_name('codename'), + backend.quote_name('auth_permission'), backend.quote_name('auth_group_permissions'), + backend.quote_name('auth_user_groups'), backend.quote_name('django_content_type'), + backend.quote_name('id'), backend.quote_name('permission_id'), + backend.quote_name('group_id'), backend.quote_name('group_id'), + backend.quote_name('id'), backend.quote_name('content_type_id'), + backend.quote_name('user_id'),) + cursor.execute(sql, [self.id]) + self._group_perm_cache = sets.Set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) + return self._group_perm_cache + + def get_all_permissions(self): + if not hasattr(self, '_perm_cache'): + import sets + self._perm_cache = sets.Set(["%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.all()]) + self._perm_cache.update(self.get_group_permissions()) + return self._perm_cache + + def has_perm(self, perm): + "Returns True if the user has the specified permission." + if not self.is_active: + return False + if self.is_superuser: + return True + return perm in self.get_all_permissions() + + def has_perms(self, perm_list): + "Returns True if the user has each of the specified permissions." + for perm in perm_list: + if not self.has_perm(perm): + return False + return True + + def has_module_perms(self, app_label): + "Returns True if the user has any permissions in the given app label." + if self.is_superuser: + return True + return bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == app_label])) + + def get_and_delete_messages(self): + messages = [] + for m in self.message_set.all(): + messages.append(m.message) + m.delete() + return messages + + def email_user(self, subject, message, from_email=None): + "Sends an e-mail to this User." + from django.core.mail import send_mail + send_mail(subject, message, from_email, [self.email]) + + def get_profile(self): + """ + Returns site-specific profile for this user. Raises + SiteProfileNotAvailable if this site does not allow profiles. + """ + if not hasattr(self, '_profile_cache'): + from django.conf import settings + if not settings.AUTH_PROFILE_MODULE: + raise SiteProfileNotAvailable + try: + app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.') + model = models.get_model(app_label, model_name) + self._profile_cache = model._default_manager.get(user__id__exact=self.id) + except ImportError, ImproperlyConfigured: + raise SiteProfileNotAvailable + return self._profile_cache + +class Message(models.Model): + user = models.ForeignKey(User) + message = models.TextField(_('message')) + + def __str__(self): + return self.message + +class AnonymousUser(object): + id = None + username = '' + + def __init__(self): + pass + + def __str__(self): + return 'AnonymousUser' + + def save(self): + raise NotImplementedError + + def delete(self): + raise NotImplementedError + + def set_password(self, raw_password): + raise NotImplementedError + + def check_password(self, raw_password): + raise NotImplementedError + + def _get_groups(self): + raise NotImplementedError + groups = property(_get_groups) + + def _get_user_permissions(self): + raise NotImplementedError + user_permissions = property(_get_user_permissions) + + def has_perm(self, perm): + return False + + def has_module_perms(self, module): + return False + + def get_and_delete_messages(self): + return [] + + def is_anonymous(self): + return True |
