mirror of https://github.com/django/django.git
Fixed #18998 - Prevented session crash when auth backend removed
Removing a backend configured in AUTHENTICATION_BACKENDS should not raise an exception for existing sessions, but should make already logged-in users disconnect. Thanks Bradley Ayers for the report.
This commit is contained in:
parent
a0c0cc924e
commit
dc43fbc2f2
1
AUTHORS
1
AUTHORS
|
@ -92,6 +92,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Randy Barlow <randy@electronsweatshop.com>
|
Randy Barlow <randy@electronsweatshop.com>
|
||||||
Scott Barr <scott@divisionbyzero.com.au>
|
Scott Barr <scott@divisionbyzero.com.au>
|
||||||
Jiri Barton
|
Jiri Barton
|
||||||
|
Jorge Bastida <me@jorgebastida.com>
|
||||||
Ned Batchelder <http://www.nedbatchelder.com/>
|
Ned Batchelder <http://www.nedbatchelder.com/>
|
||||||
batiste@dosimple.ch
|
batiste@dosimple.ch
|
||||||
Batman
|
Batman
|
||||||
|
|
|
@ -120,12 +120,14 @@ def get_user_model():
|
||||||
|
|
||||||
|
|
||||||
def get_user(request):
|
def get_user(request):
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import AnonymousUser
|
from django.contrib.auth.models import AnonymousUser
|
||||||
try:
|
try:
|
||||||
user_id = request.session[SESSION_KEY]
|
user_id = request.session[SESSION_KEY]
|
||||||
backend_path = request.session[BACKEND_SESSION_KEY]
|
backend_path = request.session[BACKEND_SESSION_KEY]
|
||||||
|
assert backend_path in settings.AUTHENTICATION_BACKENDS
|
||||||
backend = load_backend(backend_path)
|
backend = load_backend(backend_path)
|
||||||
user = backend.get_user(user_id) or AnonymousUser()
|
user = backend.get_user(user_id) or AnonymousUser()
|
||||||
except KeyError:
|
except (KeyError, AssertionError):
|
||||||
user = AnonymousUser()
|
user = AnonymousUser()
|
||||||
return user
|
return user
|
||||||
|
|
|
@ -2,12 +2,14 @@ from __future__ import unicode_literals
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.backends import ModelBackend
|
||||||
from django.contrib.auth.models import User, Group, Permission, AnonymousUser
|
from django.contrib.auth.models import User, Group, Permission, AnonymousUser
|
||||||
from django.contrib.auth.tests.utils import skipIfCustomUser
|
from django.contrib.auth.tests.utils import skipIfCustomUser
|
||||||
from django.contrib.auth.tests.test_custom_user import ExtensionUser, CustomPermissionsUser, CustomUser
|
from django.contrib.auth.tests.test_custom_user import ExtensionUser, CustomPermissionsUser, CustomUser
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
|
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate, get_user
|
||||||
|
from django.http import HttpRequest
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
|
|
||||||
|
@ -402,3 +404,52 @@ class PermissionDeniedBackendTest(TestCase):
|
||||||
settings.AUTHENTICATION_BACKENDS) + (backend, ))
|
settings.AUTHENTICATION_BACKENDS) + (backend, ))
|
||||||
def test_authenticates(self):
|
def test_authenticates(self):
|
||||||
self.assertEqual(authenticate(username='test', password='test'), self.user1)
|
self.assertEqual(authenticate(username='test', password='test'), self.user1)
|
||||||
|
|
||||||
|
|
||||||
|
class NewModelBackend(ModelBackend):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@skipIfCustomUser
|
||||||
|
class ChangedBackendSettingsTest(TestCase):
|
||||||
|
"""
|
||||||
|
Tests for changes in the settings.AUTHENTICATION_BACKENDS
|
||||||
|
"""
|
||||||
|
backend = 'django.contrib.auth.tests.test_auth_backends.NewModelBackend'
|
||||||
|
|
||||||
|
TEST_USERNAME = 'test_user'
|
||||||
|
TEST_PASSWORD = 'test_password'
|
||||||
|
TEST_EMAIL = 'test@example.com'
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
User.objects.create_user(self.TEST_USERNAME,
|
||||||
|
self.TEST_EMAIL,
|
||||||
|
self.TEST_PASSWORD)
|
||||||
|
|
||||||
|
@override_settings(AUTHENTICATION_BACKENDS=(backend, ))
|
||||||
|
def test_changed_backend_settings(self):
|
||||||
|
"""
|
||||||
|
Tests that removing a backend configured in AUTHENTICATION_BACKENDS
|
||||||
|
make already logged-in users disconnect.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Get a session for the test user
|
||||||
|
self.assertTrue(self.client.login(
|
||||||
|
username=self.TEST_USERNAME,
|
||||||
|
password=self.TEST_PASSWORD)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Prepare a request object
|
||||||
|
request = HttpRequest()
|
||||||
|
request.session = self.client.session
|
||||||
|
|
||||||
|
# Remove NewModelBackend
|
||||||
|
with self.settings(AUTHENTICATION_BACKENDS=(
|
||||||
|
'django.contrib.auth.backends.ModelBackend',)):
|
||||||
|
# Get the user from the request
|
||||||
|
user = get_user(request)
|
||||||
|
|
||||||
|
# Assert that the user retrieval is successful and the user is
|
||||||
|
# anonymous as the backend is not longer available.
|
||||||
|
self.assertIsNotNone(user)
|
||||||
|
self.assertTrue(user.is_anonymous())
|
||||||
|
|
Loading…
Reference in New Issue