diff options
| author | Michał Górny <mgorny@gentoo.org> | 2013-08-23 17:49:42 +0200 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2013-08-28 07:51:45 -0400 |
| commit | b89c2a5d9eb70ca36629ef657c98e3371e9a5c4f (patch) | |
| tree | 3fc16e81d98696e058cfba1a5d3790863604bc7f | |
| parent | 5b889b2408eeaf72f45d8f97c114d8ba9f540726 (diff) | |
Fixed #18171 -- Checked signature of authenticate() to avoid supressing TypeErrors.
The current auth backend code catches TypeError to detect backends that
do not support specified argumetnts. As a result, any TypeErrors raised
within the actual backend code are silenced.
In Python 2.7+ and 3.2+ this can be avoided by using inspect.getcallargs().
With this method, we can test whether arguments match the signature without
actually calling the function.
Thanks David Eyk for the report.
| -rw-r--r-- | django/contrib/auth/__init__.py | 6 | ||||
| -rw-r--r-- | django/contrib/auth/tests/test_auth_backends.py | 29 |
2 files changed, 34 insertions, 1 deletions
diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py index 2f620a34fe..4ef5c0b2cd 100644 --- a/django/contrib/auth/__init__.py +++ b/django/contrib/auth/__init__.py @@ -1,3 +1,4 @@ +import inspect import re from django.conf import settings @@ -46,10 +47,13 @@ def authenticate(**credentials): """ for backend in get_backends(): try: - user = backend.authenticate(**credentials) + inspect.getcallargs(backend.authenticate, **credentials) except TypeError: # This backend doesn't accept these credentials as arguments. Try the next one. continue + + try: + user = backend.authenticate(**credentials) except PermissionDenied: # This backend says to stop in our tracks - this user should not be allowed in at all. return None diff --git a/django/contrib/auth/tests/test_auth_backends.py b/django/contrib/auth/tests/test_auth_backends.py index 4e83d786cf..4afe7c026c 100644 --- a/django/contrib/auth/tests/test_auth_backends.py +++ b/django/contrib/auth/tests/test_auth_backends.py @@ -480,3 +480,32 @@ class ChangedBackendSettingsTest(TestCase): # anonymous as the backend is not longer available. self.assertIsNotNone(user) self.assertTrue(user.is_anonymous()) + + +class TypeErrorBackend(object): + """ + Always raises TypeError. + """ + supports_object_permissions = True + supports_anonymous_user = True + supports_inactive_user = True + + def authenticate(self, username=None, password=None): + raise TypeError + + +@skipIfCustomUser +class TypeErrorBackendTest(TestCase): + """ + Tests that a TypeError within a backend is propagated properly. + + Regression test for ticket #18171 + """ + backend = 'django.contrib.auth.tests.test_auth_backends.TypeErrorBackend' + + def setUp(self): + self.user1 = User.objects.create_user('test', 'test@example.com', 'test') + + @override_settings(AUTHENTICATION_BACKENDS=(backend, )) + def test_type_error_raised(self): + self.assertRaises(TypeError, authenticate, username='test', password='test') |
