Fixed #13969 -- Extended length of salt used when setting the password. Thanks to cyounkins for the initial patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16453 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c159374a33
commit
650739ef17
|
@ -1,10 +1,12 @@
|
||||||
import datetime
|
import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import random
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.contrib.auth.signals import user_logged_in
|
from django.contrib.auth.signals import user_logged_in
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.core.mail import send_mail
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.manager import EmptyManager
|
from django.db.models.manager import EmptyManager
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
@ -34,6 +36,21 @@ def get_hexdigest(algorithm, salt, raw_password):
|
||||||
return hashlib.sha1(salt + raw_password).hexdigest()
|
return hashlib.sha1(salt + raw_password).hexdigest()
|
||||||
raise ValueError("Got unknown password algorithm type in password.")
|
raise ValueError("Got unknown password algorithm type in password.")
|
||||||
|
|
||||||
|
def get_random_string(length=12, allowed_chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
|
||||||
|
"""
|
||||||
|
Returns a random string of length characters from the set of a-z, A-Z, 0-9
|
||||||
|
for use as a salt.
|
||||||
|
|
||||||
|
The default length of 12 with the a-z, A-Z, 0-9 character set returns
|
||||||
|
a 71-bit salt. log_2((26+26+10)^12) =~ 71 bits
|
||||||
|
"""
|
||||||
|
import random
|
||||||
|
try:
|
||||||
|
random = random.SystemRandom()
|
||||||
|
except NotImplementedError:
|
||||||
|
pass
|
||||||
|
return ''.join([random.choice(allowed_chars) for i in range(length)])
|
||||||
|
|
||||||
def check_password(raw_password, enc_password):
|
def check_password(raw_password, enc_password):
|
||||||
"""
|
"""
|
||||||
Returns a boolean of whether the raw_password was correct. Handles
|
Returns a boolean of whether the raw_password was correct. Handles
|
||||||
|
@ -145,11 +162,13 @@ class UserManager(models.Manager):
|
||||||
return u
|
return u
|
||||||
|
|
||||||
def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'):
|
def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'):
|
||||||
"Generates a random password with the given length and given allowed_chars"
|
"""
|
||||||
|
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
|
# Note that default value of allowed_chars does not have "I" or letters
|
||||||
# that look like it -- just to avoid confusion.
|
# that look like it -- just to avoid confusion.
|
||||||
from random import choice
|
return get_random_string(length, allowed_chars)
|
||||||
return ''.join([choice(allowed_chars) for i in range(length)])
|
|
||||||
|
|
||||||
|
|
||||||
# A few helper functions for common logic between User and AnonymousUser.
|
# A few helper functions for common logic between User and AnonymousUser.
|
||||||
|
@ -244,7 +263,9 @@ class User(models.Model):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_full_name(self):
|
def get_full_name(self):
|
||||||
"Returns the first_name plus the last_name, with a space in between."
|
"""
|
||||||
|
Returns the first_name plus the last_name, with a space in between.
|
||||||
|
"""
|
||||||
full_name = u'%s %s' % (self.first_name, self.last_name)
|
full_name = u'%s %s' % (self.first_name, self.last_name)
|
||||||
return full_name.strip()
|
return full_name.strip()
|
||||||
|
|
||||||
|
@ -252,9 +273,8 @@ class User(models.Model):
|
||||||
if raw_password is None:
|
if raw_password is None:
|
||||||
self.set_unusable_password()
|
self.set_unusable_password()
|
||||||
else:
|
else:
|
||||||
import random
|
|
||||||
algo = 'sha1'
|
algo = 'sha1'
|
||||||
salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
|
salt = get_random_string()
|
||||||
hsh = get_hexdigest(algo, salt, raw_password)
|
hsh = get_hexdigest(algo, salt, raw_password)
|
||||||
self.password = '%s$%s$%s' % (algo, salt, hsh)
|
self.password = '%s$%s$%s' % (algo, salt, hsh)
|
||||||
|
|
||||||
|
@ -346,8 +366,9 @@ class User(models.Model):
|
||||||
return _user_has_module_perms(self, app_label)
|
return _user_has_module_perms(self, app_label)
|
||||||
|
|
||||||
def email_user(self, subject, message, from_email=None):
|
def email_user(self, subject, message, from_email=None):
|
||||||
"Sends an email to this User."
|
"""
|
||||||
from django.core.mail import send_mail
|
Sends an email to this User.
|
||||||
|
"""
|
||||||
send_mail(subject, message, from_email, [self.email])
|
send_mail(subject, message, from_email, [self.email])
|
||||||
|
|
||||||
def get_profile(self):
|
def get_profile(self):
|
||||||
|
|
Loading…
Reference in New Issue