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

Submitted by Guilherme Salgado on May 6, 2011, 5:55 p.m.

Details

Message ID 20110506175444.29392.98017.stgit@localhost6.localdomain6
State Superseded
Headers show

Commit Message

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 hide | download patch | download mbox

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)