diff --git a/allauth/account/tests/test_confirm_email.py b/allauth/account/tests/test_confirm_email.py index 79103b4297..ba295935f7 100644 --- a/allauth/account/tests/test_confirm_email.py +++ b/allauth/account/tests/test_confirm_email.py @@ -2,7 +2,7 @@ from unittest.mock import Mock, patch from django.conf import settings -from django.contrib.auth import get_user_model +from django.contrib.auth import SESSION_KEY, get_user_model from django.core import mail from django.http import HttpResponseRedirect from django.test.client import Client, RequestFactory @@ -362,3 +362,21 @@ def test_confirm_email_with_same_user_logged_in(self): ) self.assertEqual(user, resp.wsgi_request.user) + + +def test_confirm_logs_out_user(auth_client, settings, user, user_factory): + """ + When a user is signed in, and you follow an email confirmation link of + another user within the same browser/session, be sure to sign out the signed + in user. + """ + settings.ACCOUNT_CONFIRM_EMAIL_ON_GET = False + confirming_user = user_factory(email_verified=False) + assert auth_client.session[SESSION_KEY] == str(user.pk) + email = EmailAddress.objects.get(user=confirming_user, verified=False) + auth_client.get( + reverse( + "account_confirm_email", kwargs={"key": EmailConfirmationHMAC(email).key} + ) + ) + assert not auth_client.session.get(SESSION_KEY) diff --git a/allauth/account/views.py b/allauth/account/views.py index 6d25d0dcca..df59171384 100644 --- a/allauth/account/views.py +++ b/allauth/account/views.py @@ -326,6 +326,7 @@ class ConfirmEmailView(TemplateResponseMixin, LogoutFunctionalityMixin, View): def get(self, *args, **kwargs): try: self.object = self.get_object() + self.logout_other_user(self.object) if app_settings.CONFIRM_EMAIL_ON_GET: return self.post(*args, **kwargs) except Http404: @@ -333,6 +334,18 @@ def get(self, *args, **kwargs): ctx = self.get_context_data() return self.render_to_response(ctx) + def logout_other_user(self, confirmation): + """ + In the event someone clicks on an email confirmation link + for one account while logged into another account, + logout of the currently logged in account. + """ + if ( + self.request.user.is_authenticated + and self.request.user.pk != confirmation.email_address.user_id + ): + self.logout() + def post(self, *args, **kwargs): self.object = confirmation = self.get_object() email_address = confirmation.confirm(self.request) @@ -345,14 +358,7 @@ def post(self, *args, **kwargs): ) return self.respond(False) - # In the event someone clicks on an email confirmation link - # for one account while logged into another account, - # logout of the currently logged in account. - if ( - self.request.user.is_authenticated - and self.request.user.pk != confirmation.email_address.user_id - ): - self.logout() + self.logout_other_user(self.object) get_adapter(self.request).add_message( self.request,