Added AccessTokenCredentials
diff --git a/oauth2client/client.py b/oauth2client/client.py
index d05b946..6ef38a6 100644
--- a/oauth2client/client.py
+++ b/oauth2client/client.py
@@ -41,7 +41,8 @@
pass
-class MissingParameter(Error):
+class AccessTokenCredentialsError(Error):
+ """Having only the access_token means no refresh is possible."""
pass
@@ -97,9 +98,9 @@
class OAuth2Credentials(Credentials):
"""Credentials object for OAuth 2.0
- Credentials can be applied to an httplib2.Http object
- using the authorize() method, which then signs each
- request from that object with the OAuth 2.0 access token.
+ Credentials can be applied to an httplib2.Http object using the authorize()
+ method, which then signs each request from that object with the OAuth 2.0
+ access token.
OAuth2Credentials objects may be safely pickled and unpickled.
"""
@@ -109,8 +110,7 @@
"""Create an instance of OAuth2Credentials
This constructor is not usually called by the user, instead
- OAuth2Credentials objects are instantiated by
- the OAuth2WebServerFlow.
+ OAuth2Credentials objects are instantiated by the OAuth2WebServerFlow.
Args:
token_uri: string, URI of token endpoint.
@@ -137,6 +137,10 @@
self.token_uri = token_uri
self.user_agent = user_agent
+ # True if the credentials have been revoked or expired and can't be
+ # refreshed.
+ self.invalid = False
+
def set_store(self, store):
"""Set the storage for the credential.
@@ -193,6 +197,15 @@
if self.store is not None:
self.store(self)
else:
+ # An {'error':...} response body means the token is expired or revoked, so
+ # we flag the credentials as such.
+ try:
+ d = simplejson.loads(content)
+ if 'error' in d:
+ self.invalid = True
+ self.store(self)
+ except:
+ pass
logging.error('Failed to retrieve access token: %s' % content)
raise RequestError('Invalid response %s.' % resp['status'])
@@ -248,6 +261,58 @@
return http
+class AccessTokenCredentials(OAuth2Credentials):
+ """Credentials object for OAuth 2.0
+
+ Credentials can be applied to an httplib2.Http object using the authorize()
+ method, which then signs each request from that object with the OAuth 2.0
+ access token. This set of credentials is for the use case where you have
+ acquired an OAuth 2.0 access_token from another place such as a JavaScript
+ client or another web application, and wish to use it from Python. Because
+ only the access_token is present it can not be refreshed and will in time
+ expire.
+
+ OAuth2Credentials objects may be safely pickled and unpickled.
+
+ Usage:
+ credentials = AccessTokenCredentials('<an access token>',
+ 'my-user-agent/1.0')
+ http = httplib2.Http()
+ http = credentials.authorize(http)
+
+ Exceptions:
+ AccessTokenCredentialsExpired: raised when the access_token expires or is
+ revoked.
+
+ """
+
+ def __init__(self, access_token, user_agent):
+ """Create an instance of OAuth2Credentials
+
+ This is one of the few types if Credentials that you should contrust,
+ Credentials objects are usually instantiated by a Flow.
+
+ Args:
+ token_uri: string, URI of token endpoint.
+ user_agent: string, The HTTP User-Agent to provide for this application.
+
+ Notes:
+ store: callable, a callable that when passed a Credential
+ will store the credential back to where it came from.
+ """
+ super(AccessTokenCredentials, self).__init__(
+ access_token,
+ None,
+ None,
+ None,
+ None,
+ None,
+ user_agent)
+
+ def _refresh(self, http_request):
+ raise AccessTokenCredentialsError(
+ "The access_token is expired or invalid and can't be refreshed.")
+
class OAuth2WebServerFlow(Flow):
"""Does the Web Server Flow for OAuth 2.0.