Patchwork Make sure Person.email is really unique by lower casing it

login
register
mail settings
Submitter Guilherme Salgado
Date May 6, 2011, 5:55 p.m.
Message ID <20110506175444.29392.98017.stgit@localhost6.localdomain6>
Download mbox | patch
Permalink /patch/94419/
State Superseded
Headers show

Comments

Guilherme Salgado - May 6, 2011, 5:55 p.m.
Currently it's possible to have two semantically identical email addresses in
the DB by varying the case of one or more letters between them. This patch
fixes it by changing Person.save() to always lower case the email address
before it is inserted into the DB.
---
 apps/patchwork/models.py       |    6 ++++++
 apps/patchwork/tests/models.py |   13 +++++++++++--
 2 files changed, 17 insertions(+), 2 deletions(-)

Patch

diff --git a/apps/patchwork/models.py b/apps/patchwork/models.py
index cfead27..8c5188f 100644
--- a/apps/patchwork/models.py
+++ b/apps/patchwork/models.py
@@ -45,6 +45,12 @@  class Person(models.Model):
     name = models.CharField(max_length=255, null = True, blank = True)
     user = models.ForeignKey(User, null = True, blank = True)
 
+    def save(self):
+        # Convert to lower case to avoid identical emails with case variations
+        # from being inserted in the DB.
+        self.email = self.email.lower()
+        super(Person, self).save()
+
     def __unicode__(self):
         if self.name:
             return u'%s <%s>' % (self.name, self.email)
diff --git a/apps/patchwork/tests/models.py b/apps/patchwork/tests/models.py
index 91bfb9d..bb26270 100644
--- a/apps/patchwork/tests/models.py
+++ b/apps/patchwork/tests/models.py
@@ -1,7 +1,8 @@ 
 
-from django.test import TestCase
+from django.db.utils import IntegrityError
+from django.test import TestCase, TransactionTestCase
 
-from patchwork.models import State
+from patchwork.models import Person, State
 from patchwork.tests.factory import factory
 
 
@@ -40,3 +41,11 @@  class UserProfileTestCase(TestCase):
         # profile.
         patches = profile.submitted_patches_waiting_feedback(patch1.project)
         self.assertEquals([patch1, patch2], list(patches))
+
+
+class PersonTestCase(TestCase):
+
+    def test_email_uniqueness_is_case_insensitive(self):
+        Person(email='foo.bar@example.com').save()
+        p2 = Person(email='Foo.Bar@example.com')
+        self.assertRaises(IntegrityError, p2.save)