Ticket #3011: 3011.7.diff
File 3011.7.diff, 18.1 KB (added by , 16 years ago) |
---|
-
django/conf/global_settings.py
a b LOGIN_REDIRECT_URL = '/accounts/profile/' 375 375 # The number of days a password reset link is valid for 376 376 PASSWORD_RESET_TIMEOUT_DAYS = 3 377 377 378 # The class to use as the default AUTH_USER for the authentication system. 379 AUTH_USER_MODULE = 'django.contrib.auth.user_model.User' 380 381 # Trigger superuser creation after syncdb 382 AUTH_AUTO_CREATE_SUPERUSER = True 383 384 # Trigger permissions creation after syncdb 385 AUTH_AUTO_CREATE_PERMISSIONS = True 386 378 387 ########### 379 388 # TESTING # 380 389 ########### -
django/contrib/auth/admin.py
a b 1 1 2 from django.contrib.auth.models import User, Group2 from django.contrib.auth.models import Permission, User, Group, Message 3 3 from django.core.exceptions import PermissionDenied 4 4 from django import template 5 5 from django.shortcuts import render_to_response, get_object_or_404 … … from django.http import HttpResponseRedirect 9 9 from django.utils.translation import ugettext, ugettext_lazy as _ 10 10 from django.contrib.auth.forms import UserCreationForm, UserChangeForm, AdminPasswordChangeForm 11 11 from django.contrib import admin 12 from django.conf import settings, global_settings 12 13 13 14 class GroupAdmin(admin.ModelAdmin): 14 15 search_fields = ('name',) … … class UserAdmin(admin.ModelAdmin): 108 111 'root_path': self.admin_site.root_path, 109 112 }, context_instance=RequestContext(request)) 110 113 111 112 114 admin.site.register(Group, GroupAdmin) 113 admin.site.register(User, UserAdmin) 115 if settings.AUTH_USER_MODULE == global_settings.AUTH_USER_MODULE: 116 admin.site.register(User, UserAdmin) 114 117 -
django/contrib/auth/management/__init__.py
diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index 01fa524..15abbec 100644
a b Creates permissions for all installed apps that need permissions. 4 4 5 5 from django.db.models import get_models, signals 6 6 from django.contrib.auth import models as auth_app 7 from django.conf import settings 7 8 8 9 def _get_permission_codename(action, opts): 9 10 return u'%s_%s' % (action, opts.object_name.lower()) … … def create_superuser(app, created_models, verbosity, **kwargs): 44 45 call_command("createsuperuser", interactive=True) 45 46 break 46 47 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") 48 if settings.AUTH_AUTO_CREATE_PERMISSIONS: 49 signals.post_syncdb.connect(create_permissions, 50 dispatch_uid = "django.contrib.auth.management.create_permissions") 51 if settings.AUTH_AUTO_CREATE_SUPERUSER: 52 signals.post_syncdb.connect(create_superuser, 53 sender=auth_app, dispatch_uid = "django.contrib.auth.management.create_superuser") -
django/contrib/auth/models.py
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 4d3189b..57b36ba 100644
a b from django.db.models.manager import EmptyManager 5 5 from django.contrib.contenttypes.models import ContentType 6 6 from django.utils.encoding import smart_str 7 7 from django.utils.translation import ugettext_lazy as _ 8 from django.conf import settings, global_settings 8 9 import datetime 9 10 import urllib 10 11 … … class Group(models.Model): 102 103 def __unicode__(self): 103 104 return self.name 104 105 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() 106 class UserTemplate(models.Model): 107 """ Base class from which all User models inherit. """ 150 108 151 109 class Meta: 110 abstract = True 111 app_label = "auth" 152 112 verbose_name = _('user') 153 113 verbose_name_plural = _('users') 154 114 155 def __unicode__(self):156 return self.username157 158 def get_absolute_url(self):159 return "/users/%s/" % urllib.quote(smart_str(self.username))160 161 115 def is_anonymous(self): 162 116 "Always returns False. This is a way of comparing User objects to anonymous users." 163 117 return False … … class User(models.Model): 167 121 """ 168 122 return True 169 123 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 random177 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. Handles185 encryption formats behind the scenes.186 """187 # Backwards-compatibility check. Older passwords won't include the188 # 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_correct196 return check_password(raw_password, self.password)197 198 def set_unusable_password(self):199 # Sets a value that will never be a valid hash200 self.password = UNUSABLE_PASSWORD201 202 def has_usable_password(self):203 return self.password != UNUSABLE_PASSWORD204 205 124 def get_group_permissions(self): 206 125 """ 207 126 Returns a list of permission strings that this user has through … … class User(models.Model): 273 192 m.delete() 274 193 return messages 275 194 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_mail279 send_mail(subject, message, from_email, [self.email])280 281 195 def get_profile(self): 282 196 """ 283 197 Returns site-specific profile for this user. Raises … … class User(models.Model): 295 209 raise SiteProfileNotAvailable 296 210 return self._profile_cache 297 211 212 # Implement the User model according to settings 213 from django.db.models import import_model 214 User = 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 298 229 class Message(models.Model): 299 230 """ 300 231 The message system is a lightweight way to queue messages for given -
django/contrib/auth/tests/basic.py
diff --git a/django/contrib/auth/tests/basic.py b/django/contrib/auth/tests/basic.py index 2071710..d7b32ef 100644
a b 1 1 2 2 BASIC_TESTS = """ 3 >>> from django.contrib.auth.models import User 4 >>> User._meta.app_label 5 'auth' 6 >>> User._meta.object_name 7 'User' 8 3 9 >>> from django.contrib.auth.models import User, AnonymousUser 4 10 >>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw') 5 11 >>> u.has_usable_password() -
new file django/contrib/auth/user_model.py
diff --git a/django/contrib/auth/user_model.py b/django/contrib/auth/user_model.py new file mode 100644 index 0000000..76b821b
- + 1 from django.db import models 2 from django.utils.translation import gettext_lazy as _ 3 4 from django.contrib.auth.models import Group, Permission, UserTemplate, get_hexdigest, check_password, UNUSABLE_PASSWORD 5 6 import datetime, urllib 7 8 9 class 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 37 class 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]) 105 No newline at end of file -
django/db/models/__init__.py
diff --git a/django/db/models/__init__.py b/django/db/models/__init__.py index 5413133..9a39cb1 100644
a b 1 1 from django.conf import settings 2 2 from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured 3 3 from django.db import connection 4 from django.db.models.loading import get_apps, get_app, get_models, get_model, register_models 4 from django.db.models.loading import get_apps, get_app, get_models, get_model, register_models, import_model 5 5 from django.db.models.query import Q 6 6 from django.db.models.manager import Manager 7 7 from django.db.models.base import Model -
django/db/models/loading.py
diff --git a/django/db/models/loading.py b/django/db/models/loading.py index 6837e07..bcb5d26 100644
a b import sys 8 8 import os 9 9 import threading 10 10 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', 12 12 'load_app', 'app_cache_ready') 13 13 14 14 class AppCache(object):