Skip to content

Commit

Permalink
Merge 4ea5db5 into 1a06325
Browse files Browse the repository at this point in the history
  • Loading branch information
Massimiliano Pippi committed Sep 18, 2013
2 parents 1a06325 + 4ea5db5 commit 5c9c836
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 42 deletions.
46 changes: 24 additions & 22 deletions oauthlib/oauth2/rfc6749/grant_types/authorization_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,40 +335,42 @@ def validate_token_request(self, request):

if request.code is None:
raise errors.InvalidRequestError(
description='Missing code parameter.', request=request)
description='Missing code parameter.', request=request)

for param in ('client_id', 'grant_type', 'redirect_uri'):
if param in request.duplicate_params:
raise errors.InvalidRequestError(state=request.state,
description='Duplicate %s parameter.' % param,
request=request)

# If the client type is confidential or the client was issued client
# credentials (or assigned other authentication requirements), the
# client MUST authenticate 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(request):
# REQUIRED, if the client is not authenticating with the
# authorization server as described in Section 3.2.1.
description='Duplicate %s parameter.' % param,
request=request)

if self.request_validator.client_authentication_required():
# If the client type is confidential or the client was issued client
# credentials (or assigned other authentication requirements), the
# client MUST authenticate 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):
if not self.request_validator.authenticate_client(request):
log.debug('Client authentication failed, %r.', request)
raise errors.InvalidClientError(request=request)
else:
if not hasattr(request.client, 'client_id'):
raise NotImplementedError('Authenticate client must set the '
'request.client.client_id attribute '
'in authenticate_client.')
elif not self.request_validator.authenticate_client_id(request.client_id, request):
# 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
log.debug('Client authentication failed, %r.', request)
raise errors.InvalidClientError(request=request)

if not hasattr(request.client, 'client_id'):
raise NotImplementedError('Authenticate client must set the '
'request.client.client_id attribute '
'in authenticate_client.')

# Ensure client is authorized use of this grant type
self.validate_grant_type(request)

# REQUIRED. The authorization code received from the
# authorization server.
if not self.request_validator.validate_code(request.client_id,
request.code, request.client, request):
request.code, request.client, request):
log.debug('Client, %r (%r), is not allowed access to scopes %r.',
request.client_id, request.client, request.scopes)
raise errors.InvalidGrantError(request=request)
Expand All @@ -380,8 +382,8 @@ def validate_token_request(self, request):
# REQUIRED, if the "redirect_uri" parameter was included in the
# authorization request as described in Section 4.1.1, and their
# values MUST be identical.
if not self.request_validator.confirm_redirect_uri(request.client_id,
request.code, request.redirect_uri, request.client):
if not self.request_validator.confirm_redirect_uri(request.client_id, request.code,
request.redirect_uri, request.client):
log.debug('Redirect_uri (%r) invalid for client %r (%r).',
request.redirect_uri, request.client_id, request.client)
raise errors.AccessDeniedError(request=request)
16 changes: 10 additions & 6 deletions oauthlib/oauth2/rfc6749/grant_types/refresh_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ def validate_token_request(self, request):

if request.refresh_token is None:
raise errors.InvalidRequestError(
description='Missing refresh token parameter.',
request=request)
description='Missing refresh token parameter.',
request=request)

# Because refresh tokens are typically long-lasting credentials used to
# request additional access tokens, the refresh token is bound to the
Expand All @@ -79,10 +79,14 @@ def validate_token_request(self, request):
# authentication requirements), the client MUST authenticate with the
# authorization server as described in Section 3.2.1.
# http://tools.ietf.org/html/rfc6749#section-3.2.1
log.debug('Authenticating client, %r.', request)
if not self.request_validator.authenticate_client(request):
log.debug('Invalid client (%r), denying access.', request)
raise errors.InvalidClientError(request=request, status_code=401)
if self.request_validator.client_authentication_required(request):
log.debug('Authenticating client, %r.', request)
if not self.request_validator.authenticate_client(request):
log.debug('Invalid client (%r), denying access.', request)
raise errors.InvalidClientError(request=request, status_code=401)
elif not self.request_validator.authenticate_client_id(request.client_id, request):
log.debug('Client authentication failed, %r.', request)
raise errors.InvalidClientError(request=request)

# Ensure client is authorized use of this grant type
self.validate_grant_type(request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ class ResourceOwnerPasswordCredentialsGrant(GrantTypeBase):
def __init__(self, request_validator=None):
self.request_validator = request_validator or RequestValidator()

def create_token_response(self, request, token_handler,
require_authentication=True):
def create_token_response(self, request, token_handler):
"""Return token or error in json format.
If the access token request is valid and authorized, the
Expand All @@ -83,24 +82,19 @@ def create_token_response(self, request, token_handler,
.. _`Section 5.2`: http://tools.ietf.org/html/rfc6749#section-5.2
"""
headers = {
'Content-Type': 'application/json;charset=UTF-8',
'Cache-Control': 'no-store',
'Pragma': 'no-cache',
'Content-Type': 'application/json;charset=UTF-8',
'Cache-Control': 'no-store',
'Pragma': 'no-cache',
}
try:
if require_authentication:
if self.request_validator.client_authentication_required(request):
log.debug('Authenticating client, %r.', request)
if not self.request_validator.authenticate_client(request):
log.debug('Client authentication failed, %r.', request)
raise errors.InvalidClientError(request=request)
else:
if not hasattr(request.client, 'client_id'):
raise NotImplementedError(
'Authenticate client must set the '
'request.client.client_id attribute '
'in authenticate_client.')
else:
log.debug('Client authentication disabled, %r.', request)
elif not self.request_validator.authenticate_client_id(request.client_id, request):
log.debug('Client authentication failed, %r.', request)
raise errors.InvalidClientError(request=request)
log.debug('Validating access token request, %r.', request)
self.validate_token_request(request)
except errors.OAuth2Error as e:
Expand Down
28 changes: 28 additions & 0 deletions oauthlib/oauth2/rfc6749/request_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,34 @@

class RequestValidator(object):

def client_authentication_required(self, request, *args, **kwargs):
"""Determine if client authentication is required for current request.
According to the rfc6749, client authentication is required in the following cases:
- Resource Owner Password Credentials Grant, when Client type is Confidential or when
Client was issued client credentials or whenever Client provided client
authentication, see `Section 4.3.2`_.
- Authorization Code Grant, when Client type is Confidential or when Client was issued
client credentials or whenever Client provided client authentication,
see `Section 4.1.3`_.
- Refresh Token Grant, when Client type is Confidential or when Client was issued
client credentials or whenever Client provided client authentication, see
`Section 6`_
:param request: oauthlib.common.Request
:rtype: True or False
Method is used by:
- Authorization Code Grant
- Resource Owner Password Credentials Grant
- Refresh Token Grant
.. _`Section 4.3.2`: http://tools.ietf.org/html/rfc6749#section-4.3.2
.. _`Section 4.1.3`: http://tools.ietf.org/html/rfc6749#section-4.1.3
.. _`Section 6`: http://tools.ietf.org/html/rfc6749#section-6
"""
return True

def authenticate_client(self, request, *args, **kwargs):
"""Authenticate client through means outside the OAuth 2 spec.
Expand Down
1 change: 1 addition & 0 deletions tests/oauth2/rfc6749/test_request_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ def test_method_contracts(self):
'client_id', 'scopes', 'client', 'request')
self.assertRaises(NotImplementedError, v.validate_user,
'username', 'password', 'client', 'request')
self.assertTrue(v.client_authentication_required('r'))

0 comments on commit 5c9c836

Please sign in to comment.