Ticket #3011: #3011-extendable_auth_user-1.4.diff

File #3011-extendable_auth_user-1.4.diff, 35.8 KB (added by German M. Bravo, 12 years ago)

Updated for django 1.4

  • django/contrib/admin/sites.py

    diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
    index 83a0869..0cc92e3 100644
     
    11from functools import update_wrapper
    22from django import http
    33from django.contrib.admin import ModelAdmin, actions
    4 from django.contrib.admin.forms import AdminAuthenticationForm
    54from django.contrib.auth import REDIRECT_FIELD_NAME
    65from django.contrib.contenttypes import views as contenttype_views
    76from django.views.decorators.csrf import csrf_protect
    class AdminSite(object):  
    307306        Displays the login form for the given HttpRequest.
    308307        """
    309308        from django.contrib.auth.views import login
     309        from django.contrib.admin.forms import AdminAuthenticationForm
    310310        context = {
    311311            'title': _('Log in'),
    312312            'app_path': request.get_full_path(),
  • new file django/contrib/auth/base.py

    diff --git a/django/contrib/auth/base.py b/django/contrib/auth/base.py
    new file mode 100644
    index 0000000..c919822
    - +  
     1import urllib
     2
     3from django.core.exceptions import ImproperlyConfigured
     4from django.core.mail import send_mail
     5from django.db import models
     6from django.db.models.manager import EmptyManager
     7from django.utils.crypto import get_random_string
     8from django.utils.encoding import smart_str
     9from django.utils.translation import ugettext_lazy as _
     10from django.utils import timezone
     11
     12from django.contrib import auth
     13# UNUSABLE_PASSWORD is still imported here for backwards compatibility
     14from django.contrib.auth.hashers import (
     15    check_password, make_password, is_password_usable, UNUSABLE_PASSWORD)
     16from django.contrib.auth.signals import user_logged_in
     17from django.contrib.contenttypes.models import ContentType
     18
     19
     20def 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()
     27user_logged_in.connect(update_last_login)
     28
     29
     30class SiteProfileNotAvailable(Exception):
     31    pass
     32
     33
     34class 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),
     40        )
     41
     42
     43class Permission(models.Model):
     44    """
     45    The permissions system provides a way to assign permissions to specific
     46    users and groups of users.
     47
     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:
     50
     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.
     56
     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."
     62
     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()
     70
     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')
     77
     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))
     83
     84    def natural_key(self):
     85        return (self.codename,) + self.content_type.natural_key()
     86    natural_key.dependencies = ['contenttypes.contenttype']
     87
     88
     89class Group(models.Model):
     90    """
     91    Groups are a generic way of categorizing users to apply permissions, or
     92    some other label, to those users. A user can belong to any number of
     93    groups.
     94
     95    A user in a group automatically has all the permissions granted to that
     96    group. For example, if the group Site editors has the permission
     97    can_edit_home_page, any user in that group will have that permission.
     98
     99    Beyond permissions, groups are a convenient way to categorize users to
     100    apply some label, or extended functionality, to them. For example, you
     101    could create a group 'Special users', and you could write code that would
     102    do special things to those users -- such as giving them access to a
     103    members-only portion of your site, or sending them members-only email
     104    messages.
     105    """
     106    name = models.CharField(_('name'), max_length=80, unique=True)
     107    permissions = models.ManyToManyField(Permission,
     108        verbose_name=_('permissions'), blank=True)
     109
     110    class Meta:
     111        verbose_name = _('group')
     112        verbose_name_plural = _('groups')
     113
     114    def __unicode__(self):
     115        return self.name
     116
     117
     118class UserManager(models.Manager):
     119    def create_user(self, username, email=None, password=None):
     120        """
     121        Creates and saves a User with the given username, email and password.
     122        """
     123        now = timezone.now()
     124
     125        # Normalize the address by lowercasing the domain part of the email
     126        # address.
     127        email = email or ''
     128        try:
     129            email_name, domain_part = email.strip().split('@', 1)
     130        except ValueError:
     131            pass
     132        else:
     133            email = '@'.join([email_name, domain_part.lower()])
     134
     135        user = self.model(username=username, email=email, is_staff=False,
     136                         is_active=True, is_superuser=False, last_login=now,
     137                         date_joined=now)
     138
     139        user.set_password(password)
     140        user.save(using=self._db)
     141        return user
     142
     143    def create_superuser(self, username, email, password):
     144        u = self.create_user(username, email, password)
     145        u.is_staff = True
     146        u.is_active = True
     147        u.is_superuser = True
     148        u.save(using=self._db)
     149        return u
     150
     151    def make_random_password(self, length=10,
     152                             allowed_chars='abcdefghjkmnpqrstuvwxyz'
     153                                           'ABCDEFGHJKLMNPQRSTUVWXYZ'
     154                                           '23456789'):
     155        """
     156        Generates a random password with the given length and given
     157        allowed_chars. Note that the default value of allowed_chars does not
     158        have "I" or "O" or letters and digits that look similar -- just to
     159        avoid confusion.
     160        """
     161        return get_random_string(length, allowed_chars)
     162
     163
     164# A few helper functions for common logic between User and AnonymousUser.
     165def _user_get_all_permissions(user, obj):
     166    permissions = set()
     167    for backend in auth.get_backends():
     168        if hasattr(backend, "get_all_permissions"):
     169            if obj is not None:
     170                permissions.update(backend.get_all_permissions(user, obj))
     171            else:
     172                permissions.update(backend.get_all_permissions(user))
     173    return permissions
     174
     175
     176def _user_has_perm(user, perm, obj):
     177    anon = user.is_anonymous()
     178    active = user.is_active
     179    for backend in auth.get_backends():
     180        if anon or active or backend.supports_inactive_user:
     181            if hasattr(backend, "has_perm"):
     182                if obj is not None:
     183                    if backend.has_perm(user, perm, obj):
     184                            return True
     185                else:
     186                    if backend.has_perm(user, perm):
     187                        return True
     188    return False
     189
     190
     191def _user_has_module_perms(user, app_label):
     192    anon = user.is_anonymous()
     193    active = user.is_active
     194    for backend in auth.get_backends():
     195        if anon or active or backend.supports_inactive_user:
     196            if hasattr(backend, "has_module_perms"):
     197                if backend.has_module_perms(user, app_label):
     198                    return True
     199    return False
     200
     201
     202class UserTemplate(models.Model):
     203    """
     204    Users within the Django authentication system are represented by this
     205    model.
     206
     207    Username and password are required. Other fields are optional.
     208    """
     209    username = models.CharField(_('username'), max_length=30, unique=True,
     210        help_text=_('Required. 30 characters or fewer. Letters, numbers and '
     211                    '@/./+/-/_ characters'))
     212    first_name = models.CharField(_('first name'), max_length=30, blank=True)
     213    last_name = models.CharField(_('last name'), max_length=30, blank=True)
     214    email = models.EmailField(_('e-mail address'), blank=True)
     215    password = models.CharField(_('password'), max_length=128)
     216    is_staff = models.BooleanField(_('staff status'), default=False,
     217        help_text=_('Designates whether the user can log into this admin '
     218                    'site.'))
     219    is_active = models.BooleanField(_('active'), default=True,
     220        help_text=_('Designates whether this user should be treated as '
     221                    'active. Unselect this instead of deleting accounts.'))
     222    is_superuser = models.BooleanField(_('superuser status'), default=False,
     223        help_text=_('Designates that this user has all permissions without '
     224                    'explicitly assigning them.'))
     225    last_login = models.DateTimeField(_('last login'), default=timezone.now)
     226    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
     227    groups = models.ManyToManyField(Group, verbose_name=_('groups'),
     228        blank=True, help_text=_('The groups this user belongs to. A user will '
     229                                'get all permissions granted to each of '
     230                                'his/her group.'))
     231    user_permissions = models.ManyToManyField(Permission,
     232        verbose_name=_('user permissions'), blank=True,
     233        help_text='Specific permissions for this user.')
     234    objects = UserManager()
     235
     236    class Meta:
     237        abstract = True
     238
     239    def __unicode__(self):
     240        return self.username
     241
     242    def get_absolute_url(self):
     243        return "/users/%s/" % urllib.quote(smart_str(self.username))
     244
     245    def is_anonymous(self):
     246        """
     247        Always returns False. This is a way of comparing User objects to
     248        anonymous users.
     249        """
     250        return False
     251
     252    def is_authenticated(self):
     253        """
     254        Always return True. This is a way to tell if the user has been
     255        authenticated in templates.
     256        """
     257        return True
     258
     259    def get_full_name(self):
     260        """
     261        Returns the first_name plus the last_name, with a space in between.
     262        """
     263        full_name = u'%s %s' % (self.first_name, self.last_name)
     264        return full_name.strip()
     265
     266    def set_password(self, raw_password):
     267        self.password = make_password(raw_password)
     268
     269    def check_password(self, raw_password):
     270        """
     271        Returns a boolean of whether the raw_password was correct. Handles
     272        hashing formats behind the scenes.
     273        """
     274        def setter(raw_password):
     275            self.set_password(raw_password)
     276            self.save()
     277        return check_password(raw_password, self.password, setter)
     278
     279    def set_unusable_password(self):
     280        # Sets a value that will never be a valid hash
     281        self.password = make_password(None)
     282
     283    def has_usable_password(self):
     284        return is_password_usable(self.password)
     285
     286    def get_group_permissions(self, obj=None):
     287        """
     288        Returns a list of permission strings that this user has through his/her
     289        groups. This method queries all available auth backends. If an object
     290        is passed in, only permissions matching this object are returned.
     291        """
     292        permissions = set()
     293        for backend in auth.get_backends():
     294            if hasattr(backend, "get_group_permissions"):
     295                if obj is not None:
     296                    permissions.update(backend.get_group_permissions(self,
     297                                                                     obj))
     298                else:
     299                    permissions.update(backend.get_group_permissions(self))
     300        return permissions
     301
     302    def get_all_permissions(self, obj=None):
     303        return _user_get_all_permissions(self, obj)
     304
     305    def has_perm(self, perm, obj=None):
     306        """
     307        Returns True if the user has the specified permission. This method
     308        queries all available auth backends, but returns immediately if any
     309        backend returns True. Thus, a user who has permission from a single
     310        auth backend is assumed to have permission in general. If an object is
     311        provided, permissions for this specific object are checked.
     312        """
     313
     314        # Active superusers have all permissions.
     315        if self.is_active and self.is_superuser:
     316            return True
     317
     318        # Otherwise we need to check the backends.
     319        return _user_has_perm(self, perm, obj)
     320
     321    def has_perms(self, perm_list, obj=None):
     322        """
     323        Returns True if the user has each of the specified permissions. If
     324        object is passed, it checks if the user has all required perms for this
     325        object.
     326        """
     327        for perm in perm_list:
     328            if not self.has_perm(perm, obj):
     329                return False
     330        return True
     331
     332    def has_module_perms(self, app_label):
     333        """
     334        Returns True if the user has any permissions in the given app label.
     335        Uses pretty much the same logic as has_perm, above.
     336        """
     337        # Active superusers have all permissions.
     338        if self.is_active and self.is_superuser:
     339            return True
     340
     341        return _user_has_module_perms(self, app_label)
     342
     343    def email_user(self, subject, message, from_email=None):
     344        """
     345        Sends an email to this User.
     346        """
     347        send_mail(subject, message, from_email, [self.email])
     348
     349    def get_profile(self):
     350        """
     351        Returns site-specific profile for this user. Raises
     352        SiteProfileNotAvailable if this site does not allow profiles.
     353        """
     354        if not hasattr(self, '_profile_cache'):
     355            from django.conf import settings
     356            if not getattr(settings, 'AUTH_PROFILE_MODULE', False):
     357                raise SiteProfileNotAvailable(
     358                    'You need to set AUTH_PROFILE_MODULE in your project '
     359                    'settings')
     360            try:
     361                app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
     362            except ValueError:
     363                raise SiteProfileNotAvailable(
     364                    'app_label and model_name should be separated by a dot in '
     365                    'the AUTH_PROFILE_MODULE setting')
     366            try:
     367                model = models.get_model(app_label, model_name)
     368                if model is None:
     369                    raise SiteProfileNotAvailable(
     370                        'Unable to load the profile model, check '
     371                        'AUTH_PROFILE_MODULE in your project settings')
     372                self._profile_cache = model._default_manager.using(
     373                                   self._state.db).get(user__id__exact=self.id)
     374                self._profile_cache.user = self
     375            except (ImportError, ImproperlyConfigured):
     376                raise SiteProfileNotAvailable
     377        return self._profile_cache
     378
     379
     380class AnonymousUser(object):
     381    id = None
     382    username = ''
     383    is_staff = False
     384    is_active = False
     385    is_superuser = False
     386    _groups = EmptyManager()
     387    _user_permissions = EmptyManager()
     388
     389    def __init__(self):
     390        pass
     391
     392    def __unicode__(self):
     393        return 'AnonymousUser'
     394
     395    def __str__(self):
     396        return unicode(self).encode('utf-8')
     397
     398    def __eq__(self, other):
     399        return isinstance(other, self.__class__)
     400
     401    def __ne__(self, other):
     402        return not self.__eq__(other)
     403
     404    def __hash__(self):
     405        return 1 # instances always return the same hash value
     406
     407    def save(self):
     408        raise NotImplementedError
     409
     410    def delete(self):
     411        raise NotImplementedError
     412
     413    def set_password(self, raw_password):
     414        raise NotImplementedError
     415
     416    def check_password(self, raw_password):
     417        raise NotImplementedError
     418
     419    def _get_groups(self):
     420        return self._groups
     421    groups = property(_get_groups)
     422
     423    def _get_user_permissions(self):
     424        return self._user_permissions
     425    user_permissions = property(_get_user_permissions)
     426
     427    def get_group_permissions(self, obj=None):
     428        return set()
     429
     430    def get_all_permissions(self, obj=None):
     431        return _user_get_all_permissions(self, obj=obj)
     432
     433    def has_perm(self, perm, obj=None):
     434        return _user_has_perm(self, perm, obj=obj)
     435
     436    def has_perms(self, perm_list, obj=None):
     437        for perm in perm_list:
     438            if not self.has_perm(perm, obj):
     439                return False
     440        return True
     441
     442    def has_module_perms(self, module):
     443        return _user_has_module_perms(self, module)
     444
     445    def is_anonymous(self):
     446        return True
     447
     448    def is_authenticated(self):
     449        return False
  • django/contrib/auth/models.py

    diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
    index 4bb8cad..6291350 100644
     
    1 import urllib
    2 
    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
     1from django.conf import settings
    92from django.utils.translation import ugettext_lazy as _
    10 from django.utils import timezone
    11 
    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
    18 
     3from django.core.exceptions import ImproperlyConfigured
    194
    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)
     5from django.contrib.auth.base import *
    286
    297
    30 class SiteProfileNotAvailable(Exception):
     8class AuthNotAvailable(Exception):
    319    pass
    3210
    3311
    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),
    40         )
    41 
    42 
    43 class Permission(models.Model):
    44     """
    45     The permissions system provides a way to assign permissions to specific
    46     users and groups of users.
    47 
    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:
    50 
    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.
    56 
    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."
    62 
    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()
    70 
    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')
    77 
    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))
    83 
    84     def natural_key(self):
    85         return (self.codename,) + self.content_type.natural_key()
    86     natural_key.dependencies = ['contenttypes.contenttype']
    87 
    88 
    89 class Group(models.Model):
    90     """
    91     Groups are a generic way of categorizing users to apply permissions, or
    92     some other label, to those users. A user can belong to any number of
    93     groups.
    94 
    95     A user in a group automatically has all the permissions granted to that
    96     group. For example, if the group Site editors has the permission
    97     can_edit_home_page, any user in that group will have that permission.
    98 
    99     Beyond permissions, groups are a convenient way to categorize users to
    100     apply some label, or extended functionality, to them. For example, you
    101     could create a group 'Special users', and you could write code that would
    102     do special things to those users -- such as giving them access to a
    103     members-only portion of your site, or sending them members-only email
    104     messages.
    105     """
    106     name = models.CharField(_('name'), max_length=80, unique=True)
    107     permissions = models.ManyToManyField(Permission,
    108         verbose_name=_('permissions'), blank=True)
    109 
    110     class Meta:
    111         verbose_name = _('group')
    112         verbose_name_plural = _('groups')
    113 
    114     def __unicode__(self):
    115         return self.name
    116 
    117 
    118 class UserManager(models.Manager):
    119     def create_user(self, username, email=None, password=None):
    120         """
    121         Creates and saves a User with the given username, email and password.
    122         """
    123         now = timezone.now()
    124 
    125         # Normalize the address by lowercasing the domain part of the email
    126         # address.
    127         email = email or ''
    128         try:
    129             email_name, domain_part = email.strip().split('@', 1)
    130         except ValueError:
    131             pass
    132         else:
    133             email = '@'.join([email_name, domain_part.lower()])
    134 
    135         user = self.model(username=username, email=email, is_staff=False,
    136                          is_active=True, is_superuser=False, last_login=now,
    137                          date_joined=now)
    138 
    139         user.set_password(password)
    140         user.save(using=self._db)
    141         return user
    142 
    143     def create_superuser(self, username, email, password):
    144         u = self.create_user(username, email, password)
    145         u.is_staff = True
    146         u.is_active = True
    147         u.is_superuser = True
    148         u.save(using=self._db)
    149         return u
    150 
    151     def make_random_password(self, length=10,
    152                              allowed_chars='abcdefghjkmnpqrstuvwxyz'
    153                                            'ABCDEFGHJKLMNPQRSTUVWXYZ'
    154                                            '23456789'):
    155         """
    156         Generates a random password with the given length and given
    157         allowed_chars. Note that the default value of allowed_chars does not
    158         have "I" or "O" or letters and digits that look similar -- just to
    159         avoid confusion.
    160         """
    161         return get_random_string(length, allowed_chars)
    162 
    163 
    164 # A few helper functions for common logic between User and AnonymousUser.
    165 def _user_get_all_permissions(user, obj):
    166     permissions = set()
    167     for backend in auth.get_backends():
    168         if hasattr(backend, "get_all_permissions"):
    169             if obj is not None:
    170                 permissions.update(backend.get_all_permissions(user, obj))
    171             else:
    172                 permissions.update(backend.get_all_permissions(user))
    173     return permissions
    174 
    175 
    176 def _user_has_perm(user, perm, obj):
    177     anon = user.is_anonymous()
    178     active = user.is_active
    179     for backend in auth.get_backends():
    180         if anon or active or backend.supports_inactive_user:
    181             if hasattr(backend, "has_perm"):
    182                 if obj is not None:
    183                     if backend.has_perm(user, perm, obj):
    184                             return True
    185                 else:
    186                     if backend.has_perm(user, perm):
    187                         return True
    188     return False
    189 
    190 
    191 def _user_has_module_perms(user, app_label):
    192     anon = user.is_anonymous()
    193     active = user.is_active
    194     for backend in auth.get_backends():
    195         if anon or active or backend.supports_inactive_user:
    196             if hasattr(backend, "has_module_perms"):
    197                 if backend.has_module_perms(user, app_label):
    198                     return True
    199     return False
    200 
    201 
    202 class User(models.Model):
    203     """
    204     Users within the Django authentication system are represented by this
    205     model.
    206 
    207     Username and password are required. Other fields are optional.
    208     """
    209     username = models.CharField(_('username'), max_length=30, unique=True,
    210         help_text=_('Required. 30 characters or fewer. Letters, numbers and '
    211                     '@/./+/-/_ characters'))
    212     first_name = models.CharField(_('first name'), max_length=60, blank=True)
    213     last_name = models.CharField(_('last name'), max_length=60, blank=True)
    214     email = models.EmailField(_('e-mail address'), max_length=255, blank=True)
    215     password = models.CharField(_('password'), max_length=128)
    216     is_staff = models.BooleanField(_('staff status'), default=False,
    217         help_text=_('Designates whether the user can log into this admin '
    218                     'site.'))
    219     is_active = models.BooleanField(_('active'), default=True,
    220         help_text=_('Designates whether this user should be treated as '
    221                     'active. Unselect this instead of deleting accounts.'))
    222     is_superuser = models.BooleanField(_('superuser status'), default=False,
    223         help_text=_('Designates that this user has all permissions without '
    224                     'explicitly assigning them.'))
    225     last_login = models.DateTimeField(_('last login'), default=timezone.now)
    226     date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
    227     groups = models.ManyToManyField(Group, verbose_name=_('groups'),
    228         blank=True, help_text=_('The groups this user belongs to. A user will '
    229                                 'get all permissions granted to each of '
    230                                 'his/her group.'))
    231     user_permissions = models.ManyToManyField(Permission,
    232         verbose_name=_('user permissions'), blank=True,
    233         help_text='Specific permissions for this user.')
    234     objects = UserManager()
    235 
    236     class Meta:
    237         verbose_name = _('user')
    238         verbose_name_plural = _('users')
    239 
    240     def __unicode__(self):
    241         return self.username
    242 
    243     def get_absolute_url(self):
    244         return "/users/%s/" % urllib.quote(smart_str(self.username))
    245 
    246     def is_anonymous(self):
    247         """
    248         Always returns False. This is a way of comparing User objects to
    249         anonymous users.
    250         """
    251         return False
    252 
    253     def is_authenticated(self):
    254         """
    255         Always return True. This is a way to tell if the user has been
    256         authenticated in templates.
    257         """
    258         return True
    259 
    260     def get_full_name(self):
    261         """
    262         Returns the first_name plus the last_name, with a space in between.
    263         """
    264         full_name = u'%s %s' % (self.first_name, self.last_name)
    265         return full_name.strip()
    266 
    267     def set_password(self, raw_password):
    268         self.password = make_password(raw_password)
    269 
    270     def check_password(self, raw_password):
    271         """
    272         Returns a boolean of whether the raw_password was correct. Handles
    273         hashing formats behind the scenes.
    274         """
    275         def setter(raw_password):
    276             self.set_password(raw_password)
    277             self.save()
    278         return check_password(raw_password, self.password, setter)
    279 
    280     def set_unusable_password(self):
    281         # Sets a value that will never be a valid hash
    282         self.password = make_password(None)
    283 
    284     def has_usable_password(self):
    285         return is_password_usable(self.password)
    286 
    287     def get_group_permissions(self, obj=None):
    288         """
    289         Returns a list of permission strings that this user has through his/her
    290         groups. This method queries all available auth backends. If an object
    291         is passed in, only permissions matching this object are returned.
    292         """
    293         permissions = set()
    294         for backend in auth.get_backends():
    295             if hasattr(backend, "get_group_permissions"):
    296                 if obj is not None:
    297                     permissions.update(backend.get_group_permissions(self,
    298                                                                      obj))
    299                 else:
    300                     permissions.update(backend.get_group_permissions(self))
    301         return permissions
    302 
    303     def get_all_permissions(self, obj=None):
    304         return _user_get_all_permissions(self, obj)
    305 
    306     def has_perm(self, perm, obj=None):
    307         """
    308         Returns True if the user has the specified permission. This method
    309         queries all available auth backends, but returns immediately if any
    310         backend returns True. Thus, a user who has permission from a single
    311         auth backend is assumed to have permission in general. If an object is
    312         provided, permissions for this specific object are checked.
    313         """
    314 
    315         # Active superusers have all permissions.
    316         if self.is_active and self.is_superuser:
    317             return True
    318 
    319         # Otherwise we need to check the backends.
    320         return _user_has_perm(self, perm, obj)
    321 
    322     def has_perms(self, perm_list, obj=None):
    323         """
    324         Returns True if the user has each of the specified permissions. If
    325         object is passed, it checks if the user has all required perms for this
    326         object.
    327         """
    328         for perm in perm_list:
    329             if not self.has_perm(perm, obj):
    330                 return False
    331         return True
    332 
    333     def has_module_perms(self, app_label):
    334         """
    335         Returns True if the user has any permissions in the given app label.
    336         Uses pretty much the same logic as has_perm, above.
    337         """
    338         # Active superusers have all permissions.
    339         if self.is_active and self.is_superuser:
    340             return True
    341 
    342         return _user_has_module_perms(self, app_label)
    343 
    344     def email_user(self, subject, message, from_email=None):
    345         """
    346         Sends an email to this User.
    347         """
    348         send_mail(subject, message, from_email, [self.email])
    349 
    350     def get_profile(self):
    351         """
    352         Returns site-specific profile for this user. Raises
    353         SiteProfileNotAvailable if this site does not allow profiles.
    354         """
    355         if not hasattr(self, '_profile_cache'):
    356             from django.conf import settings
    357             if not getattr(settings, 'AUTH_PROFILE_MODULE', False):
    358                 raise SiteProfileNotAvailable(
    359                     'You need to set AUTH_PROFILE_MODULE in your project '
    360                     'settings')
    361             try:
    362                 app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
    363             except ValueError:
    364                 raise SiteProfileNotAvailable(
    365                     'app_label and model_name should be separated by a dot in '
    366                     'the AUTH_PROFILE_MODULE setting')
    367             try:
    368                 model = models.get_model(app_label, model_name)
    369                 if model is None:
    370                     raise SiteProfileNotAvailable(
    371                         'Unable to load the profile model, check '
    372                         'AUTH_PROFILE_MODULE in your project settings')
    373                 self._profile_cache = model._default_manager.using(
    374                                    self._state.db).get(user__id__exact=self.id)
    375                 self._profile_cache.user = self
    376             except (ImportError, ImproperlyConfigured):
    377                 raise SiteProfileNotAvailable
    378         return self._profile_cache
    379 
    380 
    381 class AnonymousUser(object):
    382     id = None
    383     username = ''
    384     is_staff = False
    385     is_active = False
    386     is_superuser = False
    387     _groups = EmptyManager()
    388     _user_permissions = EmptyManager()
    389 
    390     def __init__(self):
    391         pass
    392 
    393     def __unicode__(self):
    394         return 'AnonymousUser'
    395 
    396     def __str__(self):
    397         return unicode(self).encode('utf-8')
    398 
    399     def __eq__(self, other):
    400         return isinstance(other, self.__class__)
    401 
    402     def __ne__(self, other):
    403         return not self.__eq__(other)
    404 
    405     def __hash__(self):
    406         return 1 # instances always return the same hash value
    407 
    408     def save(self):
    409         raise NotImplementedError
    410 
    411     def delete(self):
    412         raise NotImplementedError
    413 
    414     def set_password(self, raw_password):
    415         raise NotImplementedError
    416 
    417     def check_password(self, raw_password):
    418         raise NotImplementedError
    419 
    420     def _get_groups(self):
    421         return self._groups
    422     groups = property(_get_groups)
    423 
    424     def _get_user_permissions(self):
    425         return self._user_permissions
    426     user_permissions = property(_get_user_permissions)
    427 
    428     def get_group_permissions(self, obj=None):
    429         return set()
    430 
    431     def get_all_permissions(self, obj=None):
    432         return _user_get_all_permissions(self, obj=obj)
    433 
    434     def has_perm(self, perm, obj=None):
    435         return _user_has_perm(self, perm, obj=obj)
    436 
    437     def has_perms(self, perm_list, obj=None):
    438         for perm in perm_list:
    439             if not self.has_perm(perm, obj):
    440                 return False
    441         return True
    442 
    443     def has_module_perms(self, module):
    444         return _user_has_module_perms(self, module)
    445 
    446     def is_anonymous(self):
    447         return True
    448 
    449     def is_authenticated(self):
    450         return False
     12if hasattr(settings, 'AUTH_USER_MODULE'):
     13    try:
     14        app_label, model_name = settings.AUTH_USER_MODULE.split('.')
     15    except ValueError:
     16        raise AuthNotAvailable('app_label and model_name should'
     17                ' be separated by a dot in the AUTH_USER_MODULE set'
     18                'ting')
     19
     20    try:
     21        # Grab the AUTH_USER_MODULE path and classname from the settings.
     22        module = __import__(app_label + '.models', {}, {}, [''])
     23        # Store the user model so it is accessible with the standard
     24        # 'from django.contrib.auth.models import User'
     25        User = getattr(module, model_name, None)
     26
     27        if User is None:
     28            raise AuthNotAvailable('Unable to load the user '
     29                'model, check AUTH_USER_MODULE in your project sett'
     30                'ings')
     31    except (ImportError, ImproperlyConfigured):
     32        raise AuthNotAvailable
     33
     34    # Add te User model to the django models cache
     35    # These two lines allow the custom auth_user model to play nicely with syncdb
     36    # and other systems that rely on functions like
     37    # django.db.models.loading.get_model(...)
     38    from django.db.models.loading import cache
     39    cache.register_models('auth', User)
     40
     41    # We need to remove whatever we used as the AUTH_USER_MODUlE from the
     42    # db cache so apps like contenttypes don't think that it's part
     43    # of contrib.auth
     44    del cache.app_models['auth'][User.__name__.lower()]
     45else:
     46    class User(UserTemplate):
     47        class Meta:
     48            verbose_name = _('user')
     49            verbose_name_plural = _('users')
Back to Top