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.
This commit is contained in:
Aymeric Augustin 2019-06-08 21:03:26 +02:00 committed by Mariusz Felisiak
parent e065b29387
commit 3ee0834a46
2 changed files with 15 additions and 0 deletions

View File

@ -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:

View File

@ -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):
"""