2
0
Эх сурвалжийг харах

Fixed #30556 -- Avoided useless query and hasher call in ModelBackend.authenticate() when credentials aren't provided.

There's no need to fetch a user instance from the database unless
a username and a password are provided as credentials.
Aymeric Augustin 5 жил өмнө
parent
commit
3ee0834a46

+ 2 - 0
django/contrib/auth/backends.py

@@ -39,6 +39,8 @@ class ModelBackend(BaseBackend):
     def authenticate(self, request, username=None, password=None, **kwargs):
         if username is None:
             username = kwargs.get(UserModel.USERNAME_FIELD)
+        if username is None or password is None:
+            return
         try:
             user = UserModel._default_manager.get_by_natural_key(username)
         except UserModel.DoesNotExist:

+ 13 - 0
tests/auth_tests/test_auth_backends.py

@@ -226,6 +226,19 @@ class BaseModelBackendTest:
         authenticate(username='no_such_user', password='test')
         self.assertEqual(CountingMD5PasswordHasher.calls, 1)
 
+    @override_settings(PASSWORD_HASHERS=['auth_tests.test_auth_backends.CountingMD5PasswordHasher'])
+    def test_authentication_without_credentials(self):
+        CountingMD5PasswordHasher.calls = 0
+        for credentials in (
+            {},
+            {'username': getattr(self.user, self.UserModel.USERNAME_FIELD)},
+            {'password': 'test'},
+        ):
+            with self.subTest(credentials=credentials):
+                with self.assertNumQueries(0):
+                    authenticate(**credentials)
+                self.assertEqual(CountingMD5PasswordHasher.calls, 0)
+
 
 class ModelBackendTest(BaseModelBackendTest, TestCase):
     """