Skip to content

Commit

Permalink
Merge pull request #224 from wrr/is_within_original_scope
Browse files Browse the repository at this point in the history
is_within_original_scope method for refresh token grant (Issue #220)
  • Loading branch information
ib-lundgren committed Nov 10, 2013
2 parents 3cf2da9 + 7d4f5ce commit f1ba05b
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 1 deletion.
4 changes: 3 additions & 1 deletion oauthlib/oauth2/rfc6749/grant_types/refresh_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ def validate_token_request(self, request):

if request.scope:
request.scopes = utils.scope_to_list(request.scope)
if not all((s in original_scopes for s in request.scopes)):
if (not all((s in original_scopes for s in request.scopes))
and not self.request_validator.is_within_original_scope(
request.scopes, request.refresh_token, request)):
log.debug('Refresh token %s lack requested scopes, %r.',
request.refresh_token, request.scopes)
raise errors.InvalidScopeError(
Expand Down
21 changes: 21 additions & 0 deletions oauthlib/oauth2/rfc6749/request_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,27 @@ def get_original_scopes(self, refresh_token, request, *args, **kwargs):
"""
raise NotImplementedError('Subclasses must implement this method.')

def is_within_original_scope(self, request_scopes, refresh_token, request, *args, **kwargs):
"""Check if requested scopes are within a scope of the refresh token.
When access tokens are refreshed the scope of the new token
needs to be within the scope of the original token. This is
ensured by checking that all requested scopes strings are on
the list returned by the get_original_scopes. If this check
fails, is_withing_original_scope is called. The method can be
used in situations where returning all valid scopes from the
get_original_scopes is not practical.
:param request_scopes: A list of scopes that were requested by client
:param refresh_token: Unicode refresh_token
:param request: The HTTP Request (oauthlib.common.Request)
:rtype: True or False
Method is used by:
- Refresh token grant
"""
return False

def invalidate_authorization_code(self, client_id, code, request, *args, **kwargs):
"""Invalidate an authorization code after use.
Expand Down
14 changes: 14 additions & 0 deletions tests/oauth2/rfc6749/grant_types/test_refresh_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,21 @@ def test_create_token_inherit_scope(self):
self.assertIn('expires_in', token)
self.assertEqual(token['scope'], 'foo bar')

def test_create_token_within_original_scope(self):
self.mock_validator.get_original_scopes.return_value = ['baz']
self.mock_validator.is_within_original_scope.return_value = True
bearer = BearerToken(self.mock_validator)
headers, body, status_code = self.auth.create_token_response(
self.request, bearer)
token = json.loads(body)
self.assertIn('access_token', token)
self.assertIn('token_type', token)
self.assertIn('expires_in', token)
self.assertEqual(token['scope'], 'foo')

def test_invalid_scope(self):
self.mock_validator.get_original_scopes.return_value = ['baz']
self.mock_validator.is_within_original_scope.return_value = False
bearer = BearerToken(self.mock_validator)
headers, body, status_code = self.auth.create_token_response(
self.request, bearer)
Expand Down Expand Up @@ -110,6 +123,7 @@ def test_invalid_refresh_token(self):

def test_invalid_scope_original_scopes_empty(self):
self.mock_validator.validate_refresh_token.return_value = True
self.mock_validator.is_within_original_scope.return_value = False
self.assertRaises(errors.InvalidScopeError,
self.auth.validate_token_request, self.request)

Expand Down
2 changes: 2 additions & 0 deletions tests/oauth2/rfc6749/test_request_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def test_method_contracts(self):
'client_id', 'request')
self.assertRaises(NotImplementedError, v.get_original_scopes,
'refresh_token', 'request')
self.assertFalse(v.is_within_original_scope(
['scope'], 'refresh_token', 'request'))
self.assertRaises(NotImplementedError, v.invalidate_authorization_code,
'client_id', 'code', 'request')
self.assertRaises(NotImplementedError, v.save_authorization_code,
Expand Down

0 comments on commit f1ba05b

Please sign in to comment.