Fixed #23925 -- Allowed settings.AUTHENTICATION_BACKENDS to reference import aliases

This commit is contained in:
sdeprez 2014-11-27 10:35:10 +01:00 committed by Tim Graham
parent ecf7814b3a
commit 9e80c5f457
3 changed files with 36 additions and 5 deletions

View File

@ -20,10 +20,11 @@ def load_backend(path):
return import_string(path)() return import_string(path)()
def get_backends(): def _get_backends(return_tuples=False):
backends = [] backends = []
for backend_path in settings.AUTHENTICATION_BACKENDS: for backend_path in settings.AUTHENTICATION_BACKENDS:
backends.append(load_backend(backend_path)) backend = load_backend(backend_path)
backends.append((backend, backend_path) if return_tuples else backend)
if not backends: if not backends:
raise ImproperlyConfigured( raise ImproperlyConfigured(
'No authentication backends have been defined. Does ' 'No authentication backends have been defined. Does '
@ -32,6 +33,10 @@ def get_backends():
return backends return backends
def get_backends():
return _get_backends(return_tuples=False)
def _clean_credentials(credentials): def _clean_credentials(credentials):
""" """
Cleans a dictionary of credentials of potentially sensitive info before Cleans a dictionary of credentials of potentially sensitive info before
@ -51,7 +56,7 @@ def authenticate(**credentials):
""" """
If the given credentials are valid, return a User object. If the given credentials are valid, return a User object.
""" """
for backend in get_backends(): for backend, backend_path in _get_backends(return_tuples=True):
try: try:
inspect.getcallargs(backend.authenticate, **credentials) inspect.getcallargs(backend.authenticate, **credentials)
except TypeError: except TypeError:
@ -66,7 +71,7 @@ def authenticate(**credentials):
if user is None: if user is None:
continue continue
# Annotate the user object with the path of the backend. # Annotate the user object with the path of the backend.
user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__) user.backend = backend_path
return user return user
# The credentials supplied are invalid to all backends, fire signal # The credentials supplied are invalid to all backends, fire signal

View File

@ -1 +1,4 @@
# The password for the fixture data users is 'password' # The password for the fixture data users is 'password'
# For testing that auth backends can be referenced using a convenience import
from django.contrib.auth.tests.test_auth_backends import ImportedModelBackend # NOQA

View File

@ -8,7 +8,7 @@ from django.contrib.auth.tests.utils import skipIfCustomUser
from django.contrib.auth.tests.custom_user import ExtensionUser, CustomPermissionsUser, CustomUser from django.contrib.auth.tests.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, get_user from django.contrib.auth import authenticate, BACKEND_SESSION_KEY, get_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.contrib.auth.hashers import MD5PasswordHasher from django.contrib.auth.hashers import MD5PasswordHasher
@ -608,3 +608,26 @@ class ImproperlyConfiguredUserModelTest(TestCase):
request.session = self.client.session request.session = self.client.session
self.assertRaises(ImproperlyConfigured, get_user, request) self.assertRaises(ImproperlyConfigured, get_user, request)
class ImportedModelBackend(ModelBackend):
pass
class ImportedBackendTests(TestCase):
"""
#23925 - The backend path added to the session should be the same
as the one defined in AUTHENTICATION_BACKENDS setting.
"""
backend = 'django.contrib.auth.tests.ImportedModelBackend'
@override_settings(AUTHENTICATION_BACKENDS=(backend, ))
def test_backend_path(self):
username = 'username'
password = 'password'
User.objects.create_user(username, 'email', password)
self.assertTrue(self.client.login(username=username, password=password))
request = HttpRequest()
request.session = self.client.session
self.assertEqual(request.session[BACKEND_SESSION_KEY], self.backend)