diff --git a/oidc_provider/lib/endpoints/token.py b/oidc_provider/lib/endpoints/token.py index c6b96b0..8c32046 100644 --- a/oidc_provider/lib/endpoints/token.py +++ b/oidc_provider/lib/endpoints/token.py @@ -1,3 +1,4 @@ +import inspect from base64 import urlsafe_b64encode import hashlib import logging @@ -96,7 +97,14 @@ class TokenEndpoint(object): if not settings.get('OIDC_GRANT_TYPE_PASSWORD_ENABLE'): raise TokenError('unsupported_grant_type') + auth_args = (self.request,) + try: + inspect.getcallargs(authenticate, *auth_args) + except TypeError: + auth_args = () + user = authenticate( + *auth_args, username=self.params['username'], password=self.params['password'] ) diff --git a/oidc_provider/tests/app/utils.py b/oidc_provider/tests/app/utils.py index fdee81c..457757d 100644 --- a/oidc_provider/tests/app/utils.py +++ b/oidc_provider/tests/app/utils.py @@ -1,5 +1,9 @@ import random import string + +import django +from django.contrib.auth.backends import ModelBackend + try: from urlparse import parse_qs, urlsplit except ImportError: @@ -131,3 +135,10 @@ def fake_idtoken_processing_hook2(id_token, user): def fake_introspection_processing_hook(response_dict, client, id_token): response_dict['test_introspection_processing_hook'] = FAKE_RANDOM_STRING return response_dict + + +class TestAuthBackend: + def authenticate(self, *args, **kwargs): + if django.VERSION[0] >= 2 or (django.VERSION[0] == 1 and django.VERSION[1] >= 11): + assert len(args) > 0 and args[0] + return ModelBackend().authenticate(*args, **kwargs) diff --git a/oidc_provider/tests/cases/test_token_endpoint.py b/oidc_provider/tests/cases/test_token_endpoint.py index 5c787b3..0646046 100644 --- a/oidc_provider/tests/cases/test_token_endpoint.py +++ b/oidc_provider/tests/cases/test_token_endpoint.py @@ -3,6 +3,7 @@ import time import uuid from base64 import b64encode + try: from urllib.parse import urlencode except ImportError: @@ -256,6 +257,17 @@ class TokenTestCase(TestCase): else: self.assertNotIn(claim, userinfo) + @override_settings(OIDC_GRANT_TYPE_PASSWORD_ENABLE=True, + AUTHENTICATION_BACKENDS=("oidc_provider.tests.app.utils.TestAuthBackend",)) + def test_password_grant_passes_request_to_backend(self): + response = self._post_request( + post_data=self._password_grant_post_data(), + extras=self._password_grant_auth_header() + ) + + response_dict = json.loads(response.content.decode('utf-8')) + self.assertIn('access_token', response_dict) + @override_settings(OIDC_TOKEN_EXPIRE=720) def test_authorization_code(self): """