1
0
mirror of https://github.com/django/django.git synced 2024-12-22 09:05:43 +00:00

Fixed #35530 -- Deprecated request.user fallback in auth.login and auth.alogin.

This commit is contained in:
Jaap Roes 2024-11-28 14:42:59 +01:00 committed by Sarah Boyce
parent 28b9b8d6d9
commit ceecd518b1
5 changed files with 129 additions and 3 deletions

View File

@ -1,11 +1,13 @@
import inspect import inspect
import re import re
import warnings
from django.apps import apps as django_apps from django.apps import apps as django_apps
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.middleware.csrf import rotate_token from django.middleware.csrf import rotate_token
from django.utils.crypto import constant_time_compare from django.utils.crypto import constant_time_compare
from django.utils.deprecation import RemovedInDjango61Warning
from django.utils.module_loading import import_string from django.utils.module_loading import import_string
from django.views.decorators.debug import sensitive_variables from django.views.decorators.debug import sensitive_variables
@ -154,9 +156,19 @@ def login(request, user, backend=None):
have to reauthenticate on every request. Note that data set during have to reauthenticate on every request. Note that data set during
the anonymous session is retained when the user logs in. the anonymous session is retained when the user logs in.
""" """
# RemovedInDjango61Warning: When the deprecation ends, replace with:
# session_auth_hash = user.get_session_auth_hash()
session_auth_hash = "" session_auth_hash = ""
# RemovedInDjango61Warning.
if user is None: if user is None:
user = request.user user = request.user
warnings.warn(
"Fallback to request.user when user is None will be removed.",
RemovedInDjango61Warning,
stacklevel=2,
)
# RemovedInDjango61Warning.
if hasattr(user, "get_session_auth_hash"): if hasattr(user, "get_session_auth_hash"):
session_auth_hash = user.get_session_auth_hash() session_auth_hash = user.get_session_auth_hash()
@ -187,9 +199,18 @@ def login(request, user, backend=None):
async def alogin(request, user, backend=None): async def alogin(request, user, backend=None):
"""See login().""" """See login()."""
# RemovedInDjango61Warning: When the deprecation ends, replace with:
# session_auth_hash = user.get_session_auth_hash()
session_auth_hash = "" session_auth_hash = ""
# RemovedInDjango61Warning.
if user is None: if user is None:
warnings.warn(
"Fallback to request.user when user is None will be removed.",
RemovedInDjango61Warning,
stacklevel=2,
)
user = await request.auser() user = await request.auser()
# RemovedInDjango61Warning.
if hasattr(user, "get_session_auth_hash"): if hasattr(user, "get_session_auth_hash"):
session_auth_hash = user.get_session_auth_hash() session_auth_hash = user.get_session_auth_hash()

View File

@ -18,6 +18,10 @@ details on these changes.
* The ``all`` keyword argument of ``django.contrib.staticfiles.finders.find()`` * The ``all`` keyword argument of ``django.contrib.staticfiles.finders.find()``
will be removed. will be removed.
* The fallback to ``request.user`` when ``user`` is ``None`` in
``django.contrib.auth.login()`` and ``django.contrib.auth.alogin()`` will be
removed.
.. _deprecation-removed-in-6.0: .. _deprecation-removed-in-6.0:
6.0 6.0

View File

@ -443,3 +443,7 @@ Miscellaneous
* The ``all`` argument for the ``django.contrib.staticfiles.finders.find()`` * The ``all`` argument for the ``django.contrib.staticfiles.finders.find()``
function is deprecated in favor of the ``find_all`` argument. function is deprecated in favor of the ``find_all`` argument.
* The fallback to ``request.user`` when ``user`` is ``None`` in
``django.contrib.auth.login()`` and ``django.contrib.auth.alogin()`` will be
removed.

View File

@ -8,6 +8,7 @@ from django.contrib.auth import (
from django.contrib.auth.models import AnonymousUser, User from django.contrib.auth.models import AnonymousUser, User
from django.http import HttpRequest from django.http import HttpRequest
from django.test import TestCase, override_settings from django.test import TestCase, override_settings
from django.utils.deprecation import RemovedInDjango61Warning
class AsyncAuthTest(TestCase): class AsyncAuthTest(TestCase):
@ -60,7 +61,52 @@ class AsyncAuthTest(TestCase):
self.assertIsInstance(user, User) self.assertIsInstance(user, User)
self.assertEqual(user.username, second_user.username) self.assertEqual(user.username, second_user.username)
async def test_alogin_without_user(self): # RemovedInDjango61Warning: When the deprecation ends, replace with:
# async def test_alogin_without_user(self):
async def test_alogin_without_user_no_request_user(self):
request = HttpRequest()
request.session = await self.client.asession()
# RemovedInDjango61Warning: When the deprecation ends, replace with:
# with self.assertRaisesMessage(
# AttributeError,
# "'NoneType' object has no attribute 'get_session_auth_hash'",
# ):
# await alogin(request, None)
with (
self.assertRaisesMessage(
AttributeError,
"'HttpRequest' object has no attribute 'auser'",
),
self.assertWarnsMessage(
RemovedInDjango61Warning,
"Fallback to request.user when user is None will be removed.",
),
):
await alogin(request, None)
# RemovedInDjango61Warning: When the deprecation ends, remove completely.
async def test_alogin_without_user_anonymous_request(self):
async def auser():
return AnonymousUser()
request = HttpRequest()
request.user = AnonymousUser()
request.auser = auser
request.session = await self.client.asession()
with (
self.assertRaisesMessage(
AttributeError,
"'AnonymousUser' object has no attribute '_meta'",
),
self.assertWarnsMessage(
RemovedInDjango61Warning,
"Fallback to request.user when user is None will be removed.",
),
):
await alogin(request, None)
# RemovedInDjango61Warning: When the deprecation ends, remove completely.
async def test_alogin_without_user_authenticated_request(self):
async def auser(): async def auser():
return self.test_user return self.test_user
@ -68,7 +114,11 @@ class AsyncAuthTest(TestCase):
request.user = self.test_user request.user = self.test_user
request.auser = auser request.auser = auser
request.session = await self.client.asession() request.session = await self.client.asession()
await alogin(request, None) with self.assertWarnsMessage(
RemovedInDjango61Warning,
"Fallback to request.user when user is None will be removed.",
):
await alogin(request, None)
user = await aget_user(request) user = await aget_user(request)
self.assertIsInstance(user, User) self.assertIsInstance(user, User)
self.assertEqual(user.username, self.test_user.username) self.assertEqual(user.username, self.test_user.username)

View File

@ -1,7 +1,8 @@
from django.contrib import auth from django.contrib import auth
from django.contrib.auth.models import User from django.contrib.auth.models import AnonymousUser, User
from django.http import HttpRequest from django.http import HttpRequest
from django.test import TestCase from django.test import TestCase
from django.utils.deprecation import RemovedInDjango61Warning
class TestLogin(TestCase): class TestLogin(TestCase):
@ -23,3 +24,49 @@ class TestLogin(TestCase):
auth.login(self.request, self.user) auth.login(self.request, self.user)
self.assertEqual(self.request.session[auth.SESSION_KEY], str(self.user.pk)) self.assertEqual(self.request.session[auth.SESSION_KEY], str(self.user.pk))
# RemovedInDjango61Warning: When the deprecation ends, replace with:
# def test_without_user(self):
def test_without_user_no_request_user(self):
# RemovedInDjango61Warning: When the deprecation ends, replace with:
# with self.assertRaisesMessage(
# AttributeError,
# "'NoneType' object has no attribute 'get_session_auth_hash'",
# ):
# auth.login(self.request, None)
with (
self.assertRaisesMessage(
AttributeError,
"'HttpRequest' object has no attribute 'user'",
),
self.assertWarnsMessage(
RemovedInDjango61Warning,
"Fallback to request.user when user is None will be removed.",
),
):
auth.login(self.request, None)
# RemovedInDjango61Warning: When the deprecation ends, remove completely.
def test_without_user_anonymous_request(self):
self.request.user = AnonymousUser()
with (
self.assertRaisesMessage(
AttributeError,
"'AnonymousUser' object has no attribute '_meta'",
),
self.assertWarnsMessage(
RemovedInDjango61Warning,
"Fallback to request.user when user is None will be removed.",
),
):
auth.login(self.request, None)
# RemovedInDjango61Warning: When the deprecation ends, remove completely.
def test_without_user_authenticated_request(self):
self.request.user = self.user
self.assertNotIn(auth.SESSION_KEY, self.request.session)
msg = "Fallback to request.user when user is None will be removed."
with self.assertWarnsMessage(RemovedInDjango61Warning, msg):
auth.login(self.request, None)
self.assertEqual(self.request.session[auth.SESSION_KEY], str(self.user.pk))