0
0
mirror of https://github.com/django/django.git synced 2024-11-21 19:09:18 +01:00

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

This commit is contained in:
Jaap Roes 2024-06-24 10:07:00 +02:00
parent 6a1f9b1560
commit 7191e5aed1
5 changed files with 89 additions and 14 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
@ -155,8 +157,15 @@ def login(request, user, backend=None):
the anonymous session is retained when the user logs in. the anonymous session is retained when the user logs in.
""" """
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,
)
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()
@ -188,7 +197,13 @@ def login(request, user, backend=None):
async def alogin(request, user, backend=None): async def alogin(request, user, backend=None):
"""See login().""" """See login()."""
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()
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

@ -418,3 +418,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,15 +61,30 @@ 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)
# RemovedInDjango61Warning: When the deprecation ends, replace with:
# async def test_alogin_without_user(self):
async def test_alogin_without_user_no_request_user(self): async def test_alogin_without_user_no_request_user(self):
request = HttpRequest() request = HttpRequest()
request.session = await self.client.asession() request.session = await self.client.asession()
with self.assertRaisesMessage( # RemovedInDjango61Warning: When the deprecation ends, replace with:
AttributeError, # with self.assertRaisesMessage(
"'HttpRequest' object has no attribute 'auser'", # AttributeError,
# "'NoneType' object has no attribute '_meta'",
# ):
# 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) await alogin(request, None)
# RemovedInDjango61Warning: When the deprecation ends, remove completely.
async def test_alogin_without_user_anonymous_request(self): async def test_alogin_without_user_anonymous_request(self):
async def auser(): async def auser():
return AnonymousUser() return AnonymousUser()
@ -77,12 +93,19 @@ class AsyncAuthTest(TestCase):
request.user = AnonymousUser() request.user = AnonymousUser()
request.auser = auser request.auser = auser
request.session = await self.client.asession() request.session = await self.client.asession()
with self.assertRaisesMessage( with (
AttributeError, self.assertRaisesMessage(
"'AnonymousUser' object has no attribute '_meta'", 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) await alogin(request, None)
# RemovedInDjango61Warning: When the deprecation ends, remove completely.
async def test_alogin_without_user_authenticated_request(self): async def test_alogin_without_user_authenticated_request(self):
async def auser(): async def auser():
return self.test_user return self.test_user
@ -91,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

@ -2,6 +2,7 @@ from django.contrib import auth
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 from django.test import TestCase
from django.utils.deprecation import RemovedInDjango61Warning
class TestLogin(TestCase): class TestLogin(TestCase):
@ -32,27 +33,51 @@ class TestLogin(TestCase):
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): def test_without_user_no_request_user(self):
with self.assertRaisesMessage( # RemovedInDjango61Warning: When the deprecation ends, replace with:
AttributeError, # with self.assertRaisesMessage(
"'HttpRequest' object has no attribute 'user'", # AttributeError,
# "'NoneType' object has no attribute '_meta'",
# ):
# await 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) auth.login(self.request, None)
# RemovedInDjango61Warning: When the deprecation ends, remove completely.
def test_without_user_anonymous_request(self): def test_without_user_anonymous_request(self):
self.request.user = AnonymousUser() self.request.user = AnonymousUser()
with self.assertRaisesMessage( with (
AttributeError, self.assertRaisesMessage(
"'AnonymousUser' object has no attribute '_meta'", 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) auth.login(self.request, None)
# RemovedInDjango61Warning: When the deprecation ends, remove completely.
def test_without_user_authenticated_request(self): def test_without_user_authenticated_request(self):
self.request.user = self.user self.request.user = self.user
self.assertNotIn(auth.SESSION_KEY, self.request.session) self.assertNotIn(auth.SESSION_KEY, self.request.session)
auth.login(self.request, None) 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)) self.assertEqual(self.request.session[auth.SESSION_KEY], str(self.user.pk))