mirror of
https://github.com/GAM-team/GAM.git
synced 2025-07-09 14:13:35 +00:00
Update google libraries
This commit is contained in:
@ -18,13 +18,9 @@ import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import six
|
||||
|
||||
from google.auth import environment_vars
|
||||
import google.oauth2.credentials
|
||||
|
||||
# The Google OAuth 2.0 token endpoint. Used for authorized user credentials.
|
||||
_GOOGLE_OAUTH2_TOKEN_ENDPOINT = 'https://accounts.google.com/o/oauth2/token'
|
||||
|
||||
# The ~/.config subdirectory containing gcloud credentials.
|
||||
_CONFIG_DIRECTORY = 'gcloud'
|
||||
@ -94,20 +90,8 @@ def load_authorized_user_credentials(info):
|
||||
Raises:
|
||||
ValueError: if the info is in the wrong format or missing data.
|
||||
"""
|
||||
keys_needed = set(('refresh_token', 'client_id', 'client_secret'))
|
||||
missing = keys_needed.difference(six.iterkeys(info))
|
||||
|
||||
if missing:
|
||||
raise ValueError(
|
||||
'Authorized user info was not in the expected format, missing '
|
||||
'fields {}.'.format(', '.join(missing)))
|
||||
|
||||
return google.oauth2.credentials.Credentials(
|
||||
None, # No access token, must be refreshed.
|
||||
refresh_token=info['refresh_token'],
|
||||
token_uri=_GOOGLE_OAUTH2_TOKEN_ENDPOINT,
|
||||
client_id=info['client_id'],
|
||||
client_secret=info['client_secret'])
|
||||
return google.oauth2.credentials.Credentials.from_authorized_user_info(
|
||||
info)
|
||||
|
||||
|
||||
def get_project_id():
|
||||
|
@ -22,6 +22,8 @@ import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
import six
|
||||
|
||||
from google.auth import environment_vars
|
||||
from google.auth import exceptions
|
||||
import google.auth.transport._http_client
|
||||
@ -67,9 +69,11 @@ def _load_credentials_from_file(filename):
|
||||
with io.open(filename, 'r') as file_obj:
|
||||
try:
|
||||
info = json.load(file_obj)
|
||||
except ValueError as exc:
|
||||
raise exceptions.DefaultCredentialsError(
|
||||
'File {} is not a valid json file.'.format(filename), exc)
|
||||
except ValueError as caught_exc:
|
||||
new_exc = exceptions.DefaultCredentialsError(
|
||||
'File {} is not a valid json file.'.format(filename),
|
||||
caught_exc)
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
|
||||
# The type key should indicate that the file is either a service account
|
||||
# credentials file or an authorized user credentials file.
|
||||
@ -80,10 +84,11 @@ def _load_credentials_from_file(filename):
|
||||
|
||||
try:
|
||||
credentials = _cloud_sdk.load_authorized_user_credentials(info)
|
||||
except ValueError as exc:
|
||||
raise exceptions.DefaultCredentialsError(
|
||||
'Failed to load authorized user credentials from {}'.format(
|
||||
filename), exc)
|
||||
except ValueError as caught_exc:
|
||||
msg = 'Failed to load authorized user credentials from {}'.format(
|
||||
filename)
|
||||
new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
# Authorized user credentials do not contain the project ID.
|
||||
return credentials, None
|
||||
|
||||
@ -93,10 +98,11 @@ def _load_credentials_from_file(filename):
|
||||
try:
|
||||
credentials = (
|
||||
service_account.Credentials.from_service_account_info(info))
|
||||
except ValueError as exc:
|
||||
raise exceptions.DefaultCredentialsError(
|
||||
'Failed to load service account credentials from {}'.format(
|
||||
filename), exc)
|
||||
except ValueError as caught_exc:
|
||||
msg = 'Failed to load service account credentials from {}'.format(
|
||||
filename)
|
||||
new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
return credentials, info.get('project_id')
|
||||
|
||||
else:
|
||||
@ -123,12 +129,6 @@ def _get_gcloud_sdk_credentials():
|
||||
if not project_id:
|
||||
project_id = _cloud_sdk.get_project_id()
|
||||
|
||||
if not project_id:
|
||||
_LOGGER.warning(
|
||||
'No project ID could be determined from the Cloud SDK '
|
||||
'configuration. Consider running `gcloud config set project` or '
|
||||
'setting the %s environment variable', environment_vars.PROJECT)
|
||||
|
||||
return credentials, project_id
|
||||
|
||||
|
||||
@ -141,12 +141,6 @@ def _get_explicit_environ_credentials():
|
||||
credentials, project_id = _load_credentials_from_file(
|
||||
os.environ[environment_vars.CREDENTIALS])
|
||||
|
||||
if not project_id:
|
||||
_LOGGER.warning(
|
||||
'No project ID could be determined from the credentials at %s '
|
||||
'Consider setting the %s environment variable',
|
||||
environment_vars.CREDENTIALS, environment_vars.PROJECT)
|
||||
|
||||
return credentials, project_id
|
||||
|
||||
else:
|
||||
@ -182,10 +176,6 @@ def _get_gce_credentials(request=None):
|
||||
try:
|
||||
project_id = _metadata.get_project_id(request=request)
|
||||
except exceptions.TransportError:
|
||||
_LOGGER.warning(
|
||||
'No project ID could be determined from the Compute Engine '
|
||||
'metadata service. Consider setting the %s environment '
|
||||
'variable.', environment_vars.PROJECT)
|
||||
project_id = None
|
||||
|
||||
return compute_engine.Credentials(), project_id
|
||||
@ -281,6 +271,13 @@ def default(scopes=None, request=None):
|
||||
credentials, project_id = checker()
|
||||
if credentials is not None:
|
||||
credentials = with_scopes_if_required(credentials, scopes)
|
||||
return credentials, explicit_project_id or project_id
|
||||
effective_project_id = explicit_project_id or project_id
|
||||
if not effective_project_id:
|
||||
_LOGGER.warning(
|
||||
'No project ID could be determined. Consider running '
|
||||
'`gcloud config set project` or setting the %s '
|
||||
'environment variable',
|
||||
environment_vars.PROJECT)
|
||||
return credentials, effective_project_id
|
||||
|
||||
raise exceptions.DefaultCredentialsError(_HELP_MESSAGE)
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import six
|
||||
|
||||
from google.auth import _helpers
|
||||
import google.auth.app_engine
|
||||
import google.oauth2.credentials
|
||||
@ -30,8 +32,9 @@ try:
|
||||
import oauth2client.client
|
||||
import oauth2client.contrib.gce
|
||||
import oauth2client.service_account
|
||||
except ImportError:
|
||||
raise ImportError('oauth2client is not installed.')
|
||||
except ImportError as caught_exc:
|
||||
six.raise_from(
|
||||
ImportError('oauth2client is not installed.'), caught_exc)
|
||||
|
||||
try:
|
||||
import oauth2client.contrib.appengine
|
||||
@ -162,5 +165,6 @@ def convert(credentials):
|
||||
|
||||
try:
|
||||
return _CLASS_CONVERSION_MAP[credentials_class](credentials)
|
||||
except KeyError:
|
||||
raise ValueError(_CONVERT_ERROR_TMPL.format(credentials_class))
|
||||
except KeyError as caught_exc:
|
||||
new_exc = ValueError(_CONVERT_ERROR_TMPL.format(credentials_class))
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
|
@ -22,6 +22,7 @@ import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
import six
|
||||
from six.moves import http_client
|
||||
from six.moves.urllib import parse as urlparse
|
||||
|
||||
@ -118,10 +119,11 @@ def get(request, path, root=_METADATA_ROOT, recursive=False):
|
||||
if response.headers['content-type'] == 'application/json':
|
||||
try:
|
||||
return json.loads(content)
|
||||
except ValueError:
|
||||
raise exceptions.TransportError(
|
||||
except ValueError as caught_exc:
|
||||
new_exc = exceptions.TransportError(
|
||||
'Received invalid JSON from the Google Compute Engine'
|
||||
'metadata service: {:.20}'.format(content))
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
else:
|
||||
return content
|
||||
else:
|
||||
|
@ -19,6 +19,8 @@ Engine using the Compute Engine metadata server.
|
||||
|
||||
"""
|
||||
|
||||
import six
|
||||
|
||||
from google.auth import credentials
|
||||
from google.auth import exceptions
|
||||
from google.auth.compute_engine import _metadata
|
||||
@ -89,8 +91,9 @@ class Credentials(credentials.ReadOnlyScoped, credentials.Credentials):
|
||||
self.token, self.expiry = _metadata.get_service_account_token(
|
||||
request,
|
||||
service_account=self._service_account_email)
|
||||
except exceptions.TransportError as exc:
|
||||
raise exceptions.RefreshError(exc)
|
||||
except exceptions.TransportError as caught_exc:
|
||||
new_exc = exceptions.RefreshError(caught_exc)
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
|
||||
@property
|
||||
def service_account_email(self):
|
||||
|
@ -122,6 +122,43 @@ class Credentials(object):
|
||||
self.apply(headers)
|
||||
|
||||
|
||||
class AnonymousCredentials(Credentials):
|
||||
"""Credentials that do not provide any authentication information.
|
||||
|
||||
These are useful in the case of services that support anonymous access or
|
||||
local service emulators that do not use credentials.
|
||||
"""
|
||||
|
||||
@property
|
||||
def expired(self):
|
||||
"""Returns `False`, anonymous credentials never expire."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def valid(self):
|
||||
"""Returns `True`, anonymous credentials are always valid."""
|
||||
return True
|
||||
|
||||
def refresh(self, request):
|
||||
"""Raises :class:`ValueError``, anonymous credentials cannot be
|
||||
refreshed."""
|
||||
raise ValueError("Anonymous credentials cannot be refreshed.")
|
||||
|
||||
def apply(self, headers, token=None):
|
||||
"""Anonymous credentials do nothing to the request.
|
||||
|
||||
The optional ``token`` argument is not supported.
|
||||
|
||||
Raises:
|
||||
ValueError: If a token was specified.
|
||||
"""
|
||||
if token is not None:
|
||||
raise ValueError("Anonymous credentials don't support tokens.")
|
||||
|
||||
def before_request(self, request, method, url, headers):
|
||||
"""Anonymous credentials do nothing to the request."""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class ReadOnlyScoped(object):
|
||||
"""Interface for credentials whose scopes can be queried.
|
||||
@ -136,7 +173,7 @@ class ReadOnlyScoped(object):
|
||||
|
||||
if credentials.requires_scopes:
|
||||
# Scoping is required.
|
||||
credentials = credentials.create_scoped(['one', 'two'])
|
||||
credentials = credentials.with_scopes(scopes=['one', 'two'])
|
||||
|
||||
Credentials that require scopes must either be constructed with scopes::
|
||||
|
||||
@ -172,6 +209,9 @@ class ReadOnlyScoped(object):
|
||||
.. warning: This method is not guaranteed to be accurate if the
|
||||
credentials are :attr:`~Credentials.invalid`.
|
||||
|
||||
Args:
|
||||
scopes (Sequence[str]): The list of scopes to check.
|
||||
|
||||
Returns:
|
||||
bool: True if the credentials have the given scopes.
|
||||
"""
|
||||
@ -211,7 +251,8 @@ class Scoped(ReadOnlyScoped):
|
||||
"""Create a copy of these credentials with the specified scopes.
|
||||
|
||||
Args:
|
||||
scopes (Sequence[str]): The list of scopes to request.
|
||||
scopes (Sequence[str]): The list of scopes to attach to the
|
||||
current credentials.
|
||||
|
||||
Raises:
|
||||
NotImplementedError: If the credentials' scopes can not be changed.
|
||||
|
@ -29,7 +29,7 @@ If you're going to verify many messages with the same certificate, you can use
|
||||
To sign messages use :class:`RSASigner` with a private key::
|
||||
|
||||
private_key = open('private_key.pem').read()
|
||||
signer = crypt.RSASigner(private_key)
|
||||
signer = crypt.RSASigner.from_string(private_key)
|
||||
signature = signer.sign(message)
|
||||
"""
|
||||
|
||||
|
@ -47,6 +47,7 @@ import datetime
|
||||
import json
|
||||
|
||||
import cachetools
|
||||
import six
|
||||
from six.moves import urllib
|
||||
|
||||
from google.auth import _helpers
|
||||
@ -101,8 +102,9 @@ def _decode_jwt_segment(encoded_section):
|
||||
section_bytes = _helpers.padded_urlsafe_b64decode(encoded_section)
|
||||
try:
|
||||
return json.loads(section_bytes.decode('utf-8'))
|
||||
except ValueError:
|
||||
raise ValueError('Can\'t parse segment: {0}'.format(section_bytes))
|
||||
except ValueError as caught_exc:
|
||||
new_exc = ValueError('Can\'t parse segment: {0}'.format(section_bytes))
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
|
||||
|
||||
def _unverified_decode(token):
|
||||
|
@ -17,6 +17,7 @@
|
||||
import logging
|
||||
import socket
|
||||
|
||||
import six
|
||||
from six.moves import http_client
|
||||
from six.moves import urllib
|
||||
|
||||
@ -104,8 +105,9 @@ class Request(transport.Request):
|
||||
response = connection.getresponse()
|
||||
return Response(response)
|
||||
|
||||
except (http_client.HTTPException, socket.error) as exc:
|
||||
raise exceptions.TransportError(exc)
|
||||
except (http_client.HTTPException, socket.error) as caught_exc:
|
||||
new_exc = exceptions.TransportError(caught_exc)
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
|
||||
finally:
|
||||
connection.close()
|
||||
|
@ -16,13 +16,17 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import six
|
||||
try:
|
||||
import grpc
|
||||
except ImportError: # pragma: NO COVER
|
||||
raise ImportError(
|
||||
'gRPC is not installed, please install the grpcio package to use the '
|
||||
'gRPC transport.')
|
||||
import six
|
||||
except ImportError as caught_exc: # pragma: NO COVER
|
||||
six.raise_from(
|
||||
ImportError(
|
||||
'gRPC is not installed, please install the grpcio package '
|
||||
'to use the gRPC transport.'
|
||||
),
|
||||
caught_exc,
|
||||
)
|
||||
|
||||
|
||||
class AuthMetadataPlugin(grpc.AuthMetadataPlugin):
|
||||
|
@ -16,15 +16,23 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import functools
|
||||
import logging
|
||||
|
||||
try:
|
||||
import requests
|
||||
except ImportError: # pragma: NO COVER
|
||||
raise ImportError(
|
||||
'The requests library is not installed, please install the requests '
|
||||
'package to use the requests transport.')
|
||||
import requests.exceptions
|
||||
except ImportError as caught_exc: # pragma: NO COVER
|
||||
import six
|
||||
six.raise_from(
|
||||
ImportError(
|
||||
'The requests library is not installed, please install the '
|
||||
'requests package to use the requests transport.'
|
||||
),
|
||||
caught_exc,
|
||||
)
|
||||
import requests.adapters # pylint: disable=ungrouped-imports
|
||||
import requests.exceptions # pylint: disable=ungrouped-imports
|
||||
import six # pylint: disable=ungrouped-imports
|
||||
|
||||
from google.auth import exceptions
|
||||
from google.auth import transport
|
||||
@ -111,8 +119,9 @@ class Request(transport.Request):
|
||||
method, url, data=body, headers=headers, timeout=timeout,
|
||||
**kwargs)
|
||||
return _Response(response)
|
||||
except requests.exceptions.RequestException as exc:
|
||||
raise exceptions.TransportError(exc)
|
||||
except requests.exceptions.RequestException as caught_exc:
|
||||
new_exc = exceptions.TransportError(caught_exc)
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
|
||||
|
||||
class AuthorizedSession(requests.Session):
|
||||
@ -139,22 +148,35 @@ class AuthorizedSession(requests.Session):
|
||||
retried.
|
||||
max_refresh_attempts (int): The maximum number of times to attempt to
|
||||
refresh the credentials and retry the request.
|
||||
refresh_timeout (Optional[int]): The timeout value in seconds for
|
||||
credential refresh HTTP requests.
|
||||
kwargs: Additional arguments passed to the :class:`requests.Session`
|
||||
constructor.
|
||||
"""
|
||||
def __init__(self, credentials,
|
||||
refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,
|
||||
max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,
|
||||
refresh_timeout=None,
|
||||
**kwargs):
|
||||
super(AuthorizedSession, self).__init__(**kwargs)
|
||||
self.credentials = credentials
|
||||
self._refresh_status_codes = refresh_status_codes
|
||||
self._max_refresh_attempts = max_refresh_attempts
|
||||
self._refresh_timeout = refresh_timeout
|
||||
|
||||
auth_request_session = requests.Session()
|
||||
|
||||
# Using an adapter to make HTTP requests robust to network errors.
|
||||
# This adapter retrys HTTP requests when network errors occur
|
||||
# and the requests seems safely retryable.
|
||||
retry_adapter = requests.adapters.HTTPAdapter(max_retries=3)
|
||||
auth_request_session.mount("https://", retry_adapter)
|
||||
|
||||
# Request instance used by internal methods (for example,
|
||||
# credentials.refresh).
|
||||
# Do not pass `self` as the session here, as it can lead to infinite
|
||||
# recursion.
|
||||
self._auth_request = Request()
|
||||
self._auth_request = Request(auth_request_session)
|
||||
|
||||
def request(self, method, url, data=None, headers=None, **kwargs):
|
||||
"""Implementation of Requests' request."""
|
||||
@ -191,7 +213,9 @@ class AuthorizedSession(requests.Session):
|
||||
response.status_code, _credential_refresh_attempt + 1,
|
||||
self._max_refresh_attempts)
|
||||
|
||||
self.credentials.refresh(self._auth_request)
|
||||
auth_request_with_timeout = functools.partial(
|
||||
self._auth_request, timeout=self._refresh_timeout)
|
||||
self.credentials.refresh(auth_request_with_timeout)
|
||||
|
||||
# Recurse. Pass in the original headers, not our modified set.
|
||||
return self.request(
|
||||
|
@ -32,11 +32,17 @@ except ImportError: # pragma: NO COVER
|
||||
|
||||
try:
|
||||
import urllib3
|
||||
except ImportError: # pragma: NO COVER
|
||||
raise ImportError(
|
||||
'The urllib3 library is not installed, please install the urllib3 '
|
||||
'package to use the urllib3 transport.')
|
||||
import urllib3.exceptions
|
||||
except ImportError as caught_exc: # pragma: NO COVER
|
||||
import six
|
||||
six.raise_from(
|
||||
ImportError(
|
||||
'The urllib3 library is not installed, please install the '
|
||||
'urllib3 package to use the urllib3 transport.'
|
||||
),
|
||||
caught_exc,
|
||||
)
|
||||
import six
|
||||
import urllib3.exceptions # pylint: disable=ungrouped-imports
|
||||
|
||||
from google.auth import exceptions
|
||||
from google.auth import transport
|
||||
@ -126,8 +132,9 @@ class Request(transport.Request):
|
||||
response = self.http.request(
|
||||
method, url, body=body, headers=headers, **kwargs)
|
||||
return _Response(response)
|
||||
except urllib3.exceptions.HTTPError as exc:
|
||||
raise exceptions.TransportError(exc)
|
||||
except urllib3.exceptions.HTTPError as caught_exc:
|
||||
new_exc = exceptions.TransportError(caught_exc)
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
|
||||
|
||||
def _make_default_http():
|
||||
|
@ -26,6 +26,7 @@ For more information about the token endpoint, see
|
||||
import datetime
|
||||
import json
|
||||
|
||||
import six
|
||||
from six.moves import http_client
|
||||
from six.moves import urllib
|
||||
|
||||
@ -144,9 +145,10 @@ def jwt_grant(request, token_uri, assertion):
|
||||
|
||||
try:
|
||||
access_token = response_data['access_token']
|
||||
except KeyError:
|
||||
raise exceptions.RefreshError(
|
||||
except KeyError as caught_exc:
|
||||
new_exc = exceptions.RefreshError(
|
||||
'No access token in response.', response_data)
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
|
||||
expiry = _parse_expiry(response_data)
|
||||
|
||||
@ -190,9 +192,10 @@ def refresh_grant(request, token_uri, refresh_token, client_id, client_secret):
|
||||
|
||||
try:
|
||||
access_token = response_data['access_token']
|
||||
except KeyError:
|
||||
raise exceptions.RefreshError(
|
||||
except KeyError as caught_exc:
|
||||
new_exc = exceptions.RefreshError(
|
||||
'No access token in response.', response_data)
|
||||
six.raise_from(new_exc, caught_exc)
|
||||
|
||||
refresh_token = response_data.get('refresh_token', refresh_token)
|
||||
expiry = _parse_expiry(response_data)
|
||||
|
@ -31,12 +31,21 @@ Authorization Code grant flow.
|
||||
.. _rfc6749 section 4.1: https://tools.ietf.org/html/rfc6749#section-4.1
|
||||
"""
|
||||
|
||||
import io
|
||||
import json
|
||||
|
||||
import six
|
||||
|
||||
from google.auth import _helpers
|
||||
from google.auth import credentials
|
||||
from google.oauth2 import _client
|
||||
|
||||
|
||||
class Credentials(credentials.Scoped, credentials.Credentials):
|
||||
# The Google OAuth 2.0 token endpoint. Used for authorized user credentials.
|
||||
_GOOGLE_OAUTH2_TOKEN_ENDPOINT = 'https://accounts.google.com/o/oauth2/token'
|
||||
|
||||
|
||||
class Credentials(credentials.ReadOnlyScoped, credentials.Credentials):
|
||||
"""Credentials using OAuth 2.0 access and refresh tokens."""
|
||||
|
||||
def __init__(self, token, refresh_token=None, id_token=None,
|
||||
@ -109,15 +118,6 @@ class Credentials(credentials.Scoped, credentials.Credentials):
|
||||
the initial token is requested and can not be changed."""
|
||||
return False
|
||||
|
||||
def with_scopes(self, scopes):
|
||||
"""Unavailable, OAuth 2.0 credentials can not be re-scoped.
|
||||
|
||||
OAuth 2.0 credentials have their scopes set when the initial token is
|
||||
requested and can not be changed.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
'OAuth 2.0 Credentials can not modify their scopes.')
|
||||
|
||||
@_helpers.copy_docstring(credentials.Credentials)
|
||||
def refresh(self, request):
|
||||
access_token, refresh_token, expiry, grant_response = (
|
||||
@ -129,3 +129,56 @@ class Credentials(credentials.Scoped, credentials.Credentials):
|
||||
self.expiry = expiry
|
||||
self._refresh_token = refresh_token
|
||||
self._id_token = grant_response.get('id_token')
|
||||
|
||||
@classmethod
|
||||
def from_authorized_user_info(cls, info, scopes=None):
|
||||
"""Creates a Credentials instance from parsed authorized user info.
|
||||
|
||||
Args:
|
||||
info (Mapping[str, str]): The authorized user info in Google
|
||||
format.
|
||||
scopes (Sequence[str]): Optional list of scopes to include in the
|
||||
credentials.
|
||||
|
||||
Returns:
|
||||
google.oauth2.credentials.Credentials: The constructed
|
||||
credentials.
|
||||
|
||||
Raises:
|
||||
ValueError: If the info is not in the expected format.
|
||||
"""
|
||||
keys_needed = set(('refresh_token', 'client_id', 'client_secret'))
|
||||
missing = keys_needed.difference(six.iterkeys(info))
|
||||
|
||||
if missing:
|
||||
raise ValueError(
|
||||
'Authorized user info was not in the expected format, missing '
|
||||
'fields {}.'.format(', '.join(missing)))
|
||||
|
||||
return Credentials(
|
||||
None, # No access token, must be refreshed.
|
||||
refresh_token=info['refresh_token'],
|
||||
token_uri=_GOOGLE_OAUTH2_TOKEN_ENDPOINT,
|
||||
scopes=scopes,
|
||||
client_id=info['client_id'],
|
||||
client_secret=info['client_secret'])
|
||||
|
||||
@classmethod
|
||||
def from_authorized_user_file(cls, filename, scopes=None):
|
||||
"""Creates a Credentials instance from an authorized user json file.
|
||||
|
||||
Args:
|
||||
filename (str): The path to the authorized user json file.
|
||||
scopes (Sequence[str]): Optional list of scopes to include in the
|
||||
credentials.
|
||||
|
||||
Returns:
|
||||
google.oauth2.credentials.Credentials: The constructed
|
||||
credentials.
|
||||
|
||||
Raises:
|
||||
ValueError: If the file is not in the expected format.
|
||||
"""
|
||||
with io.open(filename, 'r', encoding='utf-8') as json_file:
|
||||
data = json.load(json_file)
|
||||
return cls.from_authorized_user_info(data, scopes)
|
||||
|
@ -79,7 +79,7 @@ from google.auth import credentials
|
||||
from google.auth import jwt
|
||||
from google.oauth2 import _client
|
||||
|
||||
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in sections
|
||||
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
|
||||
|
||||
|
||||
class Credentials(credentials.Signing,
|
||||
|
Reference in New Issue
Block a user