diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py index 9fd75d06d..65334c682 100644 --- a/ietf/ietfauth/tests.py +++ b/ietf/ietfauth/tests.py @@ -381,6 +381,21 @@ class IetfAuthTests(TestCase): self.assertEqual(len(updated_roles), 1) self.assertEqual(updated_roles[0].email_id, new_email_address) + def test_email_case_insensitive_protection(self): + EmailFactory(address="TestAddress@example.net") + person = PersonFactory() + url = urlreverse(ietf.ietfauth.views.profile) + login_testing_unauthorized(self, person.user.username, url) + + data = { + "name": person.name, + "plain": person.plain, + "ascii": person.ascii, + "active_emails": [e.address for e in person.email_set.filter(active=True)], + "new_email": "testaddress@example.net", + } + r = self.client.post(url, data) + self.assertContains(r, "Email address 'TestAddress@example.net' is already assigned", status_code=200) def test_nomcom_dressing_on_profile(self): url = urlreverse('ietf.ietfauth.views.profile') diff --git a/ietf/person/migrations/0030_ci_email.py b/ietf/person/migrations/0030_ci_email.py new file mode 100644 index 000000000..3a444988b --- /dev/null +++ b/ietf/person/migrations/0030_ci_email.py @@ -0,0 +1,27 @@ +# Generated by Django 2.2.28 on 2023-01-26 19:45 + +import django.contrib.postgres.fields.citext +from django.contrib.postgres.operations import CITextExtension +import django.core.validators +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('person', '0029_use_timezone_now_for_person_models'), + ] + + operations = [ + CITextExtension(), + migrations.AlterField( + model_name='email', + name='address', + field=django.contrib.postgres.fields.citext.CICharField(max_length=64, primary_key=True, serialize=False, validators=[django.core.validators.EmailValidator()]), + ), + migrations.AlterField( + model_name='historicalemail', + name='address', + field=django.contrib.postgres.fields.citext.CICharField(db_index=True, max_length=64, validators=[django.core.validators.EmailValidator()]), + ), + ] diff --git a/ietf/person/models.py b/ietf/person/models.py index a7e30b2de..02cee4d67 100644 --- a/ietf/person/models.py +++ b/ietf/person/models.py @@ -12,6 +12,7 @@ from urllib.parse import urljoin from django.conf import settings from django.contrib.auth.models import User +from django.contrib.postgres.fields import CICharField from django.core.exceptions import ValidationError from django.core.validators import validate_email from django.db import models @@ -277,7 +278,7 @@ class Alias(models.Model): class Email(models.Model): history = HistoricalRecords() - address = models.CharField(max_length=64, primary_key=True, validators=[validate_email]) + address = CICharField(max_length=64, primary_key=True, validators=[validate_email]) person = ForeignKey(Person, null=True) time = models.DateTimeField(auto_now_add=True) primary = models.BooleanField(default=False) diff --git a/ietf/settings_postgrestest.py b/ietf/settings_postgrestest.py index e6f53f09a..450fd9180 100755 --- a/ietf/settings_postgrestest.py +++ b/ietf/settings_postgrestest.py @@ -37,7 +37,7 @@ MIGRATION_MODULES = DisableMigrations() DATABASES = { 'default': { 'HOST': 'db', - 'PORT': 5432, + 'PORT': '5432', 'NAME': 'test.db', 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'USER': 'django',