Fixed #17504 -- Fixed normalization of email addresses that have '@' in the name when calling `User.objects.create_user`. Thanks, marw85.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17482 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2012-02-09 18:58:53 +00:00
parent ec5e2f0ccc
commit 875a5ea8d4
3 changed files with 50 additions and 16 deletions

View File

@ -128,25 +128,31 @@ class Group(models.Model):
class UserManager(models.Manager): class UserManager(models.Manager):
@classmethod
def normalize_email(cls, email):
"""
Normalize the address by lowercasing the domain part of the email
address.
"""
email = email or ''
try:
email_name, domain_part = email.strip().rsplit('@', 1)
except ValueError:
pass
else:
email = '@'.join([email_name, domain_part.lower()])
return email
def create_user(self, username, email=None, password=None): def create_user(self, username, email=None, password=None):
""" """
Creates and saves a User with the given username, email and password. Creates and saves a User with the given username, email and password.
""" """
now = timezone.now() now = timezone.now()
email = UserManager.normalize_email(email)
# Normalize the address by lowercasing the domain part of the email user = self.model(username=username, email=email,
# address. is_staff=False, is_active=True, is_superuser=False,
email = email or '' last_login=now, date_joined=now)
try:
email_name, domain_part = email.strip().split('@', 1)
except ValueError:
pass
else:
email = '@'.join([email_name, domain_part.lower()])
user = self.model(username=username, email=email, is_staff=False,
is_active=True, is_superuser=False, last_login=now,
date_joined=now)
user.set_password(password) user.set_password(password)
user.save(using=self._db) user.save(using=self._db)

View File

@ -11,7 +11,8 @@ from django.contrib.auth.tests.remote_user import (RemoteUserTest,
RemoteUserNoCreateTest, RemoteUserCustomTest) RemoteUserNoCreateTest, RemoteUserCustomTest)
from django.contrib.auth.tests.management import GetDefaultUsernameTestCase from django.contrib.auth.tests.management import GetDefaultUsernameTestCase
from django.contrib.auth.tests.models import (ProfileTestCase, NaturalKeysTestCase, from django.contrib.auth.tests.models import (ProfileTestCase, NaturalKeysTestCase,
LoadDataWithoutNaturalKeysTestCase, LoadDataWithNaturalKeysTestCase) LoadDataWithoutNaturalKeysTestCase, LoadDataWithNaturalKeysTestCase,
UserManagerTestCase)
from django.contrib.auth.tests.hashers import TestUtilsHashPass from django.contrib.auth.tests.hashers import TestUtilsHashPass
from django.contrib.auth.tests.signals import SignalTestCase from django.contrib.auth.tests.signals import SignalTestCase
from django.contrib.auth.tests.tokens import TokenGeneratorTest from django.contrib.auth.tests.tokens import TokenGeneratorTest

View File

@ -1,9 +1,12 @@
from django.conf import settings from django.conf import settings
from django.test import TestCase from django.test import TestCase
from django.contrib.auth.models import Group, User, SiteProfileNotAvailable from django.contrib.auth.models import (Group, User,
SiteProfileNotAvailable, UserManager)
class ProfileTestCase(TestCase): class ProfileTestCase(TestCase):
fixtures = ['authtestdata.json'] fixtures = ['authtestdata.json']
def setUp(self): def setUp(self):
"""Backs up the AUTH_PROFILE_MODULE""" """Backs up the AUTH_PROFILE_MODULE"""
self.old_AUTH_PROFILE_MODULE = getattr(settings, self.old_AUTH_PROFILE_MODULE = getattr(settings,
@ -59,8 +62,32 @@ class LoadDataWithoutNaturalKeysTestCase(TestCase):
class LoadDataWithNaturalKeysTestCase(TestCase): class LoadDataWithNaturalKeysTestCase(TestCase):
fixtures = ['natural.json'] fixtures = ['natural.json']
def test_user_is_created_and_added_to_group(self): def test_user_is_created_and_added_to_group(self):
user = User.objects.get(username='my_username') user = User.objects.get(username='my_username')
group = Group.objects.get(name='my_group') group = Group.objects.get(name='my_group')
self.assertEquals(group, user.groups.get()) self.assertEquals(group, user.groups.get())
class UserManagerTestCase(TestCase):
def test_create_user(self):
email_lowercase = 'normal@normal.com'
user = User.objects.create_user('user', email_lowercase)
self.assertEquals(user.email, email_lowercase)
self.assertEquals(user.username, 'user')
self.assertEquals(user.password, '!')
def test_create_user_email_domain_normalize_rfc3696(self):
# According to http://tools.ietf.org/html/rfc3696#section-3
# the "@" symbol can be part of the local part of an email address
returned = UserManager.normalize_email(r'Abc\@DEF@EXAMPLE.com')
self.assertEquals(returned, r'Abc\@DEF@example.com')
def test_create_user_email_domain_normalize(self):
returned = UserManager.normalize_email('normal@DOMAIN.COM')
self.assertEquals(returned, 'normal@domain.com')
def test_create_user_email_domain_normalize_with_whitespace(self):
returned = UserManager.normalize_email('email\ with_whitespace@D.COM')
self.assertEquals(returned, 'email\ with_whitespace@d.com')