فهرست منبع

Fixed #19662 -- alter auth modelbackend to accept custom username fields

Thanks to Aymeric and Carl for the review.
Preston Holmes 12 سال پیش
والد
کامیت
c44d748272
3فایلهای تغییر یافته به همراه32 افزوده شده و 8 حذف شده
  1. 4 4
      django/contrib/auth/backends.py
  2. 19 1
      django/contrib/auth/tests/auth_backends.py
  3. 9 3
      docs/ref/contrib/auth.txt

+ 4 - 4
django/contrib/auth/backends.py

@@ -8,11 +8,11 @@ class ModelBackend(object):
     Authenticates against django.contrib.auth.models.User.
     """
 
-    # TODO: Model, login attribute name and password attribute name should be
-    # configurable.
-    def authenticate(self, username=None, password=None):
+    def authenticate(self, username=None, password=None, **kwargs):
+        UserModel = get_user_model()
+        if username is None:
+            username = kwargs.get(UserModel.USERNAME_FIELD)
         try:
-            UserModel = get_user_model()
             user = UserModel._default_manager.get_by_natural_key(username)
             if user.check_password(password):
                 return user

+ 19 - 1
django/contrib/auth/tests/auth_backends.py

@@ -4,7 +4,7 @@ from datetime import date
 from django.conf import settings
 from django.contrib.auth.models import User, Group, Permission, AnonymousUser
 from django.contrib.auth.tests.utils import skipIfCustomUser
-from django.contrib.auth.tests.custom_user import ExtensionUser, CustomPermissionsUser
+from django.contrib.auth.tests.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
@@ -190,6 +190,24 @@ class CustomPermissionsUserModelBackendTest(BaseModelBackendTest, TestCase):
         )
 
 
+@override_settings(AUTH_USER_MODEL='auth.CustomUser')
+class CustomUserModelBackendAuthenticateTest(TestCase):
+    """
+    Tests that the model backend can accept a credentials kwarg labeled with
+    custom user model's USERNAME_FIELD.
+    """
+
+    def test_authenticate(self):
+        test_user = CustomUser._default_manager.create_user(
+            email='test@example.com',
+            password='test',
+            date_of_birth=date(2006, 4, 25)
+        )
+        authenticated_user = authenticate(email='test@example.com', password='test')
+        self.assertEqual(test_user, authenticated_user)
+
+
+
 class TestObj(object):
     pass
 

+ 9 - 3
docs/ref/contrib/auth.txt

@@ -412,9 +412,15 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
 .. class:: ModelBackend
 
     This is the default authentication backend used by Django.  It
-    authenticates using usernames and passwords stored in the
-    :class:`~django.contrib.auth.models.User` model.
-
+    authenticates using credentials consisting of a user identifier and
+    password.  For Django's default user model, the user identifier is the
+    username, for custom user models it is the field specified by
+    USERNAME_FIELD (see :doc:`Customizing Users and authentication
+    </topics/auth/customizing>`).
+
+    It also handles the default permissions model as defined for
+    :class:`~django.contrib.auth.models.User` and
+    :class:`~django.contrib.auth.models.PermissionsMixin`.
 
 .. class:: RemoteUserBackend