Making oauth2client/ files pass PEP8.

This commit is contained in:
Danny Hermes
2015-08-20 16:08:20 -07:00
parent b70baa4fab
commit d7c0c38b8d
20 changed files with 558 additions and 495 deletions

View File

@@ -58,8 +58,8 @@ class PyCryptoVerifier(object):
Args:
key_pem: string, public key in PEM format.
is_x509_cert: bool, True if key_pem is an X509 cert, otherwise it is
expected to be an RSA key in PEM format.
is_x509_cert: bool, True if key_pem is an X509 cert, otherwise it
is expected to be an RSA key in PEM format.
Returns:
Verifier instance.
@@ -123,6 +123,7 @@ class PyCryptoSigner(object):
raise NotImplementedError(
'PKCS12 format is not supported by the PyCrypto library. '
'Try converting to a "PEM" '
'(openssl pkcs12 -in xxxxx.p12 -nodes -nocerts > privatekey.pem) '
'(openssl pkcs12 -in xxxxx.p12 -nodes -nocerts > '
'privatekey.pem) '
'or using PyOpenSSL if native code is an option.')
return PyCryptoSigner(pkey)

View File

@@ -132,7 +132,8 @@ def xsrf_secret_key():
model.secret = _generate_new_xsrf_secret_key()
model.put()
secret = model.secret
memcache.add(XSRF_MEMCACHE_ID, secret, namespace=OAUTH2CLIENT_NAMESPACE)
memcache.add(XSRF_MEMCACHE_ID, secret,
namespace=OAUTH2CLIENT_NAMESPACE)
return str(secret)
@@ -166,7 +167,8 @@ class AppAssertionCredentials(AssertionCredentials):
self._kwargs = kwargs
self.service_account_id = kwargs.get('service_account_id', None)
# Assertion type is no longer used, but still in the parent class signature.
# Assertion type is no longer used, but still in the
# parent class signature.
super(AppAssertionCredentials, self).__init__(None)
@classmethod
@@ -199,7 +201,8 @@ class AppAssertionCredentials(AssertionCredentials):
@property
def serialization_data(self):
raise NotImplementedError('Cannot serialize credentials for AppEngine.')
raise NotImplementedError('Cannot serialize credentials '
'for Google App Engine.')
def create_scoped_required(self):
return not self.scope
@@ -220,8 +223,8 @@ class FlowProperty(db.Property):
# For writing to datastore.
def get_value_for_datastore(self, model_instance):
flow = super(FlowProperty,
self).get_value_for_datastore(model_instance)
flow = super(FlowProperty, self).get_value_for_datastore(
model_instance)
return db.Blob(pickle.dumps(flow))
# For reading from datastore.
@@ -266,7 +269,8 @@ if ndb is not None:
logger.info('validate: Got type %s', type(value))
if value is not None and not isinstance(value, Flow):
raise TypeError('Property %s must be convertible to a flow '
'instance; received: %s.' % (self._name, value))
'instance; received: %s.' % (self._name,
value))
class CredentialsProperty(db.Property):
@@ -282,8 +286,8 @@ class CredentialsProperty(db.Property):
# For writing to datastore.
def get_value_for_datastore(self, model_instance):
logger.info("get: Got type " + str(type(model_instance)))
cred = super(CredentialsProperty,
self).get_value_for_datastore(model_instance)
cred = super(CredentialsProperty, self).get_value_for_datastore(
model_instance)
if cred is None:
cred = ''
else:
@@ -310,14 +314,10 @@ class CredentialsProperty(db.Property):
raise db.BadValueError('Property %s must be convertible '
'to a Credentials instance (%s)' %
(self.name, value))
#if value is not None and not isinstance(value, Credentials):
# return None
return value
if ndb is not None:
# TODO(dhermes): Turn this into a JsonProperty and overhaul the Credentials
# and subclass mechanics to use new_from_dict, to_dict,
# from_dict, etc.
@@ -344,8 +344,9 @@ if ndb is not None:
"""
logger.info('validate: Got type %s', type(value))
if value is not None and not isinstance(value, Credentials):
raise TypeError('Property %s must be convertible to a credentials '
'instance; received: %s.' % (self._name, value))
raise TypeError('Property %s must be convertible to a '
'credentials instance; received: %s.' %
(self._name, value))
def _to_base_type(self, value):
"""Converts our validated value to a JSON serialized string.
@@ -409,7 +410,8 @@ class StorageByKeyName(Storage):
"""
if key_name is None:
if user is None:
raise ValueError('StorageByKeyName called with no key name or user.')
raise ValueError('StorageByKeyName called with no '
'key name or user.')
key_name = user.user_id()
self._model = model
@@ -423,15 +425,17 @@ class StorageByKeyName(Storage):
Returns:
Boolean indicating whether or not the model is an NDB or DB model.
"""
# issubclass will fail if one of the arguments is not a class, only need
# worry about new-style classes since ndb and db models are new-style
# issubclass will fail if one of the arguments is not a class, only
# need worry about new-style classes since ndb and db models are
# new-style
if isinstance(self._model, type):
if ndb is not None and issubclass(self._model, ndb.Model):
return True
elif issubclass(self._model, db.Model):
return False
raise TypeError('Model class not an NDB or DB model: %s.' % (self._model, ))
raise TypeError('Model class not an NDB or DB model: %s.' %
(self._model,))
def _get_entity(self):
"""Retrieve entity from datastore.
@@ -640,7 +644,6 @@ class OAuth2Decorator(object):
_credentials_class=CredentialsModel,
_credentials_property_name='credentials',
**kwargs):
"""Constructor for OAuth2Decorator
Args:
@@ -659,13 +662,14 @@ class OAuth2Decorator(object):
provider can be used.
user_agent: string, User agent of your application, default to
None.
message: Message to display if there are problems with the OAuth 2.0
configuration. The message may contain HTML and will be
presented on the web interface for any method that uses
the decorator.
message: Message to display if there are problems with the
OAuth 2.0 configuration. The message may contain HTML and
will be presented on the web interface for any method that
uses the decorator.
callback_path: string, The absolute path to use as the callback
URI. Note that this must match up with the URI given
when registering the application in the APIs Console.
when registering the application in the APIs
Console.
token_response_param: string. If provided, the full JSON response
to the access token request will be encoded
and included in this query parameter in the
@@ -730,7 +734,8 @@ class OAuth2Decorator(object):
return
user = users.get_current_user()
# Don't use @login_decorator as this could be used in a POST request.
# Don't use @login_decorator as this could be used in a
# POST request.
if not user:
request_handler.redirect(users.create_login_url(
request_handler.request.uri))
@@ -739,7 +744,8 @@ class OAuth2Decorator(object):
self._create_flow(request_handler)
# Store the request URI in 'state' so we can use it later
self.flow.params['state'] = _build_state_value(request_handler, user)
self.flow.params['state'] = _build_state_value(
request_handler, user)
self.credentials = self._storage_class(
self._credentials_class, None,
self._credentials_property_name, user=user).get()
@@ -769,13 +775,11 @@ class OAuth2Decorator(object):
if self.flow is None:
redirect_uri = request_handler.request.relative_url(
self._callback_path) # Usually /oauth2callback
self.flow = OAuth2WebServerFlow(self._client_id, self._client_secret,
self._scope, redirect_uri=redirect_uri,
user_agent=self._user_agent,
auth_uri=self._auth_uri,
token_uri=self._token_uri,
revoke_uri=self._revoke_uri,
**self._kwargs)
self.flow = OAuth2WebServerFlow(
self._client_id, self._client_secret, self._scope,
redirect_uri=redirect_uri, user_agent=self._user_agent,
auth_uri=self._auth_uri, token_uri=self._token_uri,
revoke_uri=self._revoke_uri, **self._kwargs)
def oauth_aware(self, method):
"""Decorator that sets up for OAuth 2.0 dance, but doesn't do it.
@@ -797,7 +801,8 @@ class OAuth2Decorator(object):
return
user = users.get_current_user()
# Don't use @login_decorator as this could be used in a POST request.
# Don't use @login_decorator as this could be used in a
# POST request.
if not user:
request_handler.redirect(users.create_login_url(
request_handler.request.uri))
@@ -805,7 +810,8 @@ class OAuth2Decorator(object):
self._create_flow(request_handler)
self.flow.params['state'] = _build_state_value(request_handler, user)
self.flow.params['state'] = _build_state_value(request_handler,
user)
self.credentials = self._storage_class(
self._credentials_class, None,
self._credentials_property_name, user=user).get()
@@ -885,21 +891,26 @@ class OAuth2Decorator(object):
if error:
errormsg = self.request.get('error_description', error)
self.response.out.write(
'The authorization request failed: %s' % _safe_html(errormsg))
'The authorization request failed: %s' %
_safe_html(errormsg))
else:
user = users.get_current_user()
decorator._create_flow(self)
credentials = decorator.flow.step2_exchange(self.request.params)
credentials = decorator.flow.step2_exchange(
self.request.params)
decorator._storage_class(
decorator._credentials_class, None,
decorator._credentials_property_name, user=user).put(credentials)
redirect_uri = _parse_state_value(str(self.request.get('state')),
user)
decorator._credentials_property_name,
user=user).put(credentials)
redirect_uri = _parse_state_value(
str(self.request.get('state')), user)
if decorator._token_response_param and credentials.token_response:
if (decorator._token_response_param and
credentials.token_response):
resp_json = json.dumps(credentials.token_response)
redirect_uri = util._add_query_parameter(
redirect_uri, decorator._token_response_param, resp_json)
redirect_uri, decorator._token_response_param,
resp_json)
self.redirect(redirect_uri)
@@ -959,11 +970,13 @@ class OAuth2DecoratorFromClientSecrets(OAuth2Decorator):
**kwargs: dict, Keyword arguments are passed along as kwargs to
the OAuth2WebServerFlow constructor.
"""
client_type, client_info = clientsecrets.loadfile(filename, cache=cache)
if client_type not in [
clientsecrets.TYPE_WEB, clientsecrets.TYPE_INSTALLED]:
client_type, client_info = clientsecrets.loadfile(filename,
cache=cache)
if client_type not in (clientsecrets.TYPE_WEB,
clientsecrets.TYPE_INSTALLED):
raise InvalidClientSecretsError(
"OAuth2Decorator doesn't support this OAuth 2.0 flow.")
constructor_kwargs = dict(kwargs)
constructor_kwargs.update({
'auth_uri': client_info['auth_uri'],

View File

@@ -93,12 +93,13 @@ _CLOUDSDK_CONFIG_ENV_VAR = 'CLOUDSDK_CONFIG'
# The error message we show users when we can't find the Application
# Default Credentials.
ADC_HELP_MSG = (
'The Application Default Credentials are not available. They are available '
'if running in Google Compute Engine. Otherwise, the environment variable '
+ GOOGLE_APPLICATION_CREDENTIALS +
'The Application Default Credentials are not available. They are '
'available if running in Google Compute Engine. Otherwise, the '
'environment variable ' +
GOOGLE_APPLICATION_CREDENTIALS +
' must be defined pointing to a file defining the credentials. See '
'https://developers.google.com/accounts/docs/application-default-credentials' # pylint:disable=line-too-long
' for more information.')
'https://developers.google.com/accounts/docs/'
'application-default-credentials for more information.')
# The access token along with the seconds in which it expires.
AccessTokenInfo = collections.namedtuple(
@@ -283,16 +284,19 @@ class Credentials(object):
"""
json_string_as_unicode = _from_bytes(s)
data = json.loads(json_string_as_unicode)
# Find and call the right classmethod from_json() to restore the object.
# Find and call the right classmethod from_json() to restore
# the object.
module_name = data['_module']
try:
module_obj = __import__(module_name)
except ImportError:
# In case there's an object from the old package structure, update it
# In case there's an object from the old package structure,
# update it
module_name = module_name.replace('.googleapiclient', '')
module_obj = __import__(module_name)
module_obj = __import__(module_name, fromlist=module_name.split('.')[:-1])
module_obj = __import__(module_name,
fromlist=module_name.split('.')[:-1])
kls = getattr(module_obj, data['_class'])
from_json = getattr(kls, 'from_json')
return from_json(json_string_as_unicode)
@@ -522,10 +526,9 @@ class OAuth2Credentials(Credentials):
The modified http.request method will add authentication headers to
each request and will refresh access_tokens when a 401 is received on a
request. In addition the http.request method has a credentials property,
http.request.credentials, which is the Credentials object that
authorized it.
request. In addition the http.request method has a credentials
property, http.request.credentials, which is the Credentials object
that authorized it.
Args:
http: An instance of ``httplib2.Http`` or something that acts
@@ -552,7 +555,8 @@ class OAuth2Credentials(Credentials):
redirections=httplib2.DEFAULT_MAX_REDIRECTS,
connection_type=None):
if not self.access_token:
logger.info('Attempting refresh to obtain initial access_token')
logger.info('Attempting refresh to obtain '
'initial access_token')
self._refresh(request_orig)
# Clone and modify the request headers to add the appropriate
@@ -565,7 +569,8 @@ class OAuth2Credentials(Credentials):
if self.user_agent is not None:
if 'user-agent' in headers:
headers['user-agent'] = self.user_agent + ' ' + headers['user-agent']
headers['user-agent'] = (self.user_agent + ' ' +
headers['user-agent'])
else:
headers['user-agent'] = self.user_agent
@@ -574,23 +579,26 @@ class OAuth2Credentials(Credentials):
('read', 'seek', 'tell')):
body_stream_position = body.tell()
resp, content = request_orig(uri, method, body, clean_headers(headers),
resp, content = request_orig(uri, method, body,
clean_headers(headers),
redirections, connection_type)
# A stored token may expire between the time it is retrieved and the time
# the request is made, so we may need to try twice.
# A stored token may expire between the time it is retrieved and
# the time the request is made, so we may need to try twice.
max_refresh_attempts = 2
for refresh_attempt in range(max_refresh_attempts):
if resp.status not in REFRESH_STATUS_CODES:
break
logger.info('Refreshing due to a %s (attempt %s/%s)', resp.status,
refresh_attempt + 1, max_refresh_attempts)
logger.info('Refreshing due to a %s (attempt %s/%s)',
resp.status, refresh_attempt + 1,
max_refresh_attempts)
self._refresh(request_orig)
self.apply(headers)
if body_stream_position is not None:
body.seek(body_stream_position)
resp, content = request_orig(uri, method, body, clean_headers(headers),
resp, content = request_orig(uri, method, body,
clean_headers(headers),
redirections, connection_type)
return (resp, content)
@@ -869,8 +877,8 @@ class OAuth2Credentials(Credentials):
if self.store:
self.store.locked_put(self)
else:
# An {'error':...} response body means the token is expired or revoked,
# so we flag the credentials as such.
# An {'error':...} response body means the token is expired or
# revoked, so we flag the credentials as such.
logger.info('Failed to retrieve access token: %s', content)
error_msg = 'Invalid response %s.' % resp['status']
try:
@@ -955,7 +963,8 @@ class OAuth2Credentials(Credentials):
"""
logger.info('Refreshing scopes')
query_params = {'access_token': token, 'fields': 'scope'}
token_info_uri = _update_query_params(self.token_info_uri, query_params)
token_info_uri = _update_query_params(self.token_info_uri,
query_params)
resp, content = http_request(token_info_uri)
content = _from_bytes(content)
if resp.status == 200:
@@ -1166,8 +1175,8 @@ class GoogleCredentials(OAuth2Credentials):
is None.
"""
super(GoogleCredentials, self).__init__(
access_token, client_id, client_secret, refresh_token, token_expiry,
token_uri, user_agent, revoke_uri=revoke_uri)
access_token, client_id, client_secret, refresh_token,
token_expiry, token_uri, user_agent, revoke_uri=revoke_uri)
def create_scoped_required(self):
"""Whether this Credentials object is scopeless.
@@ -1257,14 +1266,16 @@ class GoogleCredentials(OAuth2Credentials):
if not credentials_filename:
return
# If we can read the credentials from a file, we don't need to know what
# environment we are in.
# If we can read the credentials from a file, we don't need to know
# what environment we are in.
SETTINGS.env_name = DEFAULT_ENV_NAME
try:
return _get_application_default_credential_from_file(credentials_filename)
return _get_application_default_credential_from_file(
credentials_filename)
except (ApplicationDefaultCredentialsError, ValueError) as error:
_raise_exception_for_reading_json(credentials_filename, extra_help, error)
_raise_exception_for_reading_json(credentials_filename,
extra_help, error)
@classmethod
def _get_implicit_credentials(cls):
@@ -1325,7 +1336,8 @@ class GoogleCredentials(OAuth2Credentials):
return _get_application_default_credential_from_file(
credential_filename)
except (ApplicationDefaultCredentialsError, ValueError) as error:
extra_help = ' (provided as parameter to the from_stream() method)'
extra_help = (' (provided as parameter to the '
'from_stream() method)')
_raise_exception_for_reading_json(credential_filename,
extra_help,
error)
@@ -1384,7 +1396,8 @@ def _get_environment_variable_file():
return application_default_credential_filename
else:
raise ApplicationDefaultCredentialsError(
'File ' + application_default_credential_filename + ' (pointed by ' +
'File ' + application_default_credential_filename +
' (pointed by ' +
GOOGLE_APPLICATION_CREDENTIALS +
' environment variable) does not exist!')
@@ -1403,7 +1416,8 @@ def _get_well_known_file():
default_config_dir = os.path.join(os.environ['APPDATA'],
_CLOUDSDK_CONFIG_DIRECTORY)
except KeyError:
# This should never happen unless someone is really messing with things.
# This should never happen unless someone is really
# messing with things.
drive = os.environ.get('SystemDrive', 'C:')
default_config_dir = os.path.join(drive, '\\',
_CLOUDSDK_CONFIG_DIRECTORY)
@@ -1786,9 +1800,10 @@ def credentials_from_code(client_id, client_secret, scope, code,
access token
"""
flow = OAuth2WebServerFlow(client_id, client_secret, scope,
redirect_uri=redirect_uri, user_agent=user_agent,
auth_uri=auth_uri, token_uri=token_uri,
revoke_uri=revoke_uri, device_uri=device_uri,
redirect_uri=redirect_uri,
user_agent=user_agent, auth_uri=auth_uri,
token_uri=token_uri, revoke_uri=revoke_uri,
device_uri=device_uri,
token_info_uri=token_info_uri)
credentials = flow.step2_exchange(code, http=http)
@@ -1836,8 +1851,8 @@ def credentials_from_clientsecrets_and_code(filename, scope, code,
clientsecrets.InvalidClientSecretsError: if the clientsecrets file is
invalid.
"""
flow = flow_from_clientsecrets(filename, scope, message=message, cache=cache,
redirect_uri=redirect_uri,
flow = flow_from_clientsecrets(filename, scope, message=message,
cache=cache, redirect_uri=redirect_uri,
device_uri=device_uri)
credentials = flow.step2_exchange(code, http=http)
return credentials
@@ -1875,9 +1890,9 @@ class DeviceFlowInfo(collections.namedtuple('DeviceFlowInfo', (
'user_code_expiry': None,
})
if 'expires_in' in response:
kwargs['user_code_expiry'] = datetime.datetime.now() + datetime.timedelta(
seconds=int(response['expires_in']))
kwargs['user_code_expiry'] = (
datetime.datetime.now() +
datetime.timedelta(seconds=int(response['expires_in'])))
return cls(**kwargs)
@@ -1915,7 +1930,8 @@ class OAuth2WebServerFlow(Flow):
redirect_uri: string, Either the string 'urn:ietf:wg:oauth:2.0:oob'
for a non-web-based application, or a URI that
handles the callback from the authorization server.
user_agent: string, HTTP User-Agent to provide for this application.
user_agent: string, HTTP User-Agent to provide for this
application.
auth_uri: string, URI for authorization endpoint. For convenience
defaults to Google's endpoints but any OAuth 2.0 provider
can be used.
@@ -1982,8 +1998,9 @@ class OAuth2WebServerFlow(Flow):
if redirect_uri is not None:
logger.warning((
'The redirect_uri parameter for '
'OAuth2WebServerFlow.step1_get_authorize_url is deprecated. Please '
'move to passing the redirect_uri in via the constructor.'))
'OAuth2WebServerFlow.step1_get_authorize_url is deprecated. '
'Please move to passing the redirect_uri in via the '
'constructor.'))
self.redirect_uri = redirect_uri
if self.redirect_uri is None:
@@ -2034,8 +2051,8 @@ class OAuth2WebServerFlow(Flow):
flow_info = json.loads(content)
except ValueError as e:
raise OAuth2DeviceCodeError(
'Could not parse server response as JSON: "%s", error: "%s"' % (
content, e))
'Could not parse server response as JSON: "%s", '
'error: "%s"' % (content, e))
return DeviceFlowInfo.FromResponse(flow_info)
else:
error_msg = 'Invalid response %s.' % resp.status
@@ -2044,7 +2061,8 @@ class OAuth2WebServerFlow(Flow):
if 'error' in d:
error_msg += ' Error: %s' % d['error']
except ValueError:
# Couldn't decode a JSON response, stick with the default message.
# Couldn't decode a JSON response, stick with the
# default message.
pass
raise OAuth2DeviceCodeError(error_msg)
@@ -2120,27 +2138,27 @@ class OAuth2WebServerFlow(Flow):
"reauthenticating with approval_prompt='force'.")
token_expiry = None
if 'expires_in' in d:
token_expiry = datetime.datetime.utcnow() + datetime.timedelta(
seconds=int(d['expires_in']))
token_expiry = (
datetime.datetime.utcnow() +
datetime.timedelta(seconds=int(d['expires_in'])))
extracted_id_token = None
if 'id_token' in d:
extracted_id_token = _extract_id_token(d['id_token'])
logger.info('Successfully retrieved access token')
return OAuth2Credentials(access_token, self.client_id,
self.client_secret, refresh_token, token_expiry,
self.token_uri, self.user_agent,
revoke_uri=self.revoke_uri,
id_token=extracted_id_token,
token_response=d,
scopes=self.scope,
return OAuth2Credentials(
access_token, self.client_id, self.client_secret,
refresh_token, token_expiry, self.token_uri, self.user_agent,
revoke_uri=self.revoke_uri, id_token=extracted_id_token,
token_response=d, scopes=self.scope,
token_info_uri=self.token_info_uri)
else:
logger.info('Failed to retrieve access token: %s', content)
if 'error' in d:
# you never know what those providers got to say
error_msg = str(d['error']) + str(d.get('error_description', ''))
error_msg = (str(d['error']) +
str(d.get('error_description', '')))
else:
error_msg = 'Invalid response: %s.' % str(resp.status)
raise FlowExchangeError(error_msg)
@@ -2187,8 +2205,10 @@ def flow_from_clientsecrets(filename, scope, redirect_uri=None,
invalid.
"""
try:
client_type, client_info = clientsecrets.loadfile(filename, cache=cache)
if client_type in (clientsecrets.TYPE_WEB, clientsecrets.TYPE_INSTALLED):
client_type, client_info = clientsecrets.loadfile(filename,
cache=cache)
if client_type in (clientsecrets.TYPE_WEB,
clientsecrets.TYPE_INSTALLED):
constructor_kwargs = {
'redirect_uri': redirect_uri,
'auth_uri': client_info['auth_uri'],

View File

@@ -83,13 +83,14 @@ def _validate_clientsecrets(obj):
'"installed" application')
client_type = tuple(obj)[0]
if client_type not in VALID_CLIENT:
raise InvalidClientSecretsError('Unknown client type: %s.' % (client_type, ))
raise InvalidClientSecretsError(
'Unknown client type: %s.' % (client_type,))
client_info = obj[client_type]
for prop_name in VALID_CLIENT[client_type]['required']:
if prop_name not in client_info:
raise InvalidClientSecretsError(
'Missing property "%s" in a client type of "%s".' % (prop_name,
client_type))
'Missing property "%s" in a client type of "%s".' %
(prop_name, client_type))
for prop_name in VALID_CLIENT[client_type]['string']:
if client_info[prop_name].startswith('[['):
raise InvalidClientSecretsError(

View File

@@ -45,11 +45,9 @@ except ImportError:
OpenSSLVerifier = None
OpenSSLSigner = None
def pkcs12_key_as_pem(*args, **kwargs):
raise NotImplementedError('pkcs12_key_as_pem requires OpenSSL.')
try:
from oauth2client._pycrypto_crypt import PyCryptoVerifier
from oauth2client._pycrypto_crypt import PyCryptoSigner

View File

@@ -35,8 +35,9 @@ class CommunicationError(Error):
class NoDevshellServer(Error):
"""Error when no Developer Shell server can be contacted."""
# The request for credential information to the Developer Shell client socket is
# always an empty PBLite-formatted JSON object, so just define it as a constant.
# The request for credential information to the Developer Shell client socket
# is always an empty PBLite-formatted JSON object, so just define it as a
# constant.
CREDENTIAL_INFO_REQUEST_JSON = '[]'
@@ -44,7 +45,9 @@ class CredentialInfoResponse(object):
"""Credential information response from Developer Shell server.
The credential information response from Developer Shell socket is a
PBLite-formatted JSON array with fields encoded by their index in the array:
PBLite-formatted JSON array with fields encoded by their index in the
array:
* Index 0 - user email
* Index 1 - default project ID. None if the project context is not known.
* Index 2 - OAuth2 access token. None if there is no valid auth context.

View File

@@ -93,7 +93,8 @@ class Storage(BaseStorage):
Args:
model: db.Model, model class
key_name: string, key name for the entity that has the credentials
key_value: string, key value for the entity that has the credentials
key_value: string, key value for the entity that has the
credentials
property_name: string, name of the property that is an
CredentialsProperty
"""
@@ -124,12 +125,14 @@ class Storage(BaseStorage):
Args:
credentials: Credentials, the credentials to store.
overwrite: Boolean, indicates whether you would like these
credentials to overwrite any existing stored credentials.
credentials to overwrite any existing stored
credentials.
"""
args = {self.key_name: self.key_value}
if overwrite:
entity, unused_is_new = self.model_class.objects.get_or_create(**args)
(entity,
unused_is_new) = self.model_class.objects.get_or_create(**args)
else:
entity = self.model_class(**args)

View File

@@ -46,8 +46,8 @@ apiui/credential>`__.
Usage
=====
Once configured, you can use the :meth:`UserOAuth2.required` decorator to ensure
that credentials are available within a view.
Once configured, you can use the :meth:`UserOAuth2.required` decorator to
ensure that credentials are available within a view.
.. code-block:: python
:emphasize-lines: 3,7,10
@@ -291,8 +291,9 @@ class UserOAuth2(object):
raise ValueError(
'OAuth2 configuration could not be found. Either specify the '
'client_secrets_file or client_id and client_secret or set the'
'app configuration variables GOOGLE_OAUTH2_CLIENT_SECRETS_FILE '
'or GOOGLE_OAUTH2_CLIENT_ID and GOOGLE_OAUTH2_CLIENT_SECRET.')
'app configuration variables '
'GOOGLE_OAUTH2_CLIENT_SECRETS_FILE or '
'GOOGLE_OAUTH2_CLIENT_ID and GOOGLE_OAUTH2_CLIENT_SECRET.')
def _load_client_secrets(self, filename):
"""Loads client secrets from the given filename."""
@@ -392,7 +393,8 @@ class UserOAuth2(object):
credentials = flow.step2_exchange(code)
except FlowExchangeError as exchange_error:
current_app.logger.exception(exchange_error)
return 'An error occurred: %s' % exchange_error, httplib.BAD_REQUEST
content = 'An error occurred: %s' % (exchange_error,)
return content, httplib.BAD_REQUEST
# Save the credentials to the storage.
self.storage.put(credentials)
@@ -420,9 +422,9 @@ class UserOAuth2(object):
def email(self):
"""Returns the user's email address or None if there are no credentials.
The email address is provided by the current credentials' id_token. This
should not be used as unique identifier as the user can change their
email. If you need a unique identifier, use user_id.
The email address is provided by the current credentials' id_token.
This should not be used as unique identifier as the user can change
their email. If you need a unique identifier, use user_id.
"""
if not self.credentials:
return None
@@ -451,8 +453,9 @@ class UserOAuth2(object):
def authorize_url(self, return_url, **kwargs):
"""Creates a URL that can be used to start the authorization flow.
When the user is directed to the URL, the authorization flow will begin.
Once complete, the user will be redirected to the specified return URL.
When the user is directed to the URL, the authorization flow will
begin. Once complete, the user will be redirected to the specified
return URL.
Any kwargs are passed into the flow constructor.
"""

View File

@@ -44,9 +44,9 @@ class AppAssertionCredentials(AssertionCredentials):
used for the purpose of accessing data stored under an account assigned to
the Compute Engine instance itself.
This credential does not require a flow to instantiate because it represents
a two legged flow, and therefore has all of the required information to
generate and refresh its own access tokens.
This credential does not require a flow to instantiate because it
represents a two legged flow, and therefore has all of the required
information to generate and refresh its own access tokens.
"""
@util.positional(2)
@@ -60,7 +60,8 @@ class AppAssertionCredentials(AssertionCredentials):
self.scope = util.scopes_to_string(scope)
self.kwargs = kwargs
# Assertion type is no longer used, but still in the parent class signature.
# Assertion type is no longer used, but still in the
# parent class signature.
super(AppAssertionCredentials, self).__init__(None)
@classmethod
@@ -74,9 +75,9 @@ class AppAssertionCredentials(AssertionCredentials):
Skip all the storage hoops and just refresh using the API.
Args:
http_request: callable, a callable that matches the method signature
of httplib2.Http.request, used to make the refresh
request.
http_request: callable, a callable that matches the method
signature of httplib2.Http.request, used to make
the refresh request.
Raises:
AccessTokenRefreshError: When the refresh fails.

View File

@@ -176,7 +176,6 @@ class _PosixOpener(_Opener):
try:
import fcntl
class _FcntlOpener(_Opener):
"""Open, lock, and unlock a file using fcntl.lockf."""
@@ -190,7 +189,8 @@ try:
Raises:
AlreadyLockedException: if the lock is already acquired.
IOError: if the open fails.
CredentialsFileSymbolicLinkError if the file is a symbolic link.
CredentialsFileSymbolicLinkError: if the file is a symbolic
link.
"""
if self._locked:
raise AlreadyLockedException('File %s is already locked' %
@@ -201,7 +201,8 @@ try:
try:
self._fh = open(self._filename, self._mode)
except IOError as e:
# If we can't access with _mode, try _fallback_mode and don't lock.
# If we can't access with _mode, try _fallback_mode and
# don't lock.
if e.errno in (errno.EPERM, errno.EACCES):
self._fh = open(self._filename, self._fallback_mode)
return
@@ -244,7 +245,6 @@ try:
import win32con
import win32file
class _Win32Opener(_Opener):
"""Open, lock, and unlock a file using windows primitives."""
@@ -278,7 +278,8 @@ try:
try:
self._fh = open(self._filename, self._mode)
except IOError as e:
# If we can't access with _mode, try _fallback_mode and don't lock.
# If we can't access with _mode, try _fallback_mode
# and don't lock.
if e.errno == errno.EACCES:
self._fh = open(self._filename, self._fallback_mode)
return
@@ -298,7 +299,8 @@ try:
if timeout == 0:
raise
# If the error is not that the file is already in use, raise.
# If the error is not that the file is already
# in use, raise.
if e[0] != _Win32Opener.FILE_IN_USE_ERROR:
raise
@@ -317,7 +319,8 @@ try:
if self._locked:
try:
hfile = win32file._get_osfhandle(self._fh.fileno())
win32file.UnlockFileEx(hfile, 0, -0x10000, pywintypes.OVERLAPPED())
win32file.UnlockFileEx(hfile, 0, -0x10000,
pywintypes.OVERLAPPED())
except pywintypes.error as e:
if e[0] != _Win32Opener.FILE_ALREADY_UNLOCKED_ERROR:
raise

View File

@@ -97,8 +97,8 @@ def get_credential_storage(filename, client_id, user_agent, scope,
@util.positional(2)
def get_credential_storage_custom_string_key(
filename, key_string, warn_on_readonly=True):
def get_credential_storage_custom_string_key(filename, key_string,
warn_on_readonly=True):
"""Get a Storage instance for a credential using a single string as a key.
Allows you to provide a string as a custom key that will be used for
@@ -120,8 +120,8 @@ def get_credential_storage_custom_string_key(
@util.positional(2)
def get_credential_storage_custom_key(
filename, key_dict, warn_on_readonly=True):
def get_credential_storage_custom_key(filename, key_dict,
warn_on_readonly=True):
"""Get a Storage instance for a credential using a dictionary as a key.
Allows you to provide a dictionary as a custom key that will be used for
@@ -211,7 +211,7 @@ class _MultiStore(object):
self._data = None
class _Storage(BaseStorage):
"""A Storage object that knows how to read/write a single credential."""
"""A Storage object that can read/write a single credential."""
def __init__(self, multistore, key):
self._multistore = multistore
@@ -285,8 +285,8 @@ class _MultiStore(object):
self._file.open_and_lock()
except IOError as e:
if e.errno == errno.ENOSYS:
logger.warn('File system does not support locking the credentials '
'file.')
logger.warn('File system does not support locking the '
'credentials file.')
elif e.errno == errno.ENOLCK:
logger.warn('File system is out of resources for writing the '
'credentials file (is your disk full?).')
@@ -295,8 +295,9 @@ class _MultiStore(object):
if not self._file.is_locked():
self._read_only = True
if self._warn_on_readonly:
logger.warn('The credentials file (%s) is not writable. Opening in '
'read-only mode. Any refreshed credentials will only be '
logger.warn('The credentials file (%s) is not writable. '
'Opening in read-only mode. Any refreshed '
'credentials will only be '
'valid for this run.', self._file.filename())
if os.path.getsize(self._file.filename()) == 0:
logger.debug('Initializing empty multistore file')
@@ -340,7 +341,8 @@ class _MultiStore(object):
if self._read_only:
return
self._file.file_handle().seek(0)
json.dump(data, self._file.file_handle(), sort_keys=True, indent=2, separators=(',', ': '))
json.dump(data, self._file.file_handle(),
sort_keys=True, indent=2, separators=(',', ': '))
self._file.file_handle().truncate()
def _refresh_data_cache(self):
@@ -379,11 +381,12 @@ class _MultiStore(object):
for cred_entry in credentials:
try:
(key, credential) = self._decode_credential_from_json(cred_entry)
key, credential = self._decode_credential_from_json(cred_entry)
self._data[key] = credential
except:
# If something goes wrong loading a credential, just ignore it
logger.info('Error decoding credential, skipping', exc_info=True)
logger.info('Error decoding credential, skipping',
exc_info=True)
def _decode_credential_from_json(self, cred_entry):
"""Load a credential from our JSON serialization.
@@ -398,7 +401,8 @@ class _MultiStore(object):
raw_key = cred_entry['key']
key = util.dict_to_tuple_key(raw_key)
credential = None
credential = Credentials.new_from_json(json.dumps(cred_entry['credential']))
credential = Credentials.new_from_json(
json.dumps(cred_entry['credential']))
return (key, credential)
def _write(self):

View File

@@ -72,7 +72,8 @@ def run(flow, storage, http=None):
of values.
``--[no]auth_local_webserver`` (boolean, default: ``True``)
Run a local web server to handle redirects during OAuth authorization.
Run a local web server to handle redirects during OAuth
authorization.
Since it uses flags make sure to initialize the ``gflags`` module before
calling ``run()``.
@@ -87,8 +88,8 @@ def run(flow, storage, http=None):
Credentials, the obtained credential.
"""
logging.warning('This function, oauth2client.tools.run(), and the use of '
'the gflags library are deprecated and will be removed in a future '
'version of the library.')
'the gflags library are deprecated and will be removed in '
'a future version of the library.')
if FLAGS.auth_local_webserver:
success = False
port_number = 0
@@ -104,7 +105,8 @@ def run(flow, storage, http=None):
break
FLAGS.auth_local_webserver = success
if not success:
print('Failed to start a local webserver listening on either port 8080')
print('Failed to start a local webserver listening on '
'either port 8080')
print('or port 9090. Please check your firewall settings and locally')
print('running programs that may be blocking or using those ports.')
print()
@@ -144,7 +146,8 @@ def run(flow, storage, http=None):
if 'code' in httpd.query_params:
code = httpd.query_params['code']
else:
print('Failed to find "code" in the query parameters of the redirect.')
print('Failed to find "code" in the query '
'parameters of the redirect.')
sys.exit('Try running with --noauth_local_webserver.')
else:
code = input('Enter verification code: ').strip()

View File

@@ -38,13 +38,14 @@ class _ServiceAccountCredentials(AssertionCredentials):
MAX_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
def __init__(self, service_account_id, service_account_email, private_key_id,
private_key_pkcs8_text, scopes, user_agent=None,
token_uri=GOOGLE_TOKEN_URI, revoke_uri=GOOGLE_REVOKE_URI,
**kwargs):
def __init__(self, service_account_id, service_account_email,
private_key_id, private_key_pkcs8_text, scopes,
user_agent=None, token_uri=GOOGLE_TOKEN_URI,
revoke_uri=GOOGLE_REVOKE_URI, **kwargs):
super(_ServiceAccountCredentials, self).__init__(
None, user_agent=user_agent, token_uri=token_uri, revoke_uri=revoke_uri)
None, user_agent=user_agent, token_uri=token_uri,
revoke_uri=revoke_uri)
self._service_account_id = service_account_id
self._service_account_email = service_account_email
@@ -81,7 +82,8 @@ class _ServiceAccountCredentials(AssertionCredentials):
assertion_input = first_segment + b'.' + second_segment
# Sign the assertion.
rsa_bytes = rsa.pkcs1.sign(assertion_input, self._private_key, 'SHA-256')
rsa_bytes = rsa.pkcs1.sign(assertion_input, self._private_key,
'SHA-256')
signature = base64.urlsafe_b64encode(rsa_bytes).rstrip(b'=')
return assertion_input + b'.' + signature

View File

@@ -60,7 +60,8 @@ def _CreateArgumentParser():
default=False, help='Do not run a local web server.')
parser.add_argument('--auth_host_port', default=[8080, 8090], type=int,
nargs='*', help='Port web server should listen on.')
parser.add_argument('--logging_level', default='ERROR',
parser.add_argument(
'--logging_level', default='ERROR',
choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
help='Set the logging level of detail.')
return parser
@@ -100,12 +101,14 @@ class ClientRedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):
query = self.path.split('?', 1)[-1]
query = dict(urllib.parse.parse_qsl(query))
self.server.query_params = query
self.wfile.write(b"<html><head><title>Authentication Status</title></head>")
self.wfile.write(b"<body><p>The authentication flow has completed.</p>")
self.wfile.write(
b"<html><head><title>Authentication Status</title></head>")
self.wfile.write(
b"<body><p>The authentication flow has completed.</p>")
self.wfile.write(b"</body></html>")
def log_message(self, format, *args):
"""Do not log messages to stdout while running as command line program."""
"""Do not log messages to stdout while running as cmd. line program."""
@util.positional(3)
@@ -137,9 +140,9 @@ def run_flow(flow, storage, flags, http=None):
Run a local web server to handle redirects during OAuth
authorization.
The tools module defines an ``ArgumentParser`` the already contains the flag
definitions that ``run()`` requires. You can pass that ``ArgumentParser`` to
your ``ArgumentParser`` constructor::
The tools module defines an ``ArgumentParser`` the already contains the
flag definitions that ``run()`` requires. You can pass that
``ArgumentParser`` to your ``ArgumentParser`` constructor::
parser = argparse.ArgumentParser(
description=__doc__,
@@ -175,7 +178,8 @@ def run_flow(flow, storage, flags, http=None):
break
flags.noauth_local_webserver = not success
if not success:
print('Failed to start a local webserver listening on either port 8080')
print('Failed to start a local webserver listening '
'on either port 8080')
print('or port 9090. Please check your firewall settings and locally')
print('running programs that may be blocking or using those ports.')
print()
@@ -197,7 +201,8 @@ def run_flow(flow, storage, flags, http=None):
print()
print(' ' + authorize_url)
print()
print('If your browser is on a different machine then exit and re-run this')
print('If your browser is on a different machine then '
'exit and re-run this')
print('application with the command-line parameter ')
print()
print(' --noauth_local_webserver')
@@ -216,7 +221,8 @@ def run_flow(flow, storage, flags, http=None):
if 'code' in httpd.query_params:
code = httpd.query_params['code']
else:
print('Failed to find "code" in the query parameters of the redirect.')
print('Failed to find "code" in the query parameters '
'of the redirect.')
sys.exit('Try running with --noauth_local_webserver.')
else:
code = input('Enter verification code: ').strip()
@@ -235,9 +241,9 @@ def run_flow(flow, storage, flags, http=None):
def message_if_missing(filename):
"""Helpful message to display if the CLIENT_SECRETS file is missing."""
return _CLIENT_SECRETS_MESSAGE % filename
try:
from oauth2client.old_run import run
from oauth2client.old_run import FLAGS

View File

@@ -129,8 +129,10 @@ def positional(max_positional_args):
plural_s = ''
if max_positional_args != 1:
plural_s = 's'
message = '%s() takes at most %d positional argument%s (%d given)' % (
wrapped.__name__, max_positional_args, plural_s, len(args))
message = ('%s() takes at most %d positional '
'argument%s (%d given)' % (
wrapped.__name__, max_positional_args,
plural_s, len(args)))
if positional_parameters_enforcement == POSITIONAL_EXCEPTION:
raise TypeError(message)
elif positional_parameters_enforcement == POSITIONAL_WARNING: