Ticket #3011: 3011.5.diff
File 3011.5.diff, 15.5 KB (added by , 16 years ago) |
---|
-
django/conf/global_settings.py
363 363 364 364 LOGIN_REDIRECT_URL = '/accounts/profile/' 365 365 366 # The class to use as the default AUTH_USER for the authentication system. 367 AUTH_USER_MODULE = 'django.contrib.auth.default_user.DefaultUser' 368 366 369 ########### 367 370 # TESTING # 368 371 ########### -
django/contrib/auth/default_user.py
1 from django.db import models 2 from django.core import validators 3 from django.utils.translation import gettext_lazy as _ 4 5 from django.contrib.auth.models import Group, Permission, UserTemplate 6 7 import datetime 8 9 10 class DefaultUserManager(models.Manager): 11 def create_user(self, username, email, password=None): 12 "Creates and saves a User with the given username, e-mail and password." 13 now = datetime.datetime.now() 14 user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now) 15 if password: 16 user.set_password(password) 17 else: 18 user.set_unusable_password() 19 user.save() 20 return user 21 22 def create_superuser(self, username, email, password): 23 u = self.create_user(username, email, password) 24 u.is_staff = True 25 u.is_active = True 26 u.is_superuser = True 27 u.save() 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 37 class DefaultUser(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, validator_list=[validators.isAlphaNumeric], 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, filter_interface=models.HORIZONTAL) 55 objects = DefaultUserManager() 56 57 class Admin: 58 fields = ( 59 (None, {'fields': ('username', 'password')}), 60 (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}), 61 (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}), 62 (_('Important dates'), {'fields': ('last_login', 'date_joined')}), 63 (_('Groups'), {'fields': ('groups',)}), 64 ) 65 list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff') 66 list_filter = ('is_staff', 'is_superuser') 67 search_fields = ('username', 'first_name', 'last_name', 'email') 68 ordering = ('username',) 69 70 def __unicode__(self): 71 return self.username 72 73 def get_absolute_url(self): 74 return "/users/%s/" % urllib.quote(smart_str(self.username)) 75 76 def get_full_name(self): 77 "Returns the first_name plus the last_name, with a space in between." 78 full_name = u'%s %s' % (self.first_name, self.last_name) 79 return full_name.strip() 80 81 def set_password(self, raw_password): 82 import random 83 algo = 'sha1' 84 salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5] 85 hsh = get_hexdigest(algo, salt, raw_password) 86 self.password = '%s$%s$%s' % (algo, salt, hsh) 87 88 def check_password(self, raw_password): 89 """ 90 Returns a boolean of whether the raw_password was correct. Handles 91 encryption formats behind the scenes. 92 """ 93 # Backwards-compatibility check. Older passwords won't include the 94 # algorithm or salt. 95 if '$' not in self.password: 96 is_correct = (self.password == get_hexdigest('md5', '', raw_password)) 97 if is_correct: 98 # Convert the password to the new, more secure format. 99 self.set_password(raw_password) 100 self.save() 101 return is_correct 102 return check_password(raw_password, self.password) 103 104 def set_unusable_password(self): 105 # Sets a value that will never be a valid hash 106 self.password = UNUSABLE_PASSWORD 107 108 def has_usable_password(self): 109 return self.password != UNUSABLE_PASSWORD 110 111 def email_user(self, subject, message, from_email=None): 112 "Sends an e-mail to this User." 113 from django.core.mail import send_mail 114 send_mail(subject, message, from_email, [self.email]) 115 No newline at end of file -
django/contrib/auth/models.py
6 6 from django.contrib.contenttypes.models import ContentType 7 7 from django.utils.encoding import smart_str 8 8 from django.utils.translation import ugettext_lazy as _ 9 from django.conf import settings 9 10 import datetime 10 11 import urllib 11 12 … … 104 105 def __unicode__(self): 105 106 return self.name 106 107 107 class UserManager(models.Manager): 108 def create_user(self, username, email, password=None): 109 "Creates and saves a User with the given username, e-mail and password." 110 now = datetime.datetime.now() 111 user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now) 112 if password: 113 user.set_password(password) 114 else: 115 user.set_unusable_password() 116 user.save() 117 return user 108 class UserTemplate(models.Model): 109 """ Base class from which all User models inherit. """ 118 110 119 def create_superuser(self, username, email, password):120 u = self.create_user(username, email, password)121 u.is_staff = True122 u.is_active = True123 u.is_superuser = True124 u.save()125 126 def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'):127 "Generates a random password with the given length and given allowed_chars"128 # Note that default value of allowed_chars does not have "I" or letters129 # that look like it -- just to avoid confusion.130 from random import choice131 return ''.join([choice(allowed_chars) for i in range(length)])132 133 class User(models.Model):134 """Users within the Django authentication system are represented by this model.135 136 Username and password are required. Other fields are optional.137 """138 username = models.CharField(_('username'), max_length=30, unique=True, validator_list=[validators.isAlphaNumeric], help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."))139 first_name = models.CharField(_('first name'), max_length=30, blank=True)140 last_name = models.CharField(_('last name'), max_length=30, blank=True)141 email = models.EmailField(_('e-mail address'), blank=True)142 password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))143 is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site."))144 is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user should be treated as active. Unselect this instead of deleting accounts."))145 is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them."))146 last_login = models.DateTimeField(_('last login'), default=datetime.datetime.now)147 date_joined = models.DateTimeField(_('date joined'), default=datetime.datetime.now)148 groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True,149 help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."))150 user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True, filter_interface=models.HORIZONTAL)151 objects = UserManager()152 153 111 class Meta: 154 112 verbose_name = _('user') 155 113 verbose_name_plural = _('users') 156 114 157 class Admin:158 fields = (159 (None, {'fields': ('username', 'password')}),160 (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),161 (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}),162 (_('Important dates'), {'fields': ('last_login', 'date_joined')}),163 (_('Groups'), {'fields': ('groups',)}),164 )165 list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')166 list_filter = ('is_staff', 'is_superuser')167 search_fields = ('username', 'first_name', 'last_name', 'email')168 ordering = ('username',)169 170 def __unicode__(self):171 return self.username172 173 def get_absolute_url(self):174 return "/users/%s/" % urllib.quote(smart_str(self.username))175 176 115 def is_anonymous(self): 177 116 "Always returns False. This is a way of comparing User objects to anonymous users." 178 117 return False … … 181 120 """Always return True. This is a way to tell if the user has been authenticated in templates. 182 121 """ 183 122 return True 184 185 def get_full_name(self): 186 "Returns the first_name plus the last_name, with a space in between." 187 full_name = u'%s %s' % (self.first_name, self.last_name) 188 return full_name.strip() 189 190 def set_password(self, raw_password): 191 import random 192 algo = 'sha1' 193 salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5] 194 hsh = get_hexdigest(algo, salt, raw_password) 195 self.password = '%s$%s$%s' % (algo, salt, hsh) 196 197 def check_password(self, raw_password): 198 """ 199 Returns a boolean of whether the raw_password was correct. Handles 200 encryption formats behind the scenes. 201 """ 202 # Backwards-compatibility check. Older passwords won't include the 203 # algorithm or salt. 204 if '$' not in self.password: 205 is_correct = (self.password == get_hexdigest('md5', '', raw_password)) 206 if is_correct: 207 # Convert the password to the new, more secure format. 208 self.set_password(raw_password) 209 self.save() 210 return is_correct 211 return check_password(raw_password, self.password) 212 213 def set_unusable_password(self): 214 # Sets a value that will never be a valid hash 215 self.password = UNUSABLE_PASSWORD 216 217 def has_usable_password(self): 218 return self.password != UNUSABLE_PASSWORD 219 123 220 124 def get_group_permissions(self): 221 125 """ 222 126 Returns a list of permission strings that this user has through … … 288 192 m.delete() 289 193 return messages 290 194 291 def email_user(self, subject, message, from_email=None):292 "Sends an e-mail to this User."293 from django.core.mail import send_mail294 send_mail(subject, message, from_email, [self.email])295 296 195 def get_profile(self): 297 196 """ 298 197 Returns site-specific profile for this user. Raises … … 310 209 raise SiteProfileNotAvailable 311 210 return self._profile_cache 312 211 212 213 # Grab the AUTH_USER_MODULE path and classname from the settings. 214 # auth_user_module_parts[0] = module path 215 # auth_user_module_parts[1] = class name 216 auth_user_module_parts = settings.AUTH_USER_MODULE.rsplit('.', 1) 217 auth_user_module = __import__(auth_user_module_parts[0], {}, {}, [auth_user_module_parts[0]]) 218 # Store the auth_user model so it is accessible with the standard 'from django.contrib.auth.models import User' 219 User = getattr(auth_user_module, auth_user_module_parts[1]) 220 221 # Add the User model to the django models cache 222 # These two lines allow the custom auth_user model to play nicely with syncdb and other systems that rely 223 # on functions like django.db.models.loading.get_model(...) 224 from django.db.models.loading import cache 225 cache.register_models('auth', User) 226 313 227 class Message(models.Model): 314 228 """ 315 229 The message system is a lightweight way to queue messages for given -
docs/authentication.txt
1164 1164 the ``auth_permission`` table most of the time. 1165 1165 1166 1166 .. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py 1167 1168 Overriding the Default Auth User Module 1169 ======================================= 1170 1171 If the default User model doesn't work for you, you can specify your own through 1172 the AUTH_USER_MODULE variable in settings.py. 1173 1174 Simply import ``django.contrib.auth.UserTemplate`` and have your user model inherit 1175 from that. You'll also have to specify your own authentication backend and any 1176 specific manager methods you'll need, such as create_user. -
docs/settings.txt
249 249 250 250 .. _documentation on user profile models: ../authentication/#storing-additional-information-about-users 251 251 252 AUTH_USER_MODULE 253 ---------------- 254 255 Default: ``'django.contrib.auth.default_user.User'`` 256 257 The user model used by this site. See the `documentation on user models`_ for details. 258 259 .. _documentation on user models: ../authentication/#overriding-default-user-model 260 252 261 CACHE_BACKEND 253 262 ------------- 254 263