mirror of https://github.com/zulip/zulip.git
migrations: Register (UPPER(email), realm) indexes in UserProfile.Meta.
It's nicer to have these indexes properly registered, rather than hidden in RunSQL operations. Now that Django has had support for unique functional indexes for a while, let's clean this up.
This commit is contained in:
parent
a8217aee36
commit
e655a7b251
|
@ -3312,6 +3312,23 @@ class Migration(migrations.Migration):
|
|||
name="zerver_userpresence_realm_last_update_id_idx",
|
||||
),
|
||||
),
|
||||
# Ensure users have unique email addresses, case-insensitive, within their realm.
|
||||
migrations.AddConstraint(
|
||||
model_name="userprofile",
|
||||
constraint=models.UniqueConstraint(
|
||||
models.F("realm"),
|
||||
django.db.models.functions.text.Upper(models.F("email")),
|
||||
name="zerver_userprofile_realm_id_email_uniq",
|
||||
),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name="userprofile",
|
||||
constraint=models.UniqueConstraint(
|
||||
models.F("realm"),
|
||||
django.db.models.functions.text.Upper(models.F("delivery_email")),
|
||||
name="zerver_userprofile_realm_id_delivery_email_uniq",
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="usertopic",
|
||||
index=models.Index(
|
||||
|
@ -3403,13 +3420,6 @@ class Migration(migrations.Migration):
|
|||
CREATE UNIQUE INDEX zerver_stream_realm_id_name_uniq ON zerver_stream (realm_id, upper(name::text));
|
||||
"""
|
||||
),
|
||||
# Ensure users have unique email addresses, case-insensitive, within their realm.
|
||||
migrations.RunSQL(
|
||||
"""
|
||||
CREATE UNIQUE INDEX zerver_userprofile_realm_id_email_uniq ON zerver_userprofile (realm_id, upper(email::text));
|
||||
CREATE UNIQUE INDEX zerver_userprofile_realm_id_delivery_email_uniq ON zerver_userprofile (realm_id, upper(delivery_email::text));
|
||||
"""
|
||||
),
|
||||
# Set up full-text search indexes.
|
||||
migrations.RunSQL(
|
||||
sql=get_fts_sql(),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.db import migrations
|
||||
from django.db import migrations, models
|
||||
from django.db.models.functions import Upper
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -7,24 +8,21 @@ class Migration(migrations.Migration):
|
|||
]
|
||||
|
||||
operations = [
|
||||
# Zulip has always had case-insensitive matching for email
|
||||
# addresses on UserProfile objects. But Django's
|
||||
# unique_together feature only supports case-sensitive
|
||||
# indexes. So we reply the old unique_together index with a
|
||||
# new case-insensitive index.
|
||||
#
|
||||
# Further, when we created the delivery_email field, we
|
||||
# neglected to create a unique index on (realm_id,
|
||||
# delivery_email), which meant race conditions or logic bugs
|
||||
# could allow duplicate user accounts being created in
|
||||
# organizations with EMAIL_ADDRESS_VISIBILITY_ADMINS. We
|
||||
# correct this by adding the appropriate unique index there as
|
||||
# well.
|
||||
migrations.RunSQL(
|
||||
"""
|
||||
CREATE UNIQUE INDEX zerver_userprofile_realm_id_email_uniq ON zerver_userprofile (realm_id, upper(email::text));
|
||||
CREATE UNIQUE INDEX zerver_userprofile_realm_id_delivery_email_uniq ON zerver_userprofile (realm_id, upper(delivery_email::text));
|
||||
"""
|
||||
migrations.AddConstraint(
|
||||
model_name="userprofile",
|
||||
constraint=models.UniqueConstraint(
|
||||
models.F("realm"),
|
||||
Upper(models.F("email")),
|
||||
name="zerver_userprofile_realm_id_email_uniq",
|
||||
),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name="userprofile",
|
||||
constraint=models.UniqueConstraint(
|
||||
models.F("realm"),
|
||||
Upper(models.F("delivery_email")),
|
||||
name="zerver_userprofile_realm_id_delivery_email_uniq",
|
||||
),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name="userprofile",
|
||||
|
|
|
@ -5,7 +5,7 @@ from uuid import uuid4
|
|||
from django.conf import settings
|
||||
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, UserManager
|
||||
from django.db import models
|
||||
from django.db.models import CASCADE, Q, QuerySet
|
||||
from django.db.models import CASCADE, F, Q, QuerySet
|
||||
from django.db.models.functions import Upper
|
||||
from django.db.models.signals import post_save
|
||||
from django.utils.timezone import now as timezone_now
|
||||
|
@ -617,6 +617,18 @@ class UserProfile(AbstractBaseUser, PermissionsMixin, UserBaseSettings):
|
|||
ROLE_API_NAME_TO_ID = {v: k for k, v in ROLE_ID_TO_API_NAME.items()}
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
"realm",
|
||||
Upper(F("email")),
|
||||
name="zerver_userprofile_realm_id_email_uniq",
|
||||
),
|
||||
models.UniqueConstraint(
|
||||
"realm",
|
||||
Upper(F("delivery_email")),
|
||||
name="zerver_userprofile_realm_id_delivery_email_uniq",
|
||||
),
|
||||
]
|
||||
indexes = [
|
||||
models.Index(Upper("email"), name="upper_userprofile_email_idx"),
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue