summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Bastida <me@jorgebastida.com>2013-05-18 13:46:31 +0200
committerClaude Paroz <claude@2xlibre.net>2013-05-18 15:58:29 +0200
commitdc43fbc2f21c12e34e309d0e8a121020391aa03a (patch)
treefa59a272957256e31375ed3bd54b44b3b4e0e236
parenta0c0cc924e4c6ffd22158f254ed9bc9556f05cc4 (diff)
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.
-rw-r--r--AUTHORS1
-rw-r--r--django/contrib/auth/__init__.py4
-rw-r--r--django/contrib/auth/tests/test_auth_backends.py53
3 files changed, 56 insertions, 2 deletions
diff --git a/AUTHORS b/AUTHORS
index 0ad6522725..e83fc035a3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -92,6 +92,7 @@ answer newbie questions, and generally made Django that much better:
Randy Barlow <randy@electronsweatshop.com>
Scott Barr <scott@divisionbyzero.com.au>
Jiri Barton
+ Jorge Bastida <me@jorgebastida.com>
Ned Batchelder <http://www.nedbatchelder.com/>
batiste@dosimple.ch
Batman
diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
index ef9066657d..17f6b895c7 100644
--- a/django/contrib/auth/__init__.py
+++ b/django/contrib/auth/__init__.py
@@ -120,12 +120,14 @@ def get_user_model():
def get_user(request):
+ from django.conf import settings
from django.contrib.auth.models import AnonymousUser
try:
user_id = request.session[SESSION_KEY]
backend_path = request.session[BACKEND_SESSION_KEY]
+ assert backend_path in settings.AUTHENTICATION_BACKENDS
backend = load_backend(backend_path)
user = backend.get_user(user_id) or AnonymousUser()
- except KeyError:
+ except (KeyError, AssertionError):
user = AnonymousUser()
return user
diff --git a/django/contrib/auth/tests/test_auth_backends.py b/django/contrib/auth/tests/test_auth_backends.py
index bb97c54a11..fc5a80e8dd 100644
--- a/django/contrib/auth/tests/test_auth_backends.py
+++ b/django/contrib/auth/tests/test_auth_backends.py
@@ -2,12 +2,14 @@ from __future__ import unicode_literals
from datetime import date
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.tests.utils import skipIfCustomUser
from django.contrib.auth.tests.test_custom_user import ExtensionUser, CustomPermissionsUser, CustomUser
from django.contrib.contenttypes.models import ContentType
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.utils import override_settings
@@ -402,3 +404,52 @@ class PermissionDeniedBackendTest(TestCase):
settings.AUTHENTICATION_BACKENDS) + (backend, ))
def test_authenticates(self):
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())