Skip to content

allauth ACCOUNT_UNIQUE_EMAIL doesn't work as expected #617

@dontic

Description

@dontic

There is an edge case when using email as the authentication method as well as email verification. The server will crash if the user hasn't verified the email but a new registration with that same email is tried.

Steps to reproduce:

  1. Set the following allauth settings
ACCOUNT_AUTHENTICATION_METHOD = "email"  # username, email or username_email
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_EMAIL_REQUIRED = True  # Needs to be True to use email as the auth method
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"  # "none", "optional", "mandatory"
  1. Register a new email
  2. Try to register the same email without first validating it

Analysis

I found that this edge case is not handled in the serializer:

def validate_email(self, email):
    email = get_adapter().clean_email(email)
    if allauth_account_settings.UNIQUE_EMAIL:
        if email and EmailAddress.objects.is_verified(email):
            raise serializers.ValidationError(
                _("A user is already registered with this e-mail address."),
            )
    return email

The validation error for unique email is only raised if the account has been verified.

Here's the proposed fix in #618:

def validate_email(self, email):
    email = get_adapter().clean_email(email)
    if allauth_account_settings.UNIQUE_EMAIL:
        if email and EmailAddress.objects.is_verified(email):
            raise serializers.ValidationError(
                _("A user is already registered with this e-mail address."),
            )
        else:
            query = EmailAddress.objects.filter(email__iexact=email)
            if query.exists():
                email_address = query.first()
                if email_address.user.has_usable_password():
                    raise serializers.ValidationError(
                        _("A user is already registered with this e-mail address but hasn't been verified their email yet."),
                    )
    return email

Note that in the meantime users can implement this fix by creating a custom RegisterSerializer as explained in the docs.

The wording is not the best and can be changed.

Tested and working:

image

Opened #618

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions