diff options
| -rw-r--r-- | django/contrib/auth/__init__.py | 18 | ||||
| -rw-r--r-- | docs/releases/6.0.4.txt | 5 | ||||
| -rw-r--r-- | tests/auth_tests/test_middleware.py | 31 |
3 files changed, 48 insertions, 6 deletions
diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py index 1119ef4f91..db08bdff13 100644 --- a/django/contrib/auth/__init__.py +++ b/django/contrib/auth/__init__.py @@ -234,6 +234,8 @@ async def alogin(request, user, backend=None): await request.session.aset(SESSION_KEY, user._meta.pk.value_to_string(user)) await request.session.aset(BACKEND_SESSION_KEY, backend) await request.session.aset(HASH_SESSION_KEY, session_auth_hash) + if hasattr(request, "user"): + request.user = user if hasattr(request, "auser"): async def auser(): @@ -273,13 +275,21 @@ async def alogout(request): user = None await user_logged_out.asend(sender=user.__class__, request=request, user=user) await request.session.aflush() - if hasattr(request, "auser"): + + has_user = hasattr(request, "user") + has_auser = hasattr(request, "auser") + if has_user or has_auser: from django.contrib.auth.models import AnonymousUser - async def auser(): - return AnonymousUser() + anon = AnonymousUser() + if has_user: + request.user = anon + if has_auser: - request.auser = auser + async def auser(): + return anon + + request.auser = auser def get_user_model(): diff --git a/docs/releases/6.0.4.txt b/docs/releases/6.0.4.txt index a32a49dc93..e24397d9bc 100644 --- a/docs/releases/6.0.4.txt +++ b/docs/releases/6.0.4.txt @@ -10,4 +10,7 @@ issues with severity "low", and several bugs in 6.0.3. Bugfixes ======== -* ... +* Fixed a regression in Django 6.0 where :func:`~django.contrib.auth.alogin` + and :func:`~django.contrib.auth.alogout` did not respectively set or clear + ``request.user`` if it had already been materialized (e.g., by sync + middleware) (:ticket:`37017`). diff --git a/tests/auth_tests/test_middleware.py b/tests/auth_tests/test_middleware.py index 5e106d40f7..894b49548b 100644 --- a/tests/auth_tests/test_middleware.py +++ b/tests/auth_tests/test_middleware.py @@ -4,7 +4,7 @@ from django.contrib.auth.middleware import ( AuthenticationMiddleware, LoginRequiredMiddleware, ) -from django.contrib.auth.models import User +from django.contrib.auth.models import AnonymousUser, User from django.core.exceptions import ImproperlyConfigured from django.http import HttpRequest, HttpResponse from django.test import TestCase, modify_settings, override_settings @@ -77,6 +77,35 @@ class TestAuthenticationMiddleware(TestCase): self.assertTrue(auser_second.is_anonymous) +class TestAsyncLoginLogoutAfterSyncMiddleware(TestCase): + @classmethod + def setUpTestData(cls): + cls.user = User.objects.create_user( + "test_user", "test@example.com", "test_password" + ) + cls.user2 = User.objects.create_user( + "test_user2", "test2@example.com", "test_password2" + ) + + def setUp(self): + self.middleware = AuthenticationMiddleware(lambda req: HttpResponse()) + self.client.force_login(self.user) + self.request = HttpRequest() + self.request.session = self.client.session + # Populate self.request.user. + self.middleware(self.request) + # .user is lazy, so materialize it by accessing an attribute. + self.request.user.is_authenticated + + async def test_user_after_alogin(self): + await alogin(self.request, self.user2) + self.assertEqual(self.request.user, self.user2) + + async def test_user_after_alogout(self): + await alogout(self.request) + self.assertEqual(self.request.user, AnonymousUser()) + + @override_settings(ROOT_URLCONF="auth_tests.urls") @modify_settings( MIDDLEWARE={"append": "django.contrib.auth.middleware.LoginRequiredMiddleware"} |
