Fall back to using an access_token for revocation.

According to the [OAuth2
docs](https://developers.google.com/accounts/docs/OAuth2WebServer#tokenrevoke),
we can use either the refresh token or access token when revoking a token. If
we've lost the refresh token for some reason, we should fall back to revoking
via access token. (Note that if the access token has expired, this will still
raise, which is the correct behavior.)

Fixes #132.
This commit is contained in:
Craig Citro
2015-02-17 08:40:44 -08:00
parent d68049b5ee
commit b574bc2a98
2 changed files with 11 additions and 3 deletions

View File

@@ -811,16 +811,16 @@ class OAuth2Credentials(Credentials):
raise AccessTokenRefreshError(error_msg)
def _revoke(self, http_request):
"""Revokes the refresh_token and deletes the store if available.
"""Revokes this credential and deletes the stored copy (if it exists).
Args:
http_request: callable, a callable that matches the method signature of
httplib2.Http.request, used to make the revoke request.
"""
self._do_revoke(http_request, self.refresh_token)
self._do_revoke(http_request, self.refresh_token or self.access_token)
def _do_revoke(self, http_request, token):
"""Revokes the credentials and deletes the store if available.
"""Revokes this credential and deletes the stored copy (if it exists).
Args:
http_request: callable, a callable that matches the method signature of

View File

@@ -560,6 +560,14 @@ class BasicCredentialsTests(unittest.TestCase):
self, '400', revoke_raise=True,
valid_bool_value=False, token_attr='refresh_token')
def test_token_revoke_fallback(self):
original_credentials = self.credentials.to_json()
self.credentials.refresh_token = None
_token_revoke_test_helper(
self, '200', revoke_raise=False,
valid_bool_value=True, token_attr='access_token')
self.credentials = self.credentials.from_json(original_credentials)
def test_non_401_error_response(self):
http = HttpMockSequence([
({'status': '400'}, b''),