diff options
author | Ib Lundgren <ib.lundgren@gmail.com> | 2013-02-20 23:43:48 +0100 |
---|---|---|
committer | Ib Lundgren <ib.lundgren@gmail.com> | 2013-02-20 23:43:48 +0100 |
commit | 4f48d73e39e81d28215399952aeb1da672cd8c9a (patch) | |
tree | 13d2b650be6295c00d8f1055dd9d1d1db9ac92b4 | |
parent | f02e5dffcab398b0f525d71e61ec4d90f9d80b81 (diff) | |
download | oauthlib-4f48d73e39e81d28215399952aeb1da672cd8c9a.tar.gz |
Refactor auth code client_id fallback auth
-rw-r--r-- | oauthlib/oauth2/draft25/grant_types.py | 37 | ||||
-rw-r--r-- | tests/oauth2/draft25/test_grant_types.py | 2 | ||||
-rw-r--r-- | tests/oauth2/draft25/test_servers.py | 21 |
3 files changed, 46 insertions, 14 deletions
diff --git a/oauthlib/oauth2/draft25/grant_types.py b/oauthlib/oauth2/draft25/grant_types.py index 43bddb1..17e80e1 100644 --- a/oauthlib/oauth2/draft25/grant_types.py +++ b/oauthlib/oauth2/draft25/grant_types.py @@ -45,6 +45,24 @@ class RequestValidator(object): """ raise NotImplementedError('Subclasses must implement this method.') + def authenticate_client_id(self, client_id, request, *args, **kwargs): + """Ensure client_id belong to a non-confidential client. + + A non-confidential client is one that is not required to authenticate + through other means, such as using HTTP Basic. + + Note, while not strictly necessary it can often be very convenient + to set request.client to the client object associated with the + given client_id. + + :param request: oauthlib.common.Request + :rtype: True or False + + Method is used by: + - Authorization Code Grant + """ + raise NotImplementedError('Subclasses must implement this method.') + def confirm_redirect_uri(self, client_id, code, redirect_uri, client, *args, **kwargs): """Ensure client is authorized to redirect to the redirect_uri requested. @@ -517,24 +535,19 @@ class AuthorizationCodeGrant(GrantTypeBase): # in Section 3.2.1. # http://tools.ietf.org/html/rfc6749#section-3.2.1 if not self.request_validator.authenticate_client(request): - log.debug('Could not authenticate client, %r.', request) - raise errors.InvalidClientError() + # REQUIRED, if the client is not authenticating with the + # authorization server as described in Section 3.2.1. + # http://tools.ietf.org/html/rfc6749#section-3.2.1 + if not self.request_validator.authenticate_client_id( + request.client_id, request): + log.debug('Client authentication failed, %r.', request) + raise errors.InvalidClientError() else: if not hasattr(request.client, 'client_id'): raise NotImplementedError('Authenticate client must set the ' 'request.client.client_id attribute ' 'in authenticate_client.') - # REQUIRED, if the client is not authenticating with the - # authorization server as described in Section 3.2.1. - # http://tools.ietf.org/html/rfc6749#section-3.2.1 - if (not hasattr(request.client, 'client_id') and not - self.request_validator.validate_client_id( - request.client_id, request)): - log.debug('Client_id not provided for unauthenticated client, %r.', - request) - raise errors.InvalidClientError() - # Ensure client is authorized use of this grant type self.validate_grant_type(request) diff --git a/tests/oauth2/draft25/test_grant_types.py b/tests/oauth2/draft25/test_grant_types.py index fc2b2b8..549644d 100644 --- a/tests/oauth2/draft25/test_grant_types.py +++ b/tests/oauth2/draft25/test_grant_types.py @@ -88,7 +88,7 @@ class AuthorizationCodeGrantTest(TestCase): auth.validate_token_request, request) mock_validator.authenticate_client.return_value = False - mock_validator.validate_client_id.return_value = False + mock_validator.authenticate_client_id.return_value = False request.code = 'waffles' self.assertRaises(InvalidClientError, auth.validate_token_request, request) diff --git a/tests/oauth2/draft25/test_servers.py b/tests/oauth2/draft25/test_servers.py index 64e1fb2..3f07e48 100644 --- a/tests/oauth2/draft25/test_servers.py +++ b/tests/oauth2/draft25/test_servers.py @@ -284,10 +284,25 @@ class ClientAuthenticationTest(TestCase): return True def test_client_id_authentication(self): - pass + token_uri = 'http://example.com/path' + + # authorization code grant + self.validator.authenticate_client.return_value = False + self.validator.authenticate_client_id.return_value = False + _, _, body, _ = self.web.create_token_response(token_uri, + body='grant_type=authorization_code&code=mock') + self.assertEqual(json.loads(body)['error'], 'invalid_client') + + self.validator.authenticate_client_id.return_value = True + self.validator.authenticate_client.side_effect = self.set_client + _, _, body, _ = self.web.create_token_response(token_uri, + body='grant_type=authorization_code&code=mock') + self.assertIn('access_token', json.loads(body)) def test_custom_authentication(self): token_uri = 'http://example.com/path' + + # authorization code grant self.assertRaises(NotImplementedError, self.web.create_token_response, token_uri, body='grant_type=authorization_code&code=mock') @@ -297,6 +312,10 @@ class ClientAuthenticationTest(TestCase): body='grant_type=authorization_code&code=mock') self.assertIn('access_token', json.loads(body)) + # password grant + + # client credentials grant + class ResourceOwnerAssociationTest(TestCase): |