Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

email uniqueness is done with case-sensitivity on some databases #11

Open
gavinwahl opened this issue Sep 23, 2013 · 8 comments
Open

email uniqueness is done with case-sensitivity on some databases #11

gavinwahl opened this issue Sep 23, 2013 · 8 comments

Comments

@gavinwahl
Copy link
Member

Postgres performs string comparison case-sensitively, mysql does it case-insensitive. This means that on postgres, foo@example.com, FOO@example.com and foo@EXAMPLE.com are all distinct emails, and a user could register with each one.

Domain names are not case sensitive, so at least the domain part should lowercased. The local part of an email address is technically case sensitive, but I don't think it is in practice.

The easiest way to accomplish this would be to lowercase email addresses before storing them, but it might be wrong to mangle addresses like that.

@gavinwahl
Copy link
Member Author

A functional index on UPPER(email) would be the ideal solution on postgres, but we'd have to use email__iexact everywhere, and lookups by email wouldn't be indexed at all on mysql.

@pipermerriam
Copy link

Maybe we could do get by with just dbindex=True and do our normalization outside of the database. Something similar to what BaseManager does here

Is there a problem just calling .lower() or .upper() on the address part of the email?

@rockymeza
Copy link
Contributor

@chris-erickson
Copy link

This is a bit of a trouble spot for users entering emails in interesting ways. 👍 for any fix..

@aidanlister
Copy link

#31 won't work for anyone on Postgres.

It simply does a .lower() on the incoming login, but not the database User.get operation. So if there's a capitalised email in the database it's impossible to login.

@aidanlister
Copy link

aidanlister commented Sep 17, 2018

Here's a better way:

class AccountManager(models.Manager):
    def get_by_natural_key(self, username):
        field_name = f'{self.model.USERNAME_FIELD}__iexact'
        return self.get(**{field_name: username})

Set this on your custom user model.

@gavinwahl
Copy link
Member Author

Isn't that handled by CaseInsensitiveEmailBackendMixin?

@pawl-bb
Copy link

pawl-bb commented Jan 14, 2020

Django-improved-user argues that it's better to store the e-mail addresses in a case sensitive field and use case-insensitive queries to filter for a match: https://django-improved-user.readthedocs.io/en/latest/email_warning.html

@aidanlister's example seems to cover that, but he might also need to have an index on lower(email::text) to prevent duplicates? Without the unique index, another user might be able to create an uppercase version of an existing e-mail and have it match.

Although the first part of the e-mail is supposed to be case sensitive (according to RFC 5321), I don't know of any e-mail providers that actually do that. So maybe it doesn't matter?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants