Making oauth2client/ files pass PEP8.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user