From 958d2a63cb79b791927ed7545746f94ce1e4b06e Mon Sep 17 00:00:00 2001 From: "Alexis A." Date: Wed, 10 Jul 2024 15:30:32 +0200 Subject: [PATCH 1/4] test(user): add test to make sure user with same email but different casing cannot be created --- users/tests/tests.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 users/tests/tests.py diff --git a/users/tests/tests.py b/users/tests/tests.py new file mode 100644 index 000000000..fec5a1ce8 --- /dev/null +++ b/users/tests/tests.py @@ -0,0 +1,22 @@ +from django.db.utils import IntegrityError +from django.test import TestCase + +from users.models import User + + +class TestUsers(TestCase): + def test_user_with_the_same_email_cannot_be_created(self): + def create_two_users_with_same_email(): + User.objects.create(email="test@gmail.com") + User.objects.create(email="test@gmail.com") + + with self.assertRaises(IntegrityError): + create_two_users_with_same_email() + + def test_user_with_the_same_email_but_different_casing_cannot_be_created(self): + def create_two_users_with_same_email_but_different_casing(): + User.objects.create(email="test@gmail.com") + User.objects.create(email="TEST@gmail.com") + + with self.assertRaises(IntegrityError): + create_two_users_with_same_email_but_different_casing() From ac8c6367287f4e75873bffc21af12dc4fbafea83 Mon Sep 17 00:00:00 2001 From: "Alexis A." Date: Tue, 26 Nov 2024 12:14:35 +0100 Subject: [PATCH 2/4] fix(users): make email unique lower or uppercase --- .../0012_user_user_email_ci_uniqueness.py | 34 +++++++++++++++++++ users/models.py | 8 +++++ 2 files changed, 42 insertions(+) create mode 100644 users/migrations/0012_user_user_email_ci_uniqueness.py diff --git a/users/migrations/0012_user_user_email_ci_uniqueness.py b/users/migrations/0012_user_user_email_ci_uniqueness.py new file mode 100644 index 000000000..616264ca7 --- /dev/null +++ b/users/migrations/0012_user_user_email_ci_uniqueness.py @@ -0,0 +1,34 @@ +# Generated by Django 4.2.13 on 2024-11-26 11:07 + +from django.db import migrations, models +import django.db.models.functions.text +from django.db.utils import IntegrityError + + +def remove_duplicate_emails(apps, schema_editor): + User = apps.get_model("users", "User") + users = User.objects.all() + + for user in users: + user.email = user.email.lower() + try: + user.save() + except IntegrityError: + user.delete() + + +class Migration(migrations.Migration): + atomic = False + dependencies = [ + ("users", "0011_alter_user_organism"), + ] + + operations = [ + migrations.RunPython(remove_duplicate_emails), + migrations.AddConstraint( + model_name="user", + constraint=models.UniqueConstraint( + django.db.models.functions.text.Lower("email"), name="user_email_ci_uniqueness" + ), + ), + ] diff --git a/users/models.py b/users/models.py index e4dc91779..1e5953e2d 100644 --- a/users/models.py +++ b/users/models.py @@ -5,6 +5,8 @@ from django.utils import timezone from utils.validators import is_alpha_validator +from django.db.models.constraints import UniqueConstraint +from django.db.models.functions import Lower from .managers import UserManager @@ -92,3 +94,9 @@ def save(self, *args, **kwargs): class Meta: verbose_name = "Utilisateur" ordering = ["email"] + constraints = [ + UniqueConstraint( + Lower("email"), + name="user_email_ci_uniqueness", + ), + ] From 974b0aebcee8f39074f8db44318cb891ba5fd84d Mon Sep 17 00:00:00 2001 From: "Alexis A." Date: Tue, 26 Nov 2024 12:16:46 +0100 Subject: [PATCH 3/4] chore(models): fix import ordering --- users/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/users/models.py b/users/models.py index 1e5953e2d..055507ea8 100644 --- a/users/models.py +++ b/users/models.py @@ -2,11 +2,11 @@ from django.contrib.auth.models import AbstractUser from django.db import models +from django.db.models.constraints import UniqueConstraint +from django.db.models.functions import Lower from django.utils import timezone from utils.validators import is_alpha_validator -from django.db.models.constraints import UniqueConstraint -from django.db.models.functions import Lower from .managers import UserManager From 693b08f634a8a5351b82fe527a88439250bcd819 Mon Sep 17 00:00:00 2001 From: "Alexis A." Date: Tue, 26 Nov 2024 12:20:09 +0100 Subject: [PATCH 4/4] fix(migrations): merge --- users/migrations/0016_merge_20241126_1219.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 users/migrations/0016_merge_20241126_1219.py diff --git a/users/migrations/0016_merge_20241126_1219.py b/users/migrations/0016_merge_20241126_1219.py new file mode 100644 index 000000000..382c60c41 --- /dev/null +++ b/users/migrations/0016_merge_20241126_1219.py @@ -0,0 +1,12 @@ +# Generated by Django 4.2.13 on 2024-11-26 11:19 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("users", "0012_user_user_email_ci_uniqueness"), + ("users", "0015_auto_20240930_1148"), + ] + + operations = []