[1.10.x] Fixed #27363 -- Replaced unsafe redirect in SessionMiddleware with SuspiciousOperation.
Backport of 1ce04bcce0
from master
This commit is contained in:
parent
157607cb6c
commit
acacf54fa1
|
@ -3,7 +3,7 @@ from importlib import import_module
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.sessions.backends.base import UpdateError
|
from django.contrib.sessions.backends.base import UpdateError
|
||||||
from django.shortcuts import redirect
|
from django.core.exceptions import SuspiciousOperation
|
||||||
from django.utils.cache import patch_vary_headers
|
from django.utils.cache import patch_vary_headers
|
||||||
from django.utils.deprecation import MiddlewareMixin
|
from django.utils.deprecation import MiddlewareMixin
|
||||||
from django.utils.http import cookie_date
|
from django.utils.http import cookie_date
|
||||||
|
@ -57,10 +57,11 @@ class SessionMiddleware(MiddlewareMixin):
|
||||||
try:
|
try:
|
||||||
request.session.save()
|
request.session.save()
|
||||||
except UpdateError:
|
except UpdateError:
|
||||||
# The user is now logged out; redirecting to same
|
raise SuspiciousOperation(
|
||||||
# page will result in a redirect to the login page
|
"The request's session was deleted before the "
|
||||||
# if required.
|
"request completed. The user may have logged "
|
||||||
return redirect(request.path)
|
"out in a concurrent request, for example."
|
||||||
|
)
|
||||||
response.set_cookie(
|
response.set_cookie(
|
||||||
settings.SESSION_COOKIE_NAME,
|
settings.SESSION_COOKIE_NAME,
|
||||||
request.session.session_key, max_age=max_age,
|
request.session.session_key, max_age=max_age,
|
||||||
|
|
|
@ -26,3 +26,7 @@ Bugfixes
|
||||||
|
|
||||||
* Prevented ``i18n_patterns()`` from using too much of the URL as the language
|
* Prevented ``i18n_patterns()`` from using too much of the URL as the language
|
||||||
to fix a use case for ``prefix_default_language=False`` (:ticket:`27063`).
|
to fix a use case for ``prefix_default_language=False`` (:ticket:`27063`).
|
||||||
|
|
||||||
|
* Replaced a possibly incorrect redirect from ``SessionMiddleware`` when a
|
||||||
|
session is destroyed in a concurrent request with a ``SuspiciousOperation``
|
||||||
|
to indicate that the request can't be completed (:ticket:`27363`).
|
||||||
|
|
|
@ -25,7 +25,7 @@ from django.contrib.sessions.serializers import (
|
||||||
from django.core import management
|
from django.core import management
|
||||||
from django.core.cache import caches
|
from django.core.cache import caches
|
||||||
from django.core.cache.backends.base import InvalidCacheBackendError
|
from django.core.cache.backends.base import InvalidCacheBackendError
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.test import (
|
from django.test import (
|
||||||
RequestFactory, TestCase, ignore_warnings, override_settings,
|
RequestFactory, TestCase, ignore_warnings, override_settings,
|
||||||
|
@ -704,14 +704,15 @@ class SessionMiddlewareTests(TestCase):
|
||||||
request.session.save(must_create=True)
|
request.session.save(must_create=True)
|
||||||
request.session.delete()
|
request.session.delete()
|
||||||
|
|
||||||
# Handle the response through the middleware. It will try to save the
|
msg = (
|
||||||
# deleted session which will cause an UpdateError that's caught and
|
"The request's session was deleted before the request completed. "
|
||||||
# results in a redirect to the original page.
|
"The user may have logged out in a concurrent request, for example."
|
||||||
response = middleware.process_response(request, response)
|
)
|
||||||
|
with self.assertRaisesMessage(SuspiciousOperation, msg):
|
||||||
# Check that the response is a redirect.
|
# Handle the response through the middleware. It will try to save
|
||||||
self.assertEqual(response.status_code, 302)
|
# the deleted session which will cause an UpdateError that's caught
|
||||||
self.assertEqual(response['Location'], path)
|
# and raised as a SuspiciousOperation.
|
||||||
|
middleware.process_response(request, response)
|
||||||
|
|
||||||
def test_session_delete_on_end(self):
|
def test_session_delete_on_end(self):
|
||||||
request = RequestFactory().get('/')
|
request = RequestFactory().get('/')
|
||||||
|
|
Loading…
Reference in New Issue