Django

Code

Ticket #3011: 3011.7.diff

File 3011.7.diff, 18.1 kB (added by hvendelbo, 1 year ago)

Nearly there

  • a/django/conf/global_settings.py

    old new  
    375375# The number of days a password reset link is valid for 
    376376PASSWORD_RESET_TIMEOUT_DAYS = 3 
    377377 
     378# The class to use as the default AUTH_USER for the authentication system. 
     379AUTH_USER_MODULE = 'django.contrib.auth.user_model.User' 
     380 
     381# Trigger superuser creation after syncdb 
     382AUTH_AUTO_CREATE_SUPERUSER = True 
     383 
     384# Trigger permissions creation after syncdb 
     385AUTH_AUTO_CREATE_PERMISSIONS = True 
     386 
    378387########### 
    379388# TESTING # 
    380389########### 
  • a/django/contrib/auth/admin.py

    old new  
    11 
    2 from django.contrib.auth.models import User, Group 
     2from django.contrib.auth.models import Permission, User, Group, Message 
    33from django.core.exceptions import PermissionDenied 
    44from django import template 
    55from django.shortcuts import render_to_response, get_object_or_404 
     
    99from django.utils.translation import ugettext, ugettext_lazy as _ 
    1010from django.contrib.auth.forms import UserCreationForm, UserChangeForm, AdminPasswordChangeForm 
    1111from django.contrib import admin 
     12from django.conf import settings, global_settings 
    1213 
    1314class GroupAdmin(admin.ModelAdmin): 
    1415    search_fields = ('name',) 
     
    108111            'root_path': self.admin_site.root_path, 
    109112        }, context_instance=RequestContext(request)) 
    110113 
    111  
    112114admin.site.register(Group, GroupAdmin) 
    113 admin.site.register(User, UserAdmin) 
     115if settings.AUTH_USER_MODULE == global_settings.AUTH_USER_MODULE: 
     116    admin.site.register(User, UserAdmin) 
    114117 
  • a/django/contrib/auth/management/__init__.py

    old new  
    44 
    55from django.db.models import get_models, signals 
    66from django.contrib.auth import models as auth_app 
     7from django.conf import settings 
    78 
    89def _get_permission_codename(action, opts): 
    910    return u'%s_%s' % (action, opts.object_name.lower()) 
     
    4445                call_command("createsuperuser", interactive=True) 
    4546            break 
    4647 
    47 signals.post_syncdb.connect(create_permissions, 
    48     dispatch_uid = "django.contrib.auth.management.create_permissions") 
    49 signals.post_syncdb.connect(create_superuser, 
    50     sender=auth_app, dispatch_uid = "django.contrib.auth.management.create_superuser") 
     48if settings.AUTH_AUTO_CREATE_PERMISSIONS: 
     49    signals.post_syncdb.connect(create_permissions, 
     50        dispatch_uid = "django.contrib.auth.management.create_permissions") 
     51if settings.AUTH_AUTO_CREATE_SUPERUSER: 
     52    signals.post_syncdb.connect(create_superuser, 
     53        sender=auth_app, dispatch_uid = "django.contrib.auth.management.create_superuser") 
  • a/django/contrib/auth/models.py

    old new  
    55from django.contrib.contenttypes.models import ContentType 
    66from django.utils.encoding import smart_str 
    77from django.utils.translation import ugettext_lazy as _ 
     8from django.conf import settings, global_settings 
    89import datetime 
    910import urllib 
    1011 
     
    102103    def __unicode__(self): 
    103104        return self.name 
    104105 
    105 class UserManager(models.Manager): 
    106     def create_user(self, username, email, password=None): 
    107         "Creates and saves a User with the given username, e-mail and password." 
    108         now = datetime.datetime.now() 
    109         user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now) 
    110         if password: 
    111             user.set_password(password) 
    112         else: 
    113             user.set_unusable_password() 
    114         user.save() 
    115         return user 
    116  
    117     def create_superuser(self, username, email, password): 
    118         u = self.create_user(username, email, password) 
    119         u.is_staff = True 
    120         u.is_active = True 
    121         u.is_superuser = True 
    122         u.save() 
    123  
    124     def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'): 
    125         "Generates a random password with the given length and given allowed_chars" 
    126         # Note that default value of allowed_chars does not have "I" or letters 
    127         # that look like it -- just to avoid confusion. 
    128         from random import choice 
    129         return ''.join([choice(allowed_chars) for i in range(length)]) 
    130  
    131 class User(models.Model): 
    132     """Users within the Django authentication system are represented by this model. 
    133  
    134     Username and password are required. Other fields are optional. 
    135     """ 
    136     username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores).")) 
    137     first_name = models.CharField(_('first name'), max_length=30, blank=True) 
    138     last_name = models.CharField(_('last name'), max_length=30, blank=True) 
    139     email = models.EmailField(_('e-mail address'), blank=True) 
    140     password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>.")) 
    141     is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site.")) 
    142     is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user should be treated as active. Unselect this instead of deleting accounts.")) 
    143     is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them.")) 
    144     last_login = models.DateTimeField(_('last login'), default=datetime.datetime.now) 
    145     date_joined = models.DateTimeField(_('date joined'), default=datetime.datetime.now) 
    146     groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True, 
    147         help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in.")) 
    148     user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True) 
    149     objects = UserManager() 
     106class UserTemplate(models.Model): 
     107    """ Base class from which all User models inherit.  """ 
    150108 
    151109    class Meta: 
     110        abstract = True 
     111        app_label = "auth" 
    152112        verbose_name = _('user') 
    153113        verbose_name_plural = _('users') 
    154114 
    155     def __unicode__(self): 
    156         return self.username 
    157  
    158     def get_absolute_url(self): 
    159         return "/users/%s/" % urllib.quote(smart_str(self.username)) 
    160  
    161115    def is_anonymous(self): 
    162116        "Always returns False. This is a way of comparing User objects to anonymous users." 
    163117        return False 
     
    167121        """ 
    168122        return True 
    169123 
    170     def get_full_name(self): 
    171         "Returns the first_name plus the last_name, with a space in between." 
    172         full_name = u'%s %s' % (self.first_name, self.last_name) 
    173         return full_name.strip() 
    174  
    175     def set_password(self, raw_password): 
    176         import random 
    177         algo = 'sha1' 
    178         salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5] 
    179         hsh = get_hexdigest(algo, salt, raw_password) 
    180         self.password = '%s$%s$%s' % (algo, salt, hsh) 
    181  
    182     def check_password(self, raw_password): 
    183         """ 
    184         Returns a boolean of whether the raw_password was correct. Handles 
    185         encryption formats behind the scenes. 
    186         """ 
    187         # Backwards-compatibility check. Older passwords won't include the 
    188         # algorithm or salt. 
    189         if '$' not in self.password: 
    190             is_correct = (self.password == get_hexdigest('md5', '', raw_password)) 
    191             if is_correct: 
    192                 # Convert the password to the new, more secure format. 
    193                 self.set_password(raw_password) 
    194                 self.save() 
    195             return is_correct 
    196         return check_password(raw_password, self.password) 
    197  
    198     def set_unusable_password(self): 
    199         # Sets a value that will never be a valid hash 
    200         self.password = UNUSABLE_PASSWORD 
    201  
    202     def has_usable_password(self): 
    203         return self.password != UNUSABLE_PASSWORD 
    204  
    205124    def get_group_permissions(self): 
    206125        """ 
    207126        Returns a list of permission strings that this user has through 
     
    273192            m.delete() 
    274193        return messages 
    275194 
    276     def email_user(self, subject, message, from_email=None): 
    277         "Sends an e-mail to this User." 
    278         from django.core.mail import send_mail 
    279         send_mail(subject, message, from_email, [self.email]) 
    280  
    281195    def get_profile(self): 
    282196        """ 
    283197        Returns site-specific profile for this user. Raises 
     
    295209                raise SiteProfileNotAvailable 
    296210        return self._profile_cache 
    297211 
     212# Implement the User model according to settings 
     213from django.db.models import import_model 
     214User = import_model('auth',settings.AUTH_USER_MODULE) 
     215 
     216# Add the User model to the django models cache  
     217# These two lines allow the custom auth_user model to play nicely with syncdb  
     218# and other systems that rely on functions like  
     219# django.db.models.loading.get_model(...)  
     220#from django.db.models.loading import cache  
     221#cache.register_models('auth', User) 
     222 
     223# We need to remove whatever we used as the AUTH_USER_MODUlE from the 
     224# db cache so apps like contenttypes don't think that it's part 
     225# of contrib.auth 
     226#if settings.AUTH_USER_MODULE != global_settings.AUTH_USER_MODULE: 
     227#    del cache.app_models['auth'][auth_user_module_parts[1].lower()] 
     228 
    298229class Message(models.Model): 
    299230    """ 
    300231    The message system is a lightweight way to queue messages for given 
  • a/django/contrib/auth/tests/basic.py

    old new  
    11 
    22BASIC_TESTS = """ 
     3>>> from django.contrib.auth.models import User 
     4>>> User._meta.app_label 
     5'auth' 
     6>>> User._meta.object_name 
     7'User' 
     8 
    39>>> from django.contrib.auth.models import User, AnonymousUser 
    410>>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw') 
    511>>> u.has_usable_password() 
  • /dev/null

    old new  
     1from django.db import models 
     2from django.utils.translation import gettext_lazy as _ 
     3 
     4from django.contrib.auth.models import Group, Permission, UserTemplate, get_hexdigest, check_password, UNUSABLE_PASSWORD 
     5 
     6import datetime, urllib 
     7 
     8 
     9class UserManager(models.Manager): 
     10    def create_user(self, username, email, password=None): 
     11        "Creates and saves a User with the given username, e-mail and password." 
     12        now = datetime.datetime.now() 
     13        user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now) 
     14        if password: 
     15            user.set_password(password) 
     16        else: 
     17            user.set_unusable_password() 
     18        user.save() 
     19        return user 
     20 
     21    def create_superuser(self, username, email, password): 
     22        u = self.create_user(username, email, password) 
     23        u.is_staff = True 
     24        u.is_active = True 
     25        u.is_superuser = True 
     26        u.save() 
     27        return u 
     28 
     29    def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'): 
     30        "Generates a random password with the given length and given allowed_chars" 
     31        # Note that default value of allowed_chars does not have "I" or letters 
     32        # that look like it -- just to avoid confusion. 
     33        from random import choice 
     34        return ''.join([choice(allowed_chars) for i in range(length)]) 
     35 
     36 
     37class User(UserTemplate): 
     38    """Users within the Django authentication system are represented by this model. 
     39 
     40    Username and password are required. Other fields are optional. 
     41    """ 
     42    username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores).")) 
     43    first_name = models.CharField(_('first name'), max_length=30, blank=True) 
     44    last_name = models.CharField(_('last name'), max_length=30, blank=True) 
     45    email = models.EmailField(_('e-mail address'), blank=True) 
     46    password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>.")) 
     47    is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site.")) 
     48    is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user should be treated as active. Unselect this instead of deleting accounts.")) 
     49    is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them.")) 
     50    last_login = models.DateTimeField(_('last login'), default=datetime.datetime.now) 
     51    date_joined = models.DateTimeField(_('date joined'), default=datetime.datetime.now) 
     52    groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True, 
     53        help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in.")) 
     54    user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True) 
     55    objects = UserManager() 
     56     
     57    class Meta(UserTemplate.Meta): 
     58        db_table = "auth_user" 
     59 
     60    def __unicode__(self): 
     61        return self.username 
     62 
     63    def get_absolute_url(self): 
     64        return "/users/%s/" % urllib.quote(smart_str(self.username)) 
     65 
     66    def get_full_name(self): 
     67        "Returns the first_name plus the last_name, with a space in between." 
     68        full_name = u'%s %s' % (self.first_name, self.last_name) 
     69        return full_name.strip() 
     70 
     71    def set_password(self, raw_password): 
     72        import random 
     73        algo = 'sha1' 
     74        salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5] 
     75        hsh = get_hexdigest(algo, salt, raw_password) 
     76        self.password = '%s$%s$%s' % (algo, salt, hsh) 
     77 
     78    def check_password(self, raw_password): 
     79        """ 
     80        Returns a boolean of whether the raw_password was correct. Handles 
     81        encryption formats behind the scenes. 
     82        """ 
     83        # Backwards-compatibility check. Older passwords won't include the 
     84        # algorithm or salt. 
     85        if '$' not in self.password: 
     86            is_correct = (self.password == get_hexdigest('md5', '', raw_password)) 
     87            if is_correct: 
     88                # Convert the password to the new, more secure format. 
     89                self.set_password(raw_password) 
     90                self.save() 
     91            return is_correct 
     92        return check_password(raw_password, self.password) 
     93 
     94    def set_unusable_password(self): 
     95        # Sets a value that will never be a valid hash 
     96        self.password = UNUSABLE_PASSWORD 
     97 
     98    def has_usable_password(self): 
     99        return self.password != UNUSABLE_PASSWORD 
     100 
     101    def email_user(self, subject, message, from_email=None): 
     102        "Sends an e-mail to this User." 
     103        from django.core.mail import send_mail 
     104        send_mail(subject, message, from_email, [self.email]) 
  • a/django/db/models/__init__.py

    old new  
    11from django.conf import settings 
    22from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured 
    33from django.db import connection 
    4 from django.db.models.loading import get_apps, get_app, get_models, get_model, register_models 
     4from django.db.models.loading import get_apps, get_app, get_models, get_model, register_models, import_model 
    55from django.db.models.query import Q 
    66from django.db.models.manager import Manager 
    77from django.db.models.base import Model 
  • a/django/db/models/loading.py

    old new  
    88import os 
    99import threading 
    1010 
    11 __all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models', 
     11__all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models', 'import_model', 
    1212        'load_app', 'app_cache_ready') 
    1313 
    1414class AppCache(object):