diff --git a/api/users/views.py b/api/users/views.py index d4718a53e86..6387bcbcea9 100644 --- a/api/users/views.py +++ b/api/users/views.py @@ -2,6 +2,7 @@ from urllib.parse import urlencode from django.apps import apps +from django.db import IntegrityError from django.db.models import F from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_protect @@ -1146,7 +1147,12 @@ def post(self, request, *args, **kwargs): if not user.is_registered: user.register(email) - user.emails.get_or_create(address=email.lower()) + if not user.emails.filter(address=email.lower()).exists(): + try: + user.emails.create(address=email.lower()) + except IntegrityError: + raise ValidationError('Email address already exists.') + user.date_last_logged_in = timezone.now() del user.email_verifications[token] diff --git a/api_tests/users/views/test_user_confirm.py b/api_tests/users/views/test_user_confirm.py index fe4948d63da..0cb4b7606a2 100644 --- a/api_tests/users/views/test_user_confirm.py +++ b/api_tests/users/views/test_user_confirm.py @@ -199,3 +199,31 @@ def test_post_success_link_with_email_verification_none( user.reload() assert not user.external_identity + + @mock.patch('website.mails.send_mail') + def test_post_success_link_with_email_already_exists( + self, + mock_send_mail, + app, + confirm_url, + user_with_email_verification + ): + user, token, email = user_with_email_verification + AuthUserFactory(username=email) # User with already existing email + user.save() + + res = app.post_json_api( + confirm_url, + { + 'data': { + 'attributes': { + 'uid': user._id, + 'token': token, + 'destination': 'doesnotmatter' + } + } + }, + expect_errors=True + ) + assert res.status_code == 400 + assert res.json['errors'][0] == {'detail': 'Email address already exists.'}