chore: blacken (#375)
diff --git a/.flake8 b/.flake8
new file mode 100644
index 0000000..0574e0a
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,8 @@
+[flake8]
+ignore = E203, E266, E501, W503
+exclude =
+ # Standard linting exemptions.
+ __pycache__,
+ .git,
+ *.pyc,
+ conf.py
diff --git a/docs/conf.py b/docs/conf.py
index 2ac5f34..831c752 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -33,40 +33,40 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
- 'sphinx.ext.autodoc',
- 'sphinx.ext.intersphinx',
- 'sphinx.ext.viewcode',
- 'sphinx.ext.napoleon',
- 'sphinx_docstring_typing'
+ "sphinx.ext.autodoc",
+ "sphinx.ext.intersphinx",
+ "sphinx.ext.viewcode",
+ "sphinx.ext.napoleon",
+ "sphinx_docstring_typing",
]
# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
-source_suffix = '.rst'
+source_suffix = ".rst"
# The encoding of source files.
#
# source_encoding = 'utf-8-sig'
# The master toctree document.
-master_doc = 'index'
+master_doc = "index"
# General information about the project.
-project = 'google-auth'
-copyright = '2016, Google, Inc.'
-author = 'Google, Inc.'
+project = "google-auth"
+copyright = "2016, Google, Inc."
+author = "Google, Inc."
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-version = pkg_resources.get_distribution('google-auth').version
+version = pkg_resources.get_distribution("google-auth").version
# The full version, including alpha/beta/rc tags.
release = version
@@ -89,7 +89,7 @@
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# The reST default role (used for this markup: `text`) to use for all
# documents.
@@ -111,7 +111,7 @@
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
@@ -128,21 +128,21 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = 'alabaster'
+html_theme = "alabaster"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
- 'description': 'Google Auth Library for Python',
- 'github_user': 'GoogleCloudPlatform',
- 'github_repo': 'google-auth-library-python',
- 'github_banner': True,
- 'travis_button': True,
- 'font_family': "'Roboto', Georgia, sans",
- 'head_font_family': "'Roboto', Georgia, serif",
- 'code_font_family': "'Roboto Mono', 'Consolas', monospace",
+ "description": "Google Auth Library for Python",
+ "github_user": "GoogleCloudPlatform",
+ "github_repo": "google-auth-library-python",
+ "github_banner": True,
+ "travis_button": True,
+ "font_family": "'Roboto', Georgia, sans",
+ "head_font_family": "'Roboto', Georgia, serif",
+ "code_font_family": "'Roboto Mono', 'Consolas', monospace",
}
# Add any paths that contain custom themes here, relative to this directory.
@@ -171,7 +171,7 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = ["_static"]
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
@@ -194,12 +194,7 @@
#
html_sidebars = {
- '**': [
- 'about.html',
- 'navigation.html',
- 'relations.html',
- 'searchbox.html',
- ]
+ "**": ["about.html", "navigation.html", "relations.html", "searchbox.html"]
}
# Additional templates that should be rendered to pages, maps page names to
@@ -259,34 +254,36 @@
# html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
-htmlhelp_basename = 'google-authdoc'
+htmlhelp_basename = "google-authdoc"
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
- # The paper size ('letterpaper' or 'a4paper').
- #
- # 'papersize': 'letterpaper',
-
- # The font size ('10pt', '11pt' or '12pt').
- #
- # 'pointsize': '10pt',
-
- # Additional stuff for the LaTeX preamble.
- #
- # 'preamble': '',
-
- # Latex figure (float) alignment
- #
- # 'figure_align': 'htbp',
+ # The paper size ('letterpaper' or 'a4paper').
+ #
+ # 'papersize': 'letterpaper',
+ # The font size ('10pt', '11pt' or '12pt').
+ #
+ # 'pointsize': '10pt',
+ # Additional stuff for the LaTeX preamble.
+ #
+ # 'preamble': '',
+ # Latex figure (float) alignment
+ #
+ # 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
- (master_doc, 'google-auth.tex', 'google-auth Documentation',
- 'Google, Inc.', 'manual'),
+ (
+ master_doc,
+ "google-auth.tex",
+ "google-auth Documentation",
+ "Google, Inc.",
+ "manual",
+ )
]
# The name of an image file (relative to this directory) to place at the top of
@@ -326,10 +323,7 @@
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
-man_pages = [
- (master_doc, 'google-auth', 'google-auth Documentation',
- [author], 1)
-]
+man_pages = [(master_doc, "google-auth", "google-auth Documentation", [author], 1)]
# If true, show URL addresses after external links.
#
@@ -342,9 +336,15 @@
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
- (master_doc, 'google-auth', 'google-auth Documentation',
- author, 'google-auth', 'One line description of project.',
- 'Miscellaneous'),
+ (
+ master_doc,
+ "google-auth",
+ "google-auth Documentation",
+ author,
+ "google-auth",
+ "One line description of project.",
+ "Miscellaneous",
+ )
]
# Documents to append as an appendix to all manuals.
@@ -366,14 +366,13 @@
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
- 'python': ('https://docs.python.org/3.5', None),
- 'urllib3': ('https://urllib3.readthedocs.io/en/stable', None),
- 'requests': ('http://docs.python-requests.org/en/stable', None),
- 'requests-oauthlib': (
- 'http://requests-oauthlib.readthedocs.io/en/stable', None),
+ "python": ("https://docs.python.org/3.5", None),
+ "urllib3": ("https://urllib3.readthedocs.io/en/stable", None),
+ "requests": ("http://docs.python-requests.org/en/stable", None),
+ "requests-oauthlib": ("http://requests-oauthlib.readthedocs.io/en/stable", None),
}
# Autodoc config
-autoclass_content = 'both'
-autodoc_member_order = 'bysource'
-autodoc_mock_imports = ['grpc']
+autoclass_content = "both"
+autodoc_member_order = "bysource"
+autodoc_mock_imports = ["grpc"]
diff --git a/google/__init__.py b/google/__init__.py
index a35569c..f36d791 100644
--- a/google/__init__.py
+++ b/google/__init__.py
@@ -16,7 +16,9 @@
try:
import pkg_resources
+
pkg_resources.declare_namespace(__name__)
except ImportError:
import pkgutil
+
__path__ = pkgutil.extend_path(__path__, __name__)
diff --git a/google/auth/__init__.py b/google/auth/__init__.py
index 65e1395..5f78cd1 100644
--- a/google/auth/__init__.py
+++ b/google/auth/__init__.py
@@ -19,9 +19,7 @@
from google.auth._default import default
-__all__ = [
- 'default',
-]
+__all__ = ["default"]
# Set default logging handler to avoid "No handler found" warnings.
diff --git a/google/auth/_cloud_sdk.py b/google/auth/_cloud_sdk.py
index 0d4b222..61ffd4f 100644
--- a/google/auth/_cloud_sdk.py
+++ b/google/auth/_cloud_sdk.py
@@ -23,20 +23,21 @@
# The ~/.config subdirectory containing gcloud credentials.
-_CONFIG_DIRECTORY = 'gcloud'
+_CONFIG_DIRECTORY = "gcloud"
# Windows systems store config at %APPDATA%\gcloud
-_WINDOWS_CONFIG_ROOT_ENV_VAR = 'APPDATA'
+_WINDOWS_CONFIG_ROOT_ENV_VAR = "APPDATA"
# The name of the file in the Cloud SDK config that contains default
# credentials.
-_CREDENTIALS_FILENAME = 'application_default_credentials.json'
+_CREDENTIALS_FILENAME = "application_default_credentials.json"
# The name of the Cloud SDK shell script
-_CLOUD_SDK_POSIX_COMMAND = 'gcloud'
-_CLOUD_SDK_WINDOWS_COMMAND = 'gcloud.cmd'
+_CLOUD_SDK_POSIX_COMMAND = "gcloud"
+_CLOUD_SDK_WINDOWS_COMMAND = "gcloud.cmd"
# The command to get the Cloud SDK configuration
-_CLOUD_SDK_CONFIG_COMMAND = ('config', 'config-helper', '--format', 'json')
+_CLOUD_SDK_CONFIG_COMMAND = ("config", "config-helper", "--format", "json")
# Cloud SDK's application-default client ID
CLOUD_SDK_CLIENT_ID = (
- '764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com')
+ "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com"
+)
def get_config_path():
@@ -52,21 +53,19 @@
pass
# Non-windows systems store this at ~/.config/gcloud
- if os.name != 'nt':
- return os.path.join(
- os.path.expanduser('~'), '.config', _CONFIG_DIRECTORY)
+ if os.name != "nt":
+ return os.path.join(os.path.expanduser("~"), ".config", _CONFIG_DIRECTORY)
# Windows systems store config at %APPDATA%\gcloud
else:
try:
return os.path.join(
- os.environ[_WINDOWS_CONFIG_ROOT_ENV_VAR],
- _CONFIG_DIRECTORY)
+ os.environ[_WINDOWS_CONFIG_ROOT_ENV_VAR], _CONFIG_DIRECTORY
+ )
except KeyError:
# This should never happen unless someone is really
# messing with things, but we'll cover the case anyway.
- drive = os.environ.get('SystemDrive', 'C:')
- return os.path.join(
- drive, '\\', _CONFIG_DIRECTORY)
+ drive = os.environ.get("SystemDrive", "C:")
+ return os.path.join(drive, "\\", _CONFIG_DIRECTORY)
def get_application_default_credentials_path():
@@ -93,8 +92,7 @@
Raises:
ValueError: if the info is in the wrong format or missing data.
"""
- return google.oauth2.credentials.Credentials.from_authorized_user_info(
- info)
+ return google.oauth2.credentials.Credentials.from_authorized_user_info(info)
def get_project_id():
@@ -103,24 +101,24 @@
Returns:
Optional[str]: The project ID.
"""
- if os.name == 'nt':
+ if os.name == "nt":
command = _CLOUD_SDK_WINDOWS_COMMAND
else:
command = _CLOUD_SDK_POSIX_COMMAND
try:
output = subprocess.check_output(
- (command,) + _CLOUD_SDK_CONFIG_COMMAND,
- stderr=subprocess.STDOUT)
+ (command,) + _CLOUD_SDK_CONFIG_COMMAND, stderr=subprocess.STDOUT
+ )
except (subprocess.CalledProcessError, OSError, IOError):
return None
try:
- configuration = json.loads(output.decode('utf-8'))
+ configuration = json.loads(output.decode("utf-8"))
except ValueError:
return None
try:
- return configuration['configuration']['properties']['core']['project']
+ return configuration["configuration"]["properties"]["core"]["project"]
except KeyError:
return None
diff --git a/google/auth/_default.py b/google/auth/_default.py
index 27de58d..32e81ba 100644
--- a/google/auth/_default.py
+++ b/google/auth/_default.py
@@ -32,8 +32,8 @@
_LOGGER = logging.getLogger(__name__)
# Valid types accepted for file-based credentials.
-_AUTHORIZED_USER_TYPE = 'authorized_user'
-_SERVICE_ACCOUNT_TYPE = 'service_account'
+_AUTHORIZED_USER_TYPE = "authorized_user"
+_SERVICE_ACCOUNT_TYPE = "service_account"
_VALID_TYPES = (_AUTHORIZED_USER_TYPE, _SERVICE_ACCOUNT_TYPE)
# Help message when no credentials can be found.
@@ -42,7 +42,9 @@
explicitly create credentials and re-run the application. For more \
information, please see \
https://cloud.google.com/docs/authentication/getting-started
-""".format(env=environment_vars.CREDENTIALS).strip()
+""".format(
+ env=environment_vars.CREDENTIALS
+).strip()
# Warning when using Cloud SDK user credentials
_CLOUD_SDK_CREDENTIALS_WARNING = """\
@@ -62,6 +64,7 @@
quota. If this is the case, warn about it.
"""
from google.auth import _cloud_sdk
+
if credentials.client_id == _cloud_sdk.CLOUD_SDK_CLIENT_ID:
warnings.warn(_CLOUD_SDK_CREDENTIALS_WARNING)
@@ -86,20 +89,21 @@
"""
if not os.path.exists(filename):
raise exceptions.DefaultCredentialsError(
- 'File {} was not found.'.format(filename))
+ "File {} was not found.".format(filename)
+ )
- with io.open(filename, 'r') as file_obj:
+ with io.open(filename, "r") as file_obj:
try:
info = json.load(file_obj)
except ValueError as caught_exc:
new_exc = exceptions.DefaultCredentialsError(
- 'File {} is not a valid json file.'.format(filename),
- caught_exc)
+ "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.
- credential_type = info.get('type')
+ credential_type = info.get("type")
if credential_type == _AUTHORIZED_USER_TYPE:
from google.auth import _cloud_sdk
@@ -107,8 +111,7 @@
try:
credentials = _cloud_sdk.load_authorized_user_credentials(info)
except ValueError as caught_exc:
- msg = 'Failed to load authorized user credentials from {}'.format(
- filename)
+ 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.
@@ -119,20 +122,20 @@
from google.oauth2 import service_account
try:
- credentials = (
- service_account.Credentials.from_service_account_info(info))
+ credentials = service_account.Credentials.from_service_account_info(info)
except ValueError as caught_exc:
- msg = 'Failed to load service account credentials from {}'.format(
- filename)
+ 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')
+ return credentials, info.get("project_id")
else:
raise exceptions.DefaultCredentialsError(
- 'The file {file} does not have a valid type. '
- 'Type is {type}, expected one of {valid_types}.'.format(
- file=filename, type=credential_type, valid_types=_VALID_TYPES))
+ "The file {file} does not have a valid type. "
+ "Type is {type}, expected one of {valid_types}.".format(
+ file=filename, type=credential_type, valid_types=_VALID_TYPES
+ )
+ )
def _get_gcloud_sdk_credentials():
@@ -140,14 +143,12 @@
from google.auth import _cloud_sdk
# Check if application default credentials exist.
- credentials_filename = (
- _cloud_sdk.get_application_default_credentials_path())
+ credentials_filename = _cloud_sdk.get_application_default_credentials_path()
if not os.path.isfile(credentials_filename):
return None, None
- credentials, project_id = _load_credentials_from_file(
- credentials_filename)
+ credentials, project_id = _load_credentials_from_file(credentials_filename)
if not project_id:
project_id = _cloud_sdk.get_project_id()
@@ -162,7 +163,8 @@
if explicit_file is not None:
credentials, project_id = _load_credentials_from_file(
- os.environ[environment_vars.CREDENTIALS])
+ os.environ[environment_vars.CREDENTIALS]
+ )
return credentials, project_id
@@ -292,14 +294,15 @@
from google.auth.credentials import with_scopes_if_required
explicit_project_id = os.environ.get(
- environment_vars.PROJECT,
- os.environ.get(environment_vars.LEGACY_PROJECT))
+ environment_vars.PROJECT, os.environ.get(environment_vars.LEGACY_PROJECT)
+ )
checkers = (
_get_explicit_environ_credentials,
_get_gcloud_sdk_credentials,
_get_gae_credentials,
- lambda: _get_gce_credentials(request))
+ lambda: _get_gce_credentials(request),
+ )
for checker in checkers:
credentials, project_id = checker()
@@ -308,10 +311,11 @@
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)
+ "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)
diff --git a/google/auth/_helpers.py b/google/auth/_helpers.py
index b32801a..ecb88ff 100644
--- a/google/auth/_helpers.py
+++ b/google/auth/_helpers.py
@@ -36,6 +36,7 @@
Callable: A decorator that will copy the docstring of the same
named method in the source class to the decorated method.
"""
+
def decorator(method):
"""Decorator implementation.
@@ -49,12 +50,13 @@
ValueError: if the method already has a docstring.
"""
if method.__doc__:
- raise ValueError('Method already has a docstring.')
+ raise ValueError("Method already has a docstring.")
source_method = getattr(source_class, method.__name__)
method.__doc__ = source_method.__doc__
return method
+
return decorator
@@ -79,7 +81,7 @@
return calendar.timegm(value.utctimetuple())
-def to_bytes(value, encoding='utf-8'):
+def to_bytes(value, encoding="utf-8"):
"""Converts a string value to bytes, if necessary.
Unfortunately, ``six.b`` is insufficient for this task since in
@@ -97,12 +99,11 @@
Raises:
ValueError: If the value could not be converted to bytes.
"""
- result = (value.encode(encoding)
- if isinstance(value, six.text_type) else value)
+ result = value.encode(encoding) if isinstance(value, six.text_type) else value
if isinstance(result, six.binary_type):
return result
else:
- raise ValueError('{0!r} could not be converted to bytes'.format(value))
+ raise ValueError("{0!r} could not be converted to bytes".format(value))
def from_bytes(value):
@@ -118,13 +119,11 @@
Raises:
ValueError: If the value could not be converted to unicode.
"""
- result = (value.decode('utf-8')
- if isinstance(value, six.binary_type) else value)
+ result = value.decode("utf-8") if isinstance(value, six.binary_type) else value
if isinstance(result, six.text_type):
return result
else:
- raise ValueError(
- '{0!r} could not be converted to unicode'.format(value))
+ raise ValueError("{0!r} could not be converted to unicode".format(value))
def update_query(url, params, remove=None):
@@ -163,9 +162,8 @@
query_params.update(params)
# Remove any values specified in remove.
query_params = {
- key: value for key, value
- in six.iteritems(query_params)
- if key not in remove}
+ key: value for key, value in six.iteritems(query_params) if key not in remove
+ }
# Re-encoded the query string.
new_query = urllib.parse.urlencode(query_params, doseq=True)
# Unsplit the url.
@@ -183,7 +181,7 @@
Returns:
str: The scopes formatted as a single string.
"""
- return ' '.join(scopes)
+ return " ".join(scopes)
def string_to_scopes(scopes):
@@ -198,7 +196,7 @@
if not scopes:
return []
- return scopes.split(' ')
+ return scopes.split(" ")
def padded_urlsafe_b64decode(value):
@@ -213,7 +211,7 @@
bytes: The decoded value
"""
b64string = to_bytes(value)
- padded = b64string + b'=' * (-len(b64string) % 4)
+ padded = b64string + b"=" * (-len(b64string) % 4)
return base64.urlsafe_b64decode(padded)
@@ -231,4 +229,4 @@
Returns:
Union[str|bytes]: The encoded value
"""
- return base64.urlsafe_b64encode(value).rstrip(b'=')
+ return base64.urlsafe_b64encode(value).rstrip(b"=")
diff --git a/google/auth/_oauth2client.py b/google/auth/_oauth2client.py
index afe7dc4..b14a382 100644
--- a/google/auth/_oauth2client.py
+++ b/google/auth/_oauth2client.py
@@ -34,18 +34,17 @@
import oauth2client.contrib.gce
import oauth2client.service_account
except ImportError as caught_exc:
- six.raise_from(
- ImportError('oauth2client is not installed.'), caught_exc)
+ six.raise_from(ImportError("oauth2client is not installed."), caught_exc)
try:
import oauth2client.contrib.appengine # pytype: disable=import-error
+
_HAS_APPENGINE = True
except ImportError:
_HAS_APPENGINE = False
-_CONVERT_ERROR_TMPL = (
- 'Unable to convert {} to a google-auth credentials class.')
+_CONVERT_ERROR_TMPL = "Unable to convert {} to a google-auth credentials class."
def _convert_oauth2_credentials(credentials):
@@ -65,7 +64,8 @@
token_uri=credentials.token_uri,
client_id=credentials.client_id,
client_secret=credentials.client_secret,
- scopes=credentials.scopes)
+ scopes=credentials.scopes,
+ )
new_credentials._expires = credentials.token_expiry
@@ -85,9 +85,8 @@
google.oauth2.service_account.Credentials: The converted credentials.
"""
info = credentials.serialization_data.copy()
- info['token_uri'] = credentials.token_uri
- return google.oauth2.service_account.Credentials.from_service_account_info(
- info)
+ info["token_uri"] = credentials.token_uri
+ return google.oauth2.service_account.Credentials.from_service_account_info(info)
def _convert_gce_app_assertion_credentials(credentials):
@@ -101,7 +100,8 @@
google.oauth2.service_account.Credentials: The converted credentials.
"""
return google.auth.compute_engine.Credentials(
- service_account_email=credentials.service_account_email)
+ service_account_email=credentials.service_account_email
+ )
def _convert_appengine_app_assertion_credentials(credentials):
@@ -117,24 +117,22 @@
# pylint: disable=invalid-name
return google.auth.app_engine.Credentials(
scopes=_helpers.string_to_scopes(credentials.scope),
- service_account_id=credentials.service_account_id)
+ service_account_id=credentials.service_account_id,
+ )
_CLASS_CONVERSION_MAP = {
oauth2client.client.OAuth2Credentials: _convert_oauth2_credentials,
oauth2client.client.GoogleCredentials: _convert_oauth2_credentials,
- oauth2client.service_account.ServiceAccountCredentials:
- _convert_service_account_credentials,
- oauth2client.service_account._JWTAccessCredentials:
- _convert_service_account_credentials,
- oauth2client.contrib.gce.AppAssertionCredentials:
- _convert_gce_app_assertion_credentials,
+ oauth2client.service_account.ServiceAccountCredentials: _convert_service_account_credentials,
+ oauth2client.service_account._JWTAccessCredentials: _convert_service_account_credentials,
+ oauth2client.contrib.gce.AppAssertionCredentials: _convert_gce_app_assertion_credentials,
}
if _HAS_APPENGINE:
_CLASS_CONVERSION_MAP[
- oauth2client.contrib.appengine.AppAssertionCredentials] = (
- _convert_appengine_app_assertion_credentials)
+ oauth2client.contrib.appengine.AppAssertionCredentials
+ ] = _convert_appengine_app_assertion_credentials
def convert(credentials):
diff --git a/google/auth/_service_account_info.py b/google/auth/_service_account_info.py
index dd39ea7..790be92 100644
--- a/google/auth/_service_account_info.py
+++ b/google/auth/_service_account_info.py
@@ -47,8 +47,9 @@
if missing:
raise ValueError(
- 'Service account info was not in the expected format, missing '
- 'fields {}.'.format(', '.join(missing)))
+ "Service account info was not in the expected format, missing "
+ "fields {}.".format(", ".join(missing))
+ )
# Create a signer.
signer = crypt.RSASigner.from_service_account_info(data)
@@ -68,6 +69,6 @@
Tuple[ Mapping[str, str], google.auth.crypt.Signer ]: The verified
info and a signer instance.
"""
- with io.open(filename, 'r', encoding='utf-8') as json_file:
+ with io.open(filename, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
return data, from_dict(data, require=require)
diff --git a/google/auth/app_engine.py b/google/auth/app_engine.py
index 91ba842..aec86a6 100644
--- a/google/auth/app_engine.py
+++ b/google/auth/app_engine.py
@@ -73,13 +73,11 @@
# Pylint rightfully thinks EnvironmentError is OSError, but doesn't
# realize it's a valid alias.
if app_identity is None:
- raise EnvironmentError(
- 'The App Engine APIs are not available.')
+ raise EnvironmentError("The App Engine APIs are not available.")
return app_identity.get_application_id()
-class Credentials(credentials.Scoped, credentials.Signing,
- credentials.Credentials):
+class Credentials(credentials.Scoped, credentials.Signing, credentials.Credentials):
"""App Engine standard environment credentials.
These credentials use the App Engine App Identity API to obtain access
@@ -103,8 +101,7 @@
# Pylint rightfully thinks EnvironmentError is OSError, but doesn't
# realize it's a valid alias.
if app_identity is None:
- raise EnvironmentError(
- 'The App Engine APIs are not available.')
+ raise EnvironmentError("The App Engine APIs are not available.")
super(Credentials, self).__init__()
self._scopes = scopes
@@ -115,7 +112,8 @@
def refresh(self, request):
# pylint: disable=unused-argument
token, ttl = app_identity.get_access_token(
- self._scopes, self._service_account_id)
+ self._scopes, self._service_account_id
+ )
expiry = datetime.datetime.utcfromtimestamp(ttl)
self.token, self.expiry = token, expiry
@@ -139,7 +137,8 @@
@_helpers.copy_docstring(credentials.Scoped)
def with_scopes(self, scopes):
return self.__class__(
- scopes=scopes, service_account_id=self._service_account_id)
+ scopes=scopes, service_account_id=self._service_account_id
+ )
@_helpers.copy_docstring(credentials.Signing)
def sign_bytes(self, message):
diff --git a/google/auth/compute_engine/__init__.py b/google/auth/compute_engine/__init__.py
index ca31b46..461f104 100644
--- a/google/auth/compute_engine/__init__.py
+++ b/google/auth/compute_engine/__init__.py
@@ -18,7 +18,4 @@
from google.auth.compute_engine.credentials import IDTokenCredentials
-__all__ = [
- 'Credentials',
- 'IDTokenCredentials',
-]
+__all__ = ["Credentials", "IDTokenCredentials"]
diff --git a/google/auth/compute_engine/_metadata.py b/google/auth/compute_engine/_metadata.py
index d8004bb..f4fae72 100644
--- a/google/auth/compute_engine/_metadata.py
+++ b/google/auth/compute_engine/_metadata.py
@@ -32,21 +32,23 @@
_LOGGER = logging.getLogger(__name__)
-_METADATA_ROOT = 'http://{}/computeMetadata/v1/'.format(
- os.getenv(environment_vars.GCE_METADATA_ROOT, 'metadata.google.internal'))
+_METADATA_ROOT = "http://{}/computeMetadata/v1/".format(
+ os.getenv(environment_vars.GCE_METADATA_ROOT, "metadata.google.internal")
+)
# This is used to ping the metadata server, it avoids the cost of a DNS
# lookup.
-_METADATA_IP_ROOT = 'http://{}'.format(
- os.getenv(environment_vars.GCE_METADATA_IP, '169.254.169.254'))
-_METADATA_FLAVOR_HEADER = 'metadata-flavor'
-_METADATA_FLAVOR_VALUE = 'Google'
+_METADATA_IP_ROOT = "http://{}".format(
+ os.getenv(environment_vars.GCE_METADATA_IP, "169.254.169.254")
+)
+_METADATA_FLAVOR_HEADER = "metadata-flavor"
+_METADATA_FLAVOR_VALUE = "Google"
_METADATA_HEADERS = {_METADATA_FLAVOR_HEADER: _METADATA_FLAVOR_VALUE}
# Timeout in seconds to wait for the GCE metadata server when detecting the
# GCE environment.
try:
- _METADATA_DEFAULT_TIMEOUT = int(os.getenv('GCE_METADATA_TIMEOUT', 3))
+ _METADATA_DEFAULT_TIMEOUT = int(os.getenv("GCE_METADATA_TIMEOUT", 3))
except ValueError: # pragma: NO COVER
_METADATA_DEFAULT_TIMEOUT = 3
@@ -74,16 +76,24 @@
while retries < retry_count:
try:
response = request(
- url=_METADATA_IP_ROOT, method='GET', headers=_METADATA_HEADERS,
- timeout=timeout)
+ url=_METADATA_IP_ROOT,
+ method="GET",
+ headers=_METADATA_HEADERS,
+ timeout=timeout,
+ )
metadata_flavor = response.headers.get(_METADATA_FLAVOR_HEADER)
- return (response.status == http_client.OK and
- metadata_flavor == _METADATA_FLAVOR_VALUE)
+ return (
+ response.status == http_client.OK
+ and metadata_flavor == _METADATA_FLAVOR_VALUE
+ )
except exceptions.TransportError:
- _LOGGER.info('Compute Engine Metadata server unavailable on'
- 'attempt %s of %s', retries+1, retry_count)
+ _LOGGER.info(
+ "Compute Engine Metadata server unavailable on" "attempt %s of %s",
+ retries + 1,
+ retry_count,
+ )
retries += 1
return False
@@ -115,29 +125,33 @@
query_params = {}
if recursive:
- query_params['recursive'] = 'true'
+ query_params["recursive"] = "true"
url = _helpers.update_query(base_url, query_params)
- response = request(url=url, method='GET', headers=_METADATA_HEADERS)
+ response = request(url=url, method="GET", headers=_METADATA_HEADERS)
if response.status == http_client.OK:
content = _helpers.from_bytes(response.data)
- if response.headers['content-type'] == 'application/json':
+ if response.headers["content-type"] == "application/json":
try:
return json.loads(content)
except ValueError as caught_exc:
new_exc = exceptions.TransportError(
- 'Received invalid JSON from the Google Compute Engine'
- 'metadata service: {:.20}'.format(content))
+ "Received invalid JSON from the Google Compute Engine"
+ "metadata service: {:.20}".format(content)
+ )
six.raise_from(new_exc, caught_exc)
else:
return content
else:
raise exceptions.TransportError(
- 'Failed to retrieve {} from the Google Compute Engine'
- 'metadata service. Status: {} Response:\n{}'.format(
- url, response.status, response.data), response)
+ "Failed to retrieve {} from the Google Compute Engine"
+ "metadata service. Status: {} Response:\n{}".format(
+ url, response.status, response.data
+ ),
+ response,
+ )
def get_project_id(request):
@@ -154,10 +168,10 @@
google.auth.exceptions.TransportError: if an error occurred while
retrieving metadata.
"""
- return get(request, 'project/project-id')
+ return get(request, "project/project-id")
-def get_service_account_info(request, service_account='default'):
+def get_service_account_info(request, service_account="default"):
"""Get information about a service account from the metadata server.
Args:
@@ -182,11 +196,12 @@
"""
return get(
request,
- 'instance/service-accounts/{0}/'.format(service_account),
- recursive=True)
+ "instance/service-accounts/{0}/".format(service_account),
+ recursive=True,
+ )
-def get_service_account_token(request, service_account='default'):
+def get_service_account_token(request, service_account="default"):
"""Get the OAuth 2.0 access token for a service account.
Args:
@@ -204,8 +219,9 @@
retrieving metadata.
"""
token_json = get(
- request,
- 'instance/service-accounts/{0}/token'.format(service_account))
+ request, "instance/service-accounts/{0}/token".format(service_account)
+ )
token_expiry = _helpers.utcnow() + datetime.timedelta(
- seconds=token_json['expires_in'])
- return token_json['access_token'], token_expiry
+ seconds=token_json["expires_in"]
+ )
+ return token_json["access_token"], token_expiry
diff --git a/google/auth/compute_engine/credentials.py b/google/auth/compute_engine/credentials.py
index d9c6e26..eeb92f5 100644
--- a/google/auth/compute_engine/credentials.py
+++ b/google/auth/compute_engine/credentials.py
@@ -54,7 +54,7 @@
https://cloud.google.com/compute/docs/authentication#using
"""
- def __init__(self, service_account_email='default'):
+ def __init__(self, service_account_email="default"):
"""
Args:
service_account_email (str): The service account email to use, or
@@ -74,11 +74,11 @@
HTTP requests.
"""
info = _metadata.get_service_account_info(
- request,
- service_account=self._service_account_email)
+ request, service_account=self._service_account_email
+ )
- self._service_account_email = info['email']
- self._scopes = info['scopes']
+ self._service_account_email = info["email"]
+ self._scopes = info["scopes"]
def refresh(self, request):
"""Refresh the access token and scopes.
@@ -95,8 +95,8 @@
try:
self._retrieve_info(request)
self.token, self.expiry = _metadata.get_service_account_token(
- request,
- service_account=self._service_account_email)
+ request, service_account=self._service_account_email
+ )
except exceptions.TransportError as caught_exc:
new_exc = exceptions.RefreshError(caught_exc)
six.raise_from(new_exc, caught_exc)
@@ -117,7 +117,7 @@
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
-_DEFAULT_TOKEN_URI = 'https://www.googleapis.com/oauth2/v4/token'
+_DEFAULT_TOKEN_URI = "https://www.googleapis.com/oauth2/v4/token"
class IDTokenCredentials(credentials.Credentials, credentials.Signing):
@@ -128,10 +128,15 @@
In order for this to work, the GCE instance must have been started with
a service account that has access to the IAM Cloud API.
"""
- def __init__(self, request, target_audience,
- token_uri=_DEFAULT_TOKEN_URI,
- additional_claims=None,
- service_account_email=None):
+
+ def __init__(
+ self,
+ request,
+ target_audience,
+ token_uri=_DEFAULT_TOKEN_URI,
+ additional_claims=None,
+ service_account_email=None,
+ ):
"""
Args:
request (google.auth.transport.Request): The object used to make
@@ -150,13 +155,14 @@
if service_account_email is None:
sa_info = _metadata.get_service_account_info(request)
- service_account_email = sa_info['email']
+ service_account_email = sa_info["email"]
self._service_account_email = service_account_email
self._signer = iam.Signer(
request=request,
credentials=Credentials(),
- service_account_email=service_account_email)
+ service_account_email=service_account_email,
+ )
self._token_uri = token_uri
self._target_audience = target_audience
@@ -181,7 +187,8 @@
service_account_email=self._service_account_email,
token_uri=self._token_uri,
target_audience=target_audience,
- additional_claims=self._additional_claims.copy())
+ additional_claims=self._additional_claims.copy(),
+ )
def _make_authorization_grant_assertion(self):
"""Create the OAuth 2.0 assertion.
@@ -195,15 +202,15 @@
expiry = now + lifetime
payload = {
- 'iat': _helpers.datetime_to_secs(now),
- 'exp': _helpers.datetime_to_secs(expiry),
+ "iat": _helpers.datetime_to_secs(now),
+ "exp": _helpers.datetime_to_secs(expiry),
# The issuer must be the service account email.
- 'iss': self.service_account_email,
+ "iss": self.service_account_email,
# The audience must be the auth token endpoint's URI
- 'aud': self._token_uri,
+ "aud": self._token_uri,
# The target audience specifies which service the ID token is
# intended for.
- 'target_audience': self._target_audience
+ "target_audience": self._target_audience,
}
payload.update(self._additional_claims)
@@ -216,7 +223,8 @@
def refresh(self, request):
assertion = self._make_authorization_grant_assertion()
access_token, expiry, _ = _client.id_token_jwt_grant(
- request, self._token_uri, assertion)
+ request, self._token_uri, assertion
+ )
self.token = access_token
self.expiry = expiry
diff --git a/google/auth/credentials.py b/google/auth/credentials.py
index 8ff1f02..81bbd03 100644
--- a/google/auth/credentials.py
+++ b/google/auth/credentials.py
@@ -41,6 +41,7 @@
construction. Some classes will provide mechanisms to copy the credentials
with modifications such as :meth:`ScopedCredentials.with_scopes`.
"""
+
def __init__(self):
self.token = None
"""str: The bearer token that can be used in HTTP headers to make
@@ -88,7 +89,7 @@
"""
# pylint: disable=missing-raises-doc
# (pylint doesn't recognize that this is abstract)
- raise NotImplementedError('Refresh must be implemented')
+ raise NotImplementedError("Refresh must be implemented")
def apply(self, headers, token=None):
"""Apply the token to the authentication header.
@@ -98,8 +99,9 @@
token (Optional[str]): If specified, overrides the current access
token.
"""
- headers['authorization'] = 'Bearer {}'.format(
- _helpers.from_bytes(token or self.token))
+ headers["authorization"] = "Bearer {}".format(
+ _helpers.from_bytes(token or self.token)
+ )
def before_request(self, request, method, url, headers):
"""Performs credential-specific before request logic.
@@ -189,6 +191,7 @@
.. _RFC6749 Section 3.3: https://tools.ietf.org/html/rfc6749#section-3.3
"""
+
def __init__(self):
super(ReadOnlyScoped, self).__init__()
self._scopes = None
@@ -247,6 +250,7 @@
.. _RFC6749 Section 3.3: https://tools.ietf.org/html/rfc6749#section-3.3
"""
+
@abc.abstractmethod
def with_scopes(self, scopes):
"""Create a copy of these credentials with the specified scopes.
@@ -260,7 +264,7 @@
This can be avoided by checking :attr:`requires_scopes` before
calling this method.
"""
- raise NotImplementedError('This class does not require scoping.')
+ raise NotImplementedError("This class does not require scoping.")
def with_scopes_if_required(credentials, scopes):
@@ -305,18 +309,18 @@
"""
# pylint: disable=missing-raises-doc,redundant-returns-doc
# (pylint doesn't recognize that this is abstract)
- raise NotImplementedError('Sign bytes must be implemented.')
+ raise NotImplementedError("Sign bytes must be implemented.")
@abc.abstractproperty
def signer_email(self):
"""Optional[str]: An email address that identifies the signer."""
# pylint: disable=missing-raises-doc
# (pylint doesn't recognize that this is abstract)
- raise NotImplementedError('Signer email must be implemented.')
+ raise NotImplementedError("Signer email must be implemented.")
@abc.abstractproperty
def signer(self):
"""google.auth.crypt.Signer: The signer used to sign bytes."""
# pylint: disable=missing-raises-doc
# (pylint doesn't recognize that this is abstract)
- raise NotImplementedError('Signer must be implemented.')
+ raise NotImplementedError("Signer must be implemented.")
diff --git a/google/auth/crypt/__init__.py b/google/auth/crypt/__init__.py
index 7baa206..bf66e71 100644
--- a/google/auth/crypt/__init__.py
+++ b/google/auth/crypt/__init__.py
@@ -39,12 +39,7 @@
from google.auth.crypt import rsa
-__all__ = [
- 'RSASigner',
- 'RSAVerifier',
- 'Signer',
- 'Verifier',
-]
+__all__ = ["RSASigner", "RSAVerifier", "Signer", "Verifier"]
# Aliases to maintain the v1.0.0 interface, as the crypt module was split
# into submodules.
diff --git a/google/auth/crypt/_cryptography_rsa.py b/google/auth/crypt/_cryptography_rsa.py
index 87076b0..285cf5c 100644
--- a/google/auth/crypt/_cryptography_rsa.py
+++ b/google/auth/crypt/_cryptography_rsa.py
@@ -31,18 +31,18 @@
from google.auth.crypt import base
_IMPORT_ERROR_MSG = (
- 'cryptography>=1.4.0 is required to use cryptography-based RSA '
- 'implementation.')
+ "cryptography>=1.4.0 is required to use cryptography-based RSA " "implementation."
+)
try: # pragma: NO COVER
- release = pkg_resources.get_distribution('cryptography').parsed_version
- if release < pkg_resources.parse_version('1.4.0'):
+ release = pkg_resources.get_distribution("cryptography").parsed_version
+ if release < pkg_resources.parse_version("1.4.0"):
raise ImportError(_IMPORT_ERROR_MSG)
except pkg_resources.DistributionNotFound: # pragma: NO COVER
raise ImportError(_IMPORT_ERROR_MSG)
-_CERTIFICATE_MARKER = b'-----BEGIN CERTIFICATE-----'
+_CERTIFICATE_MARKER = b"-----BEGIN CERTIFICATE-----"
_BACKEND = backends.default_backend()
_PADDING = padding.PKCS1v15()
_SHA256 = hashes.SHA256()
@@ -88,12 +88,12 @@
if _CERTIFICATE_MARKER in public_key_data:
cert = cryptography.x509.load_pem_x509_certificate(
- public_key_data, _BACKEND)
+ public_key_data, _BACKEND
+ )
pubkey = cert.public_key()
else:
- pubkey = serialization.load_pem_public_key(
- public_key_data, _BACKEND)
+ pubkey = serialization.load_pem_public_key(public_key_data, _BACKEND)
return cls(pubkey)
@@ -122,8 +122,7 @@
@_helpers.copy_docstring(base.Signer)
def sign(self, message):
message = _helpers.to_bytes(message)
- return self._key.sign(
- message, _PADDING, _SHA256)
+ return self._key.sign(message, _PADDING, _SHA256)
@classmethod
def from_string(cls, key, key_id=None):
@@ -145,5 +144,6 @@
"""
key = _helpers.to_bytes(key)
private_key = serialization.load_pem_private_key(
- key, password=None, backend=_BACKEND)
+ key, password=None, backend=_BACKEND
+ )
return cls(private_key, key_id=key_id)
diff --git a/google/auth/crypt/_python_rsa.py b/google/auth/crypt/_python_rsa.py
index 44aa791..d53991c 100644
--- a/google/auth/crypt/_python_rsa.py
+++ b/google/auth/crypt/_python_rsa.py
@@ -32,11 +32,9 @@
from google.auth.crypt import base
_POW2 = (128, 64, 32, 16, 8, 4, 2, 1)
-_CERTIFICATE_MARKER = b'-----BEGIN CERTIFICATE-----'
-_PKCS1_MARKER = ('-----BEGIN RSA PRIVATE KEY-----',
- '-----END RSA PRIVATE KEY-----')
-_PKCS8_MARKER = ('-----BEGIN PRIVATE KEY-----',
- '-----END PRIVATE KEY-----')
+_CERTIFICATE_MARKER = b"-----BEGIN CERTIFICATE-----"
+_PKCS1_MARKER = ("-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----")
+_PKCS8_MARKER = ("-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----")
_PKCS8_SPEC = PrivateKeyInfo()
@@ -55,9 +53,8 @@
num_bits = len(bit_list)
byte_vals = bytearray()
for start in six.moves.xrange(0, num_bits, 8):
- curr_bits = bit_list[start:start + 8]
- char_val = sum(
- val * digit for val, digit in six.moves.zip(_POW2, curr_bits))
+ curr_bits = bit_list[start : start + 8]
+ char_val = sum(val * digit for val, digit in six.moves.zip(_POW2, curr_bits))
byte_vals.append(char_val)
return bytes(byte_vals)
@@ -101,16 +98,16 @@
# If this is a certificate, extract the public key info.
if is_x509_cert:
- der = rsa.pem.load_pem(public_key, 'CERTIFICATE')
+ der = rsa.pem.load_pem(public_key, "CERTIFICATE")
asn1_cert, remaining = decoder.decode(der, asn1Spec=Certificate())
- if remaining != b'':
- raise ValueError('Unused bytes', remaining)
+ if remaining != b"":
+ raise ValueError("Unused bytes", remaining)
- cert_info = asn1_cert['tbsCertificate']['subjectPublicKeyInfo']
- key_bytes = _bit_list_to_bytes(cert_info['subjectPublicKey'])
- pubkey = rsa.PublicKey.load_pkcs1(key_bytes, 'DER')
+ cert_info = asn1_cert["tbsCertificate"]["subjectPublicKeyInfo"]
+ key_bytes = _bit_list_to_bytes(cert_info["subjectPublicKey"])
+ pubkey = rsa.PublicKey.load_pkcs1(key_bytes, "DER")
else:
- pubkey = rsa.PublicKey.load_pkcs1(public_key, 'PEM')
+ pubkey = rsa.PublicKey.load_pkcs1(public_key, "PEM")
return cls(pubkey)
@@ -136,7 +133,7 @@
@_helpers.copy_docstring(base.Signer)
def sign(self, message):
message = _helpers.to_bytes(message)
- return rsa.pkcs1.sign(message, self._key, 'SHA-256')
+ return rsa.pkcs1.sign(message, self._key, "SHA-256")
@classmethod
def from_string(cls, key, key_id=None):
@@ -155,22 +152,22 @@
"""
key = _helpers.from_bytes(key) # PEM expects str in Python 3
marker_id, key_bytes = pem.readPemBlocksFromFile(
- six.StringIO(key), _PKCS1_MARKER, _PKCS8_MARKER)
+ six.StringIO(key), _PKCS1_MARKER, _PKCS8_MARKER
+ )
# Key is in pkcs1 format.
if marker_id == 0:
- private_key = rsa.key.PrivateKey.load_pkcs1(
- key_bytes, format='DER')
+ private_key = rsa.key.PrivateKey.load_pkcs1(key_bytes, format="DER")
# Key is in pkcs8.
elif marker_id == 1:
- key_info, remaining = decoder.decode(
- key_bytes, asn1Spec=_PKCS8_SPEC)
- if remaining != b'':
- raise ValueError('Unused bytes', remaining)
- private_key_info = key_info.getComponentByName('privateKey')
+ key_info, remaining = decoder.decode(key_bytes, asn1Spec=_PKCS8_SPEC)
+ if remaining != b"":
+ raise ValueError("Unused bytes", remaining)
+ private_key_info = key_info.getComponentByName("privateKey")
private_key = rsa.key.PrivateKey.load_pkcs1(
- private_key_info.asOctets(), format='DER')
+ private_key_info.asOctets(), format="DER"
+ )
else:
- raise ValueError('No key could be detected.')
+ raise ValueError("No key could be detected.")
return cls(private_key, key_id=key_id)
diff --git a/google/auth/crypt/base.py b/google/auth/crypt/base.py
index c6c0427..ceb6e9c 100644
--- a/google/auth/crypt/base.py
+++ b/google/auth/crypt/base.py
@@ -21,8 +21,8 @@
import six
-_JSON_FILE_PRIVATE_KEY = 'private_key'
-_JSON_FILE_PRIVATE_KEY_ID = 'private_key_id'
+_JSON_FILE_PRIVATE_KEY = "private_key"
+_JSON_FILE_PRIVATE_KEY_ID = "private_key_id"
@six.add_metaclass(abc.ABCMeta)
@@ -43,7 +43,7 @@
"""
# pylint: disable=missing-raises-doc,redundant-returns-doc
# (pylint doesn't recognize that this is abstract)
- raise NotImplementedError('Verify must be implemented')
+ raise NotImplementedError("Verify must be implemented")
@six.add_metaclass(abc.ABCMeta)
@@ -53,7 +53,7 @@
@abc.abstractproperty
def key_id(self):
"""Optional[str]: The key ID used to identify this private key."""
- raise NotImplementedError('Key id must be implemented')
+ raise NotImplementedError("Key id must be implemented")
@abc.abstractmethod
def sign(self, message):
@@ -67,7 +67,7 @@
"""
# pylint: disable=missing-raises-doc,redundant-returns-doc
# (pylint doesn't recognize that this is abstract)
- raise NotImplementedError('Sign must be implemented')
+ raise NotImplementedError("Sign must be implemented")
@six.add_metaclass(abc.ABCMeta)
@@ -88,7 +88,7 @@
Raises:
ValueError: If the key cannot be parsed.
"""
- raise NotImplementedError('from_string must be implemented')
+ raise NotImplementedError("from_string must be implemented")
@classmethod
def from_service_account_info(cls, info):
@@ -107,12 +107,12 @@
"""
if _JSON_FILE_PRIVATE_KEY not in info:
raise ValueError(
- 'The private_key field was not found in the service account '
- 'info.')
+ "The private_key field was not found in the service account " "info."
+ )
return cls.from_string(
- info[_JSON_FILE_PRIVATE_KEY],
- info.get(_JSON_FILE_PRIVATE_KEY_ID))
+ info[_JSON_FILE_PRIVATE_KEY], info.get(_JSON_FILE_PRIVATE_KEY_ID)
+ )
@classmethod
def from_service_account_file(cls, filename):
@@ -125,7 +125,7 @@
Returns:
google.auth.crypt.Signer: The constructed signer.
"""
- with io.open(filename, 'r', encoding='utf-8') as json_file:
+ with io.open(filename, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
return cls.from_service_account_info(data)
diff --git a/google/auth/environment_vars.py b/google/auth/environment_vars.py
index 0110e6a..96d2ffc 100644
--- a/google/auth/environment_vars.py
+++ b/google/auth/environment_vars.py
@@ -15,35 +15,35 @@
"""Environment variables used by :mod:`google.auth`."""
-PROJECT = 'GOOGLE_CLOUD_PROJECT'
+PROJECT = "GOOGLE_CLOUD_PROJECT"
"""Environment variable defining default project.
This used by :func:`google.auth.default` to explicitly set a project ID. This
environment variable is also used by the Google Cloud Python Library.
"""
-LEGACY_PROJECT = 'GCLOUD_PROJECT'
+LEGACY_PROJECT = "GCLOUD_PROJECT"
"""Previously used environment variable defining the default project.
This environment variable is used instead of the current one in some
situations (such as Google App Engine).
"""
-CREDENTIALS = 'GOOGLE_APPLICATION_CREDENTIALS'
+CREDENTIALS = "GOOGLE_APPLICATION_CREDENTIALS"
"""Environment variable defining the location of Google application default
credentials."""
# The environment variable name which can replace ~/.config if set.
-CLOUD_SDK_CONFIG_DIR = 'CLOUDSDK_CONFIG'
+CLOUD_SDK_CONFIG_DIR = "CLOUDSDK_CONFIG"
"""Environment variable defines the location of Google Cloud SDK's config
files."""
# These two variables allow for customization of the addresses used when
# contacting the GCE metadata service.
-GCE_METADATA_ROOT = 'GCE_METADATA_ROOT'
+GCE_METADATA_ROOT = "GCE_METADATA_ROOT"
"""Environment variable providing an alternate hostname or host:port to be
used for GCE metadata requests."""
-GCE_METADATA_IP = 'GCE_METADATA_IP'
+GCE_METADATA_IP = "GCE_METADATA_IP"
"""Environment variable providing an alternate ip:port to be used for ip-only
GCE metadata requests."""
diff --git a/google/auth/iam.py b/google/auth/iam.py
index e091e47..a438726 100644
--- a/google/auth/iam.py
+++ b/google/auth/iam.py
@@ -28,9 +28,8 @@
from google.auth import crypt
from google.auth import exceptions
-_IAM_API_ROOT_URI = 'https://iam.googleapis.com/v1'
-_SIGN_BLOB_URI = (
- _IAM_API_ROOT_URI + '/projects/-/serviceAccounts/{}:signBlob?alt=json')
+_IAM_API_ROOT_URI = "https://iam.googleapis.com/v1"
+_SIGN_BLOB_URI = _IAM_API_ROOT_URI + "/projects/-/serviceAccounts/{}:signBlob?alt=json"
class Signer(crypt.Signer):
@@ -68,23 +67,20 @@
"""Makes a request to the API signBlob API."""
message = _helpers.to_bytes(message)
- method = 'POST'
+ method = "POST"
url = _SIGN_BLOB_URI.format(self._service_account_email)
headers = {}
- body = json.dumps({
- 'bytesToSign': base64.b64encode(message).decode('utf-8'),
- })
+ body = json.dumps({"bytesToSign": base64.b64encode(message).decode("utf-8")})
self._credentials.before_request(self._request, method, url, headers)
- response = self._request(
- url=url, method=method, body=body, headers=headers)
+ response = self._request(url=url, method=method, body=body, headers=headers)
if response.status != http_client.OK:
raise exceptions.TransportError(
- 'Error calling the IAM signBytes API: {}'.format(
- response.data))
+ "Error calling the IAM signBytes API: {}".format(response.data)
+ )
- return json.loads(response.data.decode('utf-8'))
+ return json.loads(response.data.decode("utf-8"))
@property
def key_id(self):
@@ -99,4 +95,4 @@
@_helpers.copy_docstring(crypt.Signer)
def sign(self, message):
response = self._make_signing_request(message)
- return base64.b64decode(response['signature'])
+ return base64.b64decode(response["signature"])
diff --git a/google/auth/impersonated_credentials.py b/google/auth/impersonated_credentials.py
index bb2bbf2..70fa5dc 100644
--- a/google/auth/impersonated_credentials.py
+++ b/google/auth/impersonated_credentials.py
@@ -41,22 +41,28 @@
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
-_IAM_SCOPE = ['https://www.googleapis.com/auth/iam']
+_IAM_SCOPE = ["https://www.googleapis.com/auth/iam"]
-_IAM_ENDPOINT = ('https://iamcredentials.googleapis.com/v1/projects/-' +
- '/serviceAccounts/{}:generateAccessToken')
+_IAM_ENDPOINT = (
+ "https://iamcredentials.googleapis.com/v1/projects/-"
+ + "/serviceAccounts/{}:generateAccessToken"
+)
-_IAM_SIGN_ENDPOINT = ('https://iamcredentials.googleapis.com/v1/projects/-' +
- '/serviceAccounts/{}:signBlob')
+_IAM_SIGN_ENDPOINT = (
+ "https://iamcredentials.googleapis.com/v1/projects/-"
+ + "/serviceAccounts/{}:signBlob"
+)
-_IAM_IDTOKEN_ENDPOINT = ('https://iamcredentials.googleapis.com/v1/' +
- 'projects/-/serviceAccounts/{}:generateIdToken')
+_IAM_IDTOKEN_ENDPOINT = (
+ "https://iamcredentials.googleapis.com/v1/"
+ + "projects/-/serviceAccounts/{}:generateIdToken"
+)
-_REFRESH_ERROR = 'Unable to acquire impersonated credentials'
+_REFRESH_ERROR = "Unable to acquire impersonated credentials"
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
-_DEFAULT_TOKEN_URI = 'https://oauth2.googleapis.com/token'
+_DEFAULT_TOKEN_URI = "https://oauth2.googleapis.com/token"
def _make_iam_token_request(request, principal, headers, body):
@@ -80,34 +86,31 @@
body = json.dumps(body)
- response = request(
- url=iam_endpoint,
- method='POST',
- headers=headers,
- body=body)
+ response = request(url=iam_endpoint, method="POST", headers=headers, body=body)
- response_body = response.data.decode('utf-8')
+ response_body = response.data.decode("utf-8")
if response.status != http_client.OK:
exceptions.RefreshError(_REFRESH_ERROR, response_body)
try:
- token_response = json.loads(response.data.decode('utf-8'))
- token = token_response['accessToken']
- expiry = datetime.strptime(
- token_response['expireTime'], '%Y-%m-%dT%H:%M:%SZ')
+ token_response = json.loads(response.data.decode("utf-8"))
+ token = token_response["accessToken"]
+ expiry = datetime.strptime(token_response["expireTime"], "%Y-%m-%dT%H:%M:%SZ")
return token, expiry
except (KeyError, ValueError) as caught_exc:
new_exc = exceptions.RefreshError(
- '{}: No access token or invalid expiration in response.'.format(
- _REFRESH_ERROR),
- response_body)
+ "{}: No access token or invalid expiration in response.".format(
+ _REFRESH_ERROR
+ ),
+ response_body,
+ )
six.raise_from(new_exc, caught_exc)
-class Credentials(credentials.Credentials, credentials.Signing):
+class Credentials(credentials.Credentials, credentials.Signing):
"""This module defines impersonated credentials which are essentially
impersonated identities.
@@ -169,9 +172,14 @@
print(bucket.name)
"""
- def __init__(self, source_credentials, target_principal,
- target_scopes, delegates=None,
- lifetime=_DEFAULT_TOKEN_LIFETIME_SECS):
+ def __init__(
+ self,
+ source_credentials,
+ target_principal,
+ target_scopes,
+ delegates=None,
+ lifetime=_DEFAULT_TOKEN_LIFETIME_SECS,
+ ):
"""
Args:
source_credentials (google.auth.Credentials): The source credential
@@ -228,12 +236,10 @@
body = {
"delegates": self._delegates,
"scope": self._target_scopes,
- "lifetime": str(self._lifetime) + "s"
+ "lifetime": str(self._lifetime) + "s",
}
- headers = {
- 'Content-Type': 'application/json',
- }
+ headers = {"Content-Type": "application/json"}
# Apply the source credentials authentication info.
self._source_credentials.apply(headers)
@@ -242,29 +248,24 @@
request=request,
principal=self._target_principal,
headers=headers,
- body=body)
+ body=body,
+ )
def sign_bytes(self, message):
iam_sign_endpoint = _IAM_SIGN_ENDPOINT.format(self._target_principal)
- body = {
- "payload": base64.b64encode(message),
- "delegates": self._delegates
- }
+ body = {"payload": base64.b64encode(message), "delegates": self._delegates}
- headers = {
- 'Content-Type': 'application/json',
- }
+ headers = {"Content-Type": "application/json"}
authed_session = AuthorizedSession(self._source_credentials)
response = authed_session.post(
- url=iam_sign_endpoint,
- headers=headers,
- json=body)
+ url=iam_sign_endpoint, headers=headers, json=body
+ )
- return base64.b64decode(response.json()['signedBlob'])
+ return base64.b64decode(response.json()["signedBlob"])
@property
def signer_email(self):
@@ -283,8 +284,8 @@
"""Open ID Connect ID Token-based service account credentials.
"""
- def __init__(self, target_credentials,
- target_audience=None, include_email=False):
+
+ def __init__(self, target_credentials, target_audience=None, include_email=False):
"""
Args:
target_credentials (google.auth.Credentials): The target
@@ -294,57 +295,54 @@
"""
super(IDTokenCredentials, self).__init__()
- if not isinstance(target_credentials,
- Credentials):
- raise exceptions.GoogleAuthError("Provided Credential must be "
- "impersonated_credentials")
+ if not isinstance(target_credentials, Credentials):
+ raise exceptions.GoogleAuthError(
+ "Provided Credential must be " "impersonated_credentials"
+ )
self._target_credentials = target_credentials
self._target_audience = target_audience
self._include_email = include_email
- def from_credentials(self, target_credentials,
- target_audience=None):
+ def from_credentials(self, target_credentials, target_audience=None):
return self.__class__(
- target_credentials=self._target_credentials,
- target_audience=target_audience)
+ target_credentials=self._target_credentials, target_audience=target_audience
+ )
def with_target_audience(self, target_audience):
return self.__class__(
- target_credentials=self._target_credentials,
- target_audience=target_audience)
+ target_credentials=self._target_credentials, target_audience=target_audience
+ )
def with_include_email(self, include_email):
return self.__class__(
target_credentials=self._target_credentials,
target_audience=self._target_audience,
- include_email=include_email)
+ include_email=include_email,
+ )
@_helpers.copy_docstring(credentials.Credentials)
def refresh(self, request):
- iam_sign_endpoint = _IAM_IDTOKEN_ENDPOINT.format(self.
- _target_credentials.
- signer_email)
+ iam_sign_endpoint = _IAM_IDTOKEN_ENDPOINT.format(
+ self._target_credentials.signer_email
+ )
body = {
"audience": self._target_audience,
"delegates": self._target_credentials._delegates,
- "includeEmail": self._include_email
+ "includeEmail": self._include_email,
}
- headers = {
- 'Content-Type': 'application/json',
- }
+ headers = {"Content-Type": "application/json"}
- authed_session = AuthorizedSession(self._target_credentials.
- _source_credentials)
+ authed_session = AuthorizedSession(self._target_credentials._source_credentials)
response = authed_session.post(
url=iam_sign_endpoint,
headers=headers,
- data=json.dumps(body).encode('utf-8'))
+ data=json.dumps(body).encode("utf-8"),
+ )
- id_token = response.json()['token']
+ id_token = response.json()["token"]
self.token = id_token
- self.expiry = datetime.fromtimestamp(jwt.decode(id_token,
- verify=False)['exp'])
+ self.expiry = datetime.fromtimestamp(jwt.decode(id_token, verify=False)["exp"])
diff --git a/google/auth/jwt.py b/google/auth/jwt.py
index d63c50b..a30c575 100644
--- a/google/auth/jwt.py
+++ b/google/auth/jwt.py
@@ -79,36 +79,30 @@
if key_id is None:
key_id = signer.key_id
- header.update({'typ': 'JWT', 'alg': 'RS256'})
+ header.update({"typ": "JWT", "alg": "RS256"})
if key_id is not None:
- header['kid'] = key_id
+ header["kid"] = key_id
segments = [
- _helpers.unpadded_urlsafe_b64encode(
- json.dumps(header).encode('utf-8')
- ),
- _helpers.unpadded_urlsafe_b64encode(
- json.dumps(payload).encode('utf-8')
- ),
+ _helpers.unpadded_urlsafe_b64encode(json.dumps(header).encode("utf-8")),
+ _helpers.unpadded_urlsafe_b64encode(json.dumps(payload).encode("utf-8")),
]
- signing_input = b'.'.join(segments)
+ signing_input = b".".join(segments)
signature = signer.sign(signing_input)
- segments.append(
- _helpers.unpadded_urlsafe_b64encode(signature)
- )
+ segments.append(_helpers.unpadded_urlsafe_b64encode(signature))
- return b'.'.join(segments)
+ return b".".join(segments)
def _decode_jwt_segment(encoded_section):
"""Decodes a single JWT segment."""
section_bytes = _helpers.padded_urlsafe_b64decode(encoded_section)
try:
- return json.loads(section_bytes.decode('utf-8'))
+ return json.loads(section_bytes.decode("utf-8"))
except ValueError as caught_exc:
- new_exc = ValueError('Can\'t parse segment: {0}'.format(section_bytes))
+ new_exc = ValueError("Can't parse segment: {0}".format(section_bytes))
six.raise_from(new_exc, caught_exc)
@@ -127,12 +121,11 @@
"""
token = _helpers.to_bytes(token)
- if token.count(b'.') != 2:
- raise ValueError(
- 'Wrong number of segments in token: {0}'.format(token))
+ if token.count(b".") != 2:
+ raise ValueError("Wrong number of segments in token: {0}".format(token))
- encoded_header, encoded_payload, signature = token.split(b'.')
- signed_section = encoded_header + b'.' + encoded_payload
+ encoded_header, encoded_payload, signature = token.split(b".")
+ signed_section = encoded_header + b"." + encoded_payload
signature = _helpers.padded_urlsafe_b64decode(signature)
# Parse segments
@@ -172,26 +165,25 @@
now = _helpers.datetime_to_secs(_helpers.utcnow())
# Make sure the iat and exp claims are present.
- for key in ('iat', 'exp'):
+ for key in ("iat", "exp"):
if key not in payload:
- raise ValueError(
- 'Token does not contain required claim {}'.format(key))
+ raise ValueError("Token does not contain required claim {}".format(key))
# Make sure the token wasn't issued in the future.
- iat = payload['iat']
+ iat = payload["iat"]
# Err on the side of accepting a token that is slightly early to account
# for clock skew.
earliest = iat - _helpers.CLOCK_SKEW_SECS
if now < earliest:
- raise ValueError('Token used too early, {} < {}'.format(now, iat))
+ raise ValueError("Token used too early, {} < {}".format(now, iat))
# Make sure the token wasn't issued in the past.
- exp = payload['exp']
+ exp = payload["exp"]
# Err on the side of accepting a token that is slightly out of date
# to account for clow skew.
latest = exp + _helpers.CLOCK_SKEW_SECS
if latest < now:
- raise ValueError('Token expired, {} < {}'.format(latest, now))
+ raise ValueError("Token expired, {} < {}".format(latest, now))
def decode(token, certs=None, verify=True, audience=None):
@@ -224,11 +216,10 @@
# If certs is specified as a dictionary of key IDs to certificates, then
# use the certificate identified by the key ID in the token header.
if isinstance(certs, collections.Mapping):
- key_id = header.get('kid')
+ key_id = header.get("kid")
if key_id:
if key_id not in certs:
- raise ValueError(
- 'Certificate for key id {} not found.'.format(key_id))
+ raise ValueError("Certificate for key id {} not found.".format(key_id))
certs_to_check = [certs[key_id]]
# If there's no key id in the header, check against all of the certs.
else:
@@ -238,24 +229,25 @@
# Verify that the signature matches the message.
if not crypt.verify_signature(signed_section, signature, certs_to_check):
- raise ValueError('Could not verify token signature.')
+ raise ValueError("Could not verify token signature.")
# Verify the issued at and created times in the payload.
_verify_iat_and_exp(payload)
# Check audience.
if audience is not None:
- claim_audience = payload.get('aud')
+ claim_audience = payload.get("aud")
if audience != claim_audience:
raise ValueError(
- 'Token has wrong audience {}, expected {}'.format(
- claim_audience, audience))
+ "Token has wrong audience {}, expected {}".format(
+ claim_audience, audience
+ )
+ )
return payload
-class Credentials(google.auth.credentials.Signing,
- google.auth.credentials.Credentials):
+class Credentials(google.auth.credentials.Signing, google.auth.credentials.Credentials):
"""Credentials that use a JWT as the bearer token.
These credentials require an "audience" claim. This claim identifies the
@@ -305,9 +297,15 @@
new_credentials = credentials.with_claims(audience=new_audience)
"""
- def __init__(self, signer, issuer, subject, audience,
- additional_claims=None,
- token_lifetime=_DEFAULT_TOKEN_LIFETIME_SECS):
+ def __init__(
+ self,
+ signer,
+ issuer,
+ subject,
+ audience,
+ additional_claims=None,
+ token_lifetime=_DEFAULT_TOKEN_LIFETIME_SECS,
+ ):
"""
Args:
signer (google.auth.crypt.Signer): The signer used to sign JWTs.
@@ -348,8 +346,8 @@
Raises:
ValueError: If the info is not in the expected format.
"""
- kwargs.setdefault('subject', info['client_email'])
- kwargs.setdefault('issuer', info['client_email'])
+ kwargs.setdefault("subject", info["client_email"])
+ kwargs.setdefault("issuer", info["client_email"])
return cls(signer, **kwargs)
@classmethod
@@ -367,8 +365,7 @@
Raises:
ValueError: If the info is not in the expected format.
"""
- signer = _service_account_info.from_dict(
- info, require=['client_email'])
+ signer = _service_account_info.from_dict(info, require=["client_email"])
return cls._from_signer_and_info(signer, info, **kwargs)
@classmethod
@@ -384,7 +381,8 @@
google.auth.jwt.Credentials: The constructed credentials.
"""
info, signer = _service_account_info.from_filename(
- filename, require=['client_email'])
+ filename, require=["client_email"]
+ )
return cls._from_signer_and_info(signer, info, **kwargs)
@classmethod
@@ -415,15 +413,13 @@
Returns:
google.auth.jwt.Credentials: A new Credentials instance.
"""
- kwargs.setdefault('issuer', credentials.signer_email)
- kwargs.setdefault('subject', credentials.signer_email)
- return cls(
- credentials.signer,
- audience=audience,
- **kwargs)
+ kwargs.setdefault("issuer", credentials.signer_email)
+ kwargs.setdefault("subject", credentials.signer_email)
+ return cls(credentials.signer, audience=audience, **kwargs)
- def with_claims(self, issuer=None, subject=None, audience=None,
- additional_claims=None):
+ def with_claims(
+ self, issuer=None, subject=None, audience=None, additional_claims=None
+ ):
"""Returns a copy of these credentials with modified claims.
Args:
@@ -448,7 +444,8 @@
issuer=issuer if issuer is not None else self._issuer,
subject=subject if subject is not None else self._subject,
audience=audience if audience is not None else self._audience,
- additional_claims=new_additional_claims)
+ additional_claims=new_additional_claims,
+ )
def _make_jwt(self):
"""Make a signed JWT.
@@ -461,11 +458,11 @@
expiry = now + lifetime
payload = {
- 'iss': self._issuer,
- 'sub': self._subject,
- 'iat': _helpers.datetime_to_secs(now),
- 'exp': _helpers.datetime_to_secs(expiry),
- 'aud': self._audience,
+ "iss": self._issuer,
+ "sub": self._subject,
+ "iat": _helpers.datetime_to_secs(now),
+ "exp": _helpers.datetime_to_secs(expiry),
+ "aud": self._audience,
}
payload.update(self._additional_claims)
@@ -500,8 +497,8 @@
class OnDemandCredentials(
- google.auth.credentials.Signing,
- google.auth.credentials.Credentials):
+ google.auth.credentials.Signing, google.auth.credentials.Credentials
+):
"""On-demand JWT credentials.
Like :class:`Credentials`, this class uses a JWT as the bearer token for
@@ -519,10 +516,15 @@
.. _grpc: http://www.grpc.io/
"""
- def __init__(self, signer, issuer, subject,
- additional_claims=None,
- token_lifetime=_DEFAULT_TOKEN_LIFETIME_SECS,
- max_cache_size=_DEFAULT_MAX_CACHE_SIZE):
+ def __init__(
+ self,
+ signer,
+ issuer,
+ subject,
+ additional_claims=None,
+ token_lifetime=_DEFAULT_TOKEN_LIFETIME_SECS,
+ max_cache_size=_DEFAULT_MAX_CACHE_SIZE,
+ ):
"""
Args:
signer (google.auth.crypt.Signer): The signer used to sign JWTs.
@@ -563,8 +565,8 @@
Raises:
ValueError: If the info is not in the expected format.
"""
- kwargs.setdefault('subject', info['client_email'])
- kwargs.setdefault('issuer', info['client_email'])
+ kwargs.setdefault("subject", info["client_email"])
+ kwargs.setdefault("issuer", info["client_email"])
return cls(signer, **kwargs)
@classmethod
@@ -582,8 +584,7 @@
Raises:
ValueError: If the info is not in the expected format.
"""
- signer = _service_account_info.from_dict(
- info, require=['client_email'])
+ signer = _service_account_info.from_dict(info, require=["client_email"])
return cls._from_signer_and_info(signer, info, **kwargs)
@classmethod
@@ -599,7 +600,8 @@
google.auth.jwt.OnDemandCredentials: The constructed credentials.
"""
info, signer = _service_account_info.from_filename(
- filename, require=['client_email'])
+ filename, require=["client_email"]
+ )
return cls._from_signer_and_info(signer, info, **kwargs)
@classmethod
@@ -626,8 +628,8 @@
Returns:
google.auth.jwt.Credentials: A new Credentials instance.
"""
- kwargs.setdefault('issuer', credentials.signer_email)
- kwargs.setdefault('subject', credentials.signer_email)
+ kwargs.setdefault("issuer", credentials.signer_email)
+ kwargs.setdefault("subject", credentials.signer_email)
return cls(credentials.signer, **kwargs)
def with_claims(self, issuer=None, subject=None, additional_claims=None):
@@ -653,7 +655,8 @@
issuer=issuer if issuer is not None else self._issuer,
subject=subject if subject is not None else self._subject,
additional_claims=new_additional_claims,
- max_cache_size=self._cache.maxsize)
+ max_cache_size=self._cache.maxsize,
+ )
@property
def valid(self):
@@ -678,11 +681,11 @@
expiry = now + lifetime
payload = {
- 'iss': self._issuer,
- 'sub': self._subject,
- 'iat': _helpers.datetime_to_secs(now),
- 'exp': _helpers.datetime_to_secs(expiry),
- 'aud': audience,
+ "iss": self._issuer,
+ "sub": self._subject,
+ "iat": _helpers.datetime_to_secs(now),
+ "exp": _helpers.datetime_to_secs(expiry),
+ "aud": audience,
}
payload.update(self._additional_claims)
@@ -725,7 +728,8 @@
# pylint: disable=unused-argument
# (pylint doesn't correctly recognize overridden methods.)
raise exceptions.RefreshError(
- 'OnDemandCredentials can not be directly refreshed.')
+ "OnDemandCredentials can not be directly refreshed."
+ )
def before_request(self, request, method, url, headers):
"""Performs credential-specific before request logic.
@@ -743,7 +747,8 @@
parts = urllib.parse.urlsplit(url)
# Strip query string and fragment
audience = urllib.parse.urlunsplit(
- (parts.scheme, parts.netloc, parts.path, "", ""))
+ (parts.scheme, parts.netloc, parts.path, "", "")
+ )
token = self._get_jwt_for_audience(audience)
self.apply(headers, token=token)
diff --git a/google/auth/transport/__init__.py b/google/auth/transport/__init__.py
index d73c63c..53aa4ba 100644
--- a/google/auth/transport/__init__.py
+++ b/google/auth/transport/__init__.py
@@ -45,17 +45,17 @@
@abc.abstractproperty
def status(self):
"""int: The HTTP status code."""
- raise NotImplementedError('status must be implemented.')
+ raise NotImplementedError("status must be implemented.")
@abc.abstractproperty
def headers(self):
"""Mapping[str, str]: The HTTP response headers."""
- raise NotImplementedError('headers must be implemented.')
+ raise NotImplementedError("headers must be implemented.")
@abc.abstractproperty
def data(self):
"""bytes: The response body."""
- raise NotImplementedError('data must be implemented.')
+ raise NotImplementedError("data must be implemented.")
@six.add_metaclass(abc.ABCMeta)
@@ -69,8 +69,9 @@
"""
@abc.abstractmethod
- def __call__(self, url, method='GET', body=None, headers=None,
- timeout=None, **kwargs):
+ def __call__(
+ self, url, method="GET", body=None, headers=None, timeout=None, **kwargs
+ ):
"""Make an HTTP request.
Args:
@@ -93,4 +94,4 @@
"""
# pylint: disable=redundant-returns-doc, missing-raises-doc
# (pylint doesn't play well with abstract docstrings.)
- raise NotImplementedError('__call__ must be implemented.')
+ raise NotImplementedError("__call__ must be implemented.")
diff --git a/google/auth/transport/_http_client.py b/google/auth/transport/_http_client.py
index 08b1ab6..b52ca7b 100644
--- a/google/auth/transport/_http_client.py
+++ b/google/auth/transport/_http_client.py
@@ -33,10 +33,10 @@
Args:
response (http.client.HTTPResponse): The raw http client response.
"""
+
def __init__(self, response):
self._status = response.status
- self._headers = {
- key.lower(): value for key, value in response.getheaders()}
+ self._headers = {key.lower(): value for key, value in response.getheaders()}
self._data = response.read()
@property
@@ -55,8 +55,9 @@
class Request(transport.Request):
"""http.client transport request adapter."""
- def __call__(self, url, method='GET', body=None, headers=None,
- timeout=None, **kwargs):
+ def __call__(
+ self, url, method="GET", body=None, headers=None, timeout=None, **kwargs
+ ):
"""Make an HTTP request using http.client.
Args:
@@ -88,20 +89,21 @@
# http.client needs the host and path parts specified separately.
parts = urllib.parse.urlsplit(url)
path = urllib.parse.urlunsplit(
- ('', '', parts.path, parts.query, parts.fragment))
+ ("", "", parts.path, parts.query, parts.fragment)
+ )
- if parts.scheme != 'http':
+ if parts.scheme != "http":
raise exceptions.TransportError(
- 'http.client transport only supports the http scheme, {}'
- 'was specified'.format(parts.scheme))
+ "http.client transport only supports the http scheme, {}"
+ "was specified".format(parts.scheme)
+ )
connection = http_client.HTTPConnection(parts.netloc, timeout=timeout)
try:
- _LOGGER.debug('Making request: %s %s', method, url)
+ _LOGGER.debug("Making request: %s %s", method, url)
- connection.request(
- method, path, body=body, headers=headers, **kwargs)
+ connection.request(method, path, body=body, headers=headers, **kwargs)
response = connection.getresponse()
return Response(response)
diff --git a/google/auth/transport/grpc.py b/google/auth/transport/grpc.py
index 0d44f64..9a1bc6d 100644
--- a/google/auth/transport/grpc.py
+++ b/google/auth/transport/grpc.py
@@ -17,13 +17,14 @@
from __future__ import absolute_import
import six
+
try:
import grpc
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.'
+ "gRPC is not installed, please install the grpcio package "
+ "to use the gRPC transport."
),
caught_exc,
)
@@ -42,6 +43,7 @@
request (google.auth.transport.Request): A HTTP transport request
object used to refresh credentials as needed.
"""
+
def __init__(self, credentials, request):
# pylint: disable=no-value-for-parameter
# pylint doesn't realize that the super method takes no arguments
@@ -59,10 +61,8 @@
"""
headers = {}
self._credentials.before_request(
- self._request,
- context.method_name,
- context.service_url,
- headers)
+ self._request, context.method_name, context.service_url, headers
+ )
return list(six.iteritems(headers))
@@ -78,7 +78,8 @@
def secure_authorized_channel(
- credentials, request, target, ssl_credentials=None, **kwargs):
+ credentials, request, target, ssl_credentials=None, **kwargs
+):
"""Creates a secure authorized gRPC channel.
This creates a channel with SSL and :class:`AuthMetadataPlugin`. This
@@ -130,6 +131,7 @@
# Combine the ssl credentials and the authorization credentials.
composite_credentials = grpc.composite_channel_credentials(
- ssl_credentials, google_auth_credentials)
+ ssl_credentials, google_auth_credentials
+ )
return grpc.secure_channel(target, composite_credentials, **kwargs)
diff --git a/google/auth/transport/requests.py b/google/auth/transport/requests.py
index 8250c74..564a0cd 100644
--- a/google/auth/transport/requests.py
+++ b/google/auth/transport/requests.py
@@ -23,10 +23,11 @@
import requests
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.'
+ "The requests library is not installed, please install the "
+ "requests package to use the requests transport."
),
caught_exc,
)
@@ -46,6 +47,7 @@
Args:
response (requests.Response): The raw Requests response.
"""
+
def __init__(self, response):
self._response = response
@@ -85,14 +87,16 @@
.. automethod:: __call__
"""
+
def __init__(self, session=None):
if not session:
session = requests.Session()
self.session = session
- def __call__(self, url, method='GET', body=None, headers=None,
- timeout=None, **kwargs):
+ def __call__(
+ self, url, method="GET", body=None, headers=None, timeout=None, **kwargs
+ ):
"""Make an HTTP request using requests.
Args:
@@ -114,10 +118,10 @@
google.auth.exceptions.TransportError: If any exception occurred.
"""
try:
- _LOGGER.debug('Making request: %s %s', method, url)
+ _LOGGER.debug("Making request: %s %s", method, url)
response = self.session.request(
- method, url, data=body, headers=headers, timeout=timeout,
- **kwargs)
+ method, url, data=body, headers=headers, timeout=timeout, **kwargs
+ )
return _Response(response)
except requests.exceptions.RequestException as caught_exc:
new_exc = exceptions.TransportError(caught_exc)
@@ -157,11 +161,15 @@
an instance of :class:`~google.auth.transport.requests.Request`
is created.
"""
- def __init__(self, credentials,
- refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,
- max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,
- refresh_timeout=None,
- auth_request=None):
+
+ def __init__(
+ self,
+ credentials,
+ refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,
+ max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,
+ refresh_timeout=None,
+ auth_request=None,
+ ):
super(AuthorizedSession, self).__init__()
self.credentials = credentials
self._refresh_status_codes = refresh_status_codes
@@ -194,40 +202,50 @@
# Use a kwarg for this instead of an attribute to maintain
# thread-safety.
- _credential_refresh_attempt = kwargs.pop(
- '_credential_refresh_attempt', 0)
+ _credential_refresh_attempt = kwargs.pop("_credential_refresh_attempt", 0)
# Make a copy of the headers. They will be modified by the credentials
# and we want to pass the original headers if we recurse.
request_headers = headers.copy() if headers is not None else {}
self.credentials.before_request(
- self._auth_request, method, url, request_headers)
+ self._auth_request, method, url, request_headers
+ )
response = super(AuthorizedSession, self).request(
- method, url, data=data, headers=request_headers, **kwargs)
+ method, url, data=data, headers=request_headers, **kwargs
+ )
# If the response indicated that the credentials needed to be
# refreshed, then refresh the credentials and re-attempt the
# request.
# 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.
- if (response.status_code in self._refresh_status_codes
- and _credential_refresh_attempt < self._max_refresh_attempts):
+ if (
+ response.status_code in self._refresh_status_codes
+ and _credential_refresh_attempt < self._max_refresh_attempts
+ ):
_LOGGER.info(
- 'Refreshing credentials due to a %s response. Attempt %s/%s.',
- response.status_code, _credential_refresh_attempt + 1,
- self._max_refresh_attempts)
+ "Refreshing credentials due to a %s response. Attempt %s/%s.",
+ response.status_code,
+ _credential_refresh_attempt + 1,
+ self._max_refresh_attempts,
+ )
auth_request_with_timeout = functools.partial(
- self._auth_request, timeout=self._refresh_timeout)
+ 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(
- method, url, data=data, headers=headers,
+ method,
+ url,
+ data=data,
+ headers=headers,
_credential_refresh_attempt=_credential_refresh_attempt + 1,
- **kwargs)
+ **kwargs
+ )
return response
diff --git a/google/auth/transport/urllib3.py b/google/auth/transport/urllib3.py
index 37eb317..dbb186b 100644
--- a/google/auth/transport/urllib3.py
+++ b/google/auth/transport/urllib3.py
@@ -34,10 +34,11 @@
import urllib3
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.'
+ "The urllib3 library is not installed, please install the "
+ "urllib3 package to use the urllib3 transport."
),
caught_exc,
)
@@ -56,6 +57,7 @@
Args:
response (urllib3.response.HTTPResponse): The raw urllib3 response.
"""
+
def __init__(self, response):
self._response = response
@@ -97,11 +99,13 @@
.. automethod:: __call__
"""
+
def __init__(self, http):
self.http = http
- def __call__(self, url, method='GET', body=None, headers=None,
- timeout=None, **kwargs):
+ def __call__(
+ self, url, method="GET", body=None, headers=None, timeout=None, **kwargs
+ ):
"""Make an HTTP request using urllib3.
Args:
@@ -125,12 +129,13 @@
# urllib3 uses a sentinel default value for timeout, so only set it if
# specified.
if timeout is not None:
- kwargs['timeout'] = timeout
+ kwargs["timeout"] = timeout
try:
- _LOGGER.debug('Making request: %s %s', method, url)
+ _LOGGER.debug("Making request: %s %s", method, url)
response = self.http.request(
- method, url, body=body, headers=headers, **kwargs)
+ method, url, body=body, headers=headers, **kwargs
+ )
return _Response(response)
except urllib3.exceptions.HTTPError as caught_exc:
new_exc = exceptions.TransportError(caught_exc)
@@ -139,9 +144,7 @@
def _make_default_http():
if certifi is not None:
- return urllib3.PoolManager(
- cert_reqs='CERT_REQUIRED',
- ca_certs=certifi.where())
+ return urllib3.PoolManager(cert_reqs="CERT_REQUIRED", ca_certs=certifi.where())
else:
return urllib3.PoolManager()
@@ -178,9 +181,14 @@
max_refresh_attempts (int): The maximum number of times to attempt to
refresh the credentials and retry the request.
"""
- def __init__(self, credentials, http=None,
- refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,
- max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS):
+
+ def __init__(
+ self,
+ credentials,
+ http=None,
+ refresh_status_codes=transport.DEFAULT_REFRESH_STATUS_CODES,
+ max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,
+ ):
if http is None:
http = _make_default_http()
@@ -204,8 +212,7 @@
# Use a kwarg for this instead of an attribute to maintain
# thread-safety.
- _credential_refresh_attempt = kwargs.pop(
- '_credential_refresh_attempt', 0)
+ _credential_refresh_attempt = kwargs.pop("_credential_refresh_attempt", 0)
if headers is None:
headers = self.headers
@@ -214,11 +221,11 @@
# and we want to pass the original headers if we recurse.
request_headers = headers.copy()
- self.credentials.before_request(
- self._request, method, url, request_headers)
+ self.credentials.before_request(self._request, method, url, request_headers)
response = self.http.urlopen(
- method, url, body=body, headers=request_headers, **kwargs)
+ method, url, body=body, headers=request_headers, **kwargs
+ )
# If the response indicated that the credentials needed to be
# refreshed, then refresh the credentials and re-attempt the
@@ -227,21 +234,29 @@
# the time the request is made, so we may need to try twice.
# The reason urllib3's retries aren't used is because they
# don't allow you to modify the request headers. :/
- if (response.status in self._refresh_status_codes
- and _credential_refresh_attempt < self._max_refresh_attempts):
+ if (
+ response.status in self._refresh_status_codes
+ and _credential_refresh_attempt < self._max_refresh_attempts
+ ):
_LOGGER.info(
- 'Refreshing credentials due to a %s response. Attempt %s/%s.',
- response.status, _credential_refresh_attempt + 1,
- self._max_refresh_attempts)
+ "Refreshing credentials due to a %s response. Attempt %s/%s.",
+ response.status,
+ _credential_refresh_attempt + 1,
+ self._max_refresh_attempts,
+ )
self.credentials.refresh(self._request)
# Recurse. Pass in the original headers, not our modified set.
return self.urlopen(
- method, url, body=body, headers=headers,
+ method,
+ url,
+ body=body,
+ headers=headers,
_credential_refresh_attempt=_credential_refresh_attempt + 1,
- **kwargs)
+ **kwargs
+ )
return response
diff --git a/google/oauth2/_client.py b/google/oauth2/_client.py
index eac01b7..996f9b7 100644
--- a/google/oauth2/_client.py
+++ b/google/oauth2/_client.py
@@ -34,9 +34,9 @@
from google.auth import exceptions
from google.auth import jwt
-_URLENCODED_CONTENT_TYPE = 'application/x-www-form-urlencoded'
-_JWT_GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
-_REFRESH_GRANT_TYPE = 'refresh_token'
+_URLENCODED_CONTENT_TYPE = "application/x-www-form-urlencoded"
+_JWT_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"
+_REFRESH_GRANT_TYPE = "refresh_token"
def _handle_error_response(response_body):
@@ -50,15 +50,14 @@
"""
try:
error_data = json.loads(response_body)
- error_details = '{}: {}'.format(
- error_data['error'],
- error_data.get('error_description'))
+ error_details = "{}: {}".format(
+ error_data["error"], error_data.get("error_description")
+ )
# If no details could be extracted, use the response data.
except (KeyError, ValueError):
error_details = response_body
- raise exceptions.RefreshError(
- error_details, response_body)
+ raise exceptions.RefreshError(error_details, response_body)
def _parse_expiry(response_data):
@@ -71,11 +70,10 @@
Optional[datetime]: The expiration or ``None`` if no expiration was
specified.
"""
- expires_in = response_data.get('expires_in', None)
+ expires_in = response_data.get("expires_in", None)
if expires_in is not None:
- return _helpers.utcnow() + datetime.timedelta(
- seconds=expires_in)
+ return _helpers.utcnow() + datetime.timedelta(seconds=expires_in)
else:
return None
@@ -98,24 +96,20 @@
an error.
"""
body = urllib.parse.urlencode(body)
- headers = {
- 'content-type': _URLENCODED_CONTENT_TYPE,
- }
+ headers = {"content-type": _URLENCODED_CONTENT_TYPE}
retry = 0
# retry to fetch token for maximum of two times if any internal failure
# occurs.
while True:
- response = request(
- method='POST', url=token_uri, headers=headers, body=body)
- response_body = response.data.decode('utf-8')
+ response = request(method="POST", url=token_uri, headers=headers, body=body)
+ response_body = response.data.decode("utf-8")
if response.status == http_client.OK:
break
else:
- error_desc = json.loads(
- response_body).get('error_description') or ''
- if error_desc == 'internal_failure' and retry < 1:
+ error_desc = json.loads(response_body).get("error_description") or ""
+ if error_desc == "internal_failure" and retry < 1:
retry += 1
continue
_handle_error_response(response_body)
@@ -147,18 +141,14 @@
.. _rfc7523 section 4: https://tools.ietf.org/html/rfc7523#section-4
"""
- body = {
- 'assertion': assertion,
- 'grant_type': _JWT_GRANT_TYPE,
- }
+ body = {"assertion": assertion, "grant_type": _JWT_GRANT_TYPE}
response_data = _token_endpoint_request(request, token_uri, body)
try:
- access_token = response_data['access_token']
+ access_token = response_data["access_token"]
except KeyError as caught_exc:
- new_exc = exceptions.RefreshError(
- 'No access token in response.', response_data)
+ new_exc = exceptions.RefreshError("No access token in response.", response_data)
six.raise_from(new_exc, caught_exc)
expiry = _parse_expiry(response_data)
@@ -191,28 +181,25 @@
google.auth.exceptions.RefreshError: If the token endpoint returned
an error.
"""
- body = {
- 'assertion': assertion,
- 'grant_type': _JWT_GRANT_TYPE,
- }
+ body = {"assertion": assertion, "grant_type": _JWT_GRANT_TYPE}
response_data = _token_endpoint_request(request, token_uri, body)
try:
- id_token = response_data['id_token']
+ id_token = response_data["id_token"]
except KeyError as caught_exc:
- new_exc = exceptions.RefreshError(
- 'No ID token in response.', response_data)
+ new_exc = exceptions.RefreshError("No ID token in response.", response_data)
six.raise_from(new_exc, caught_exc)
payload = jwt.decode(id_token, verify=False)
- expiry = datetime.datetime.utcfromtimestamp(payload['exp'])
+ expiry = datetime.datetime.utcfromtimestamp(payload["exp"])
return id_token, expiry, response_data
-def refresh_grant(request, token_uri, refresh_token, client_id, client_secret,
- scopes=None):
+def refresh_grant(
+ request, token_uri, refresh_token, client_id, client_secret, scopes=None
+):
"""Implements the OAuth 2.0 refresh token grant.
For more details, see `rfc678 section 6`_.
@@ -243,24 +230,23 @@
.. _rfc6748 section 6: https://tools.ietf.org/html/rfc6749#section-6
"""
body = {
- 'grant_type': _REFRESH_GRANT_TYPE,
- 'client_id': client_id,
- 'client_secret': client_secret,
- 'refresh_token': refresh_token,
+ "grant_type": _REFRESH_GRANT_TYPE,
+ "client_id": client_id,
+ "client_secret": client_secret,
+ "refresh_token": refresh_token,
}
if scopes:
- body['scope'] = ' '.join(scopes)
+ body["scope"] = " ".join(scopes)
response_data = _token_endpoint_request(request, token_uri, body)
try:
- access_token = response_data['access_token']
+ access_token = response_data["access_token"]
except KeyError as caught_exc:
- new_exc = exceptions.RefreshError(
- 'No access token in response.', response_data)
+ 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)
+ refresh_token = response_data.get("refresh_token", refresh_token)
expiry = _parse_expiry(response_data)
return access_token, refresh_token, expiry, response_data
diff --git a/google/oauth2/credentials.py b/google/oauth2/credentials.py
index 9e11416..676a432 100644
--- a/google/oauth2/credentials.py
+++ b/google/oauth2/credentials.py
@@ -43,15 +43,22 @@
# The Google OAuth 2.0 token endpoint. Used for authorized user credentials.
-_GOOGLE_OAUTH2_TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token'
+_GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/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,
- token_uri=None, client_id=None, client_secret=None,
- scopes=None):
+ def __init__(
+ self,
+ token,
+ refresh_token=None,
+ id_token=None,
+ token_uri=None,
+ client_id=None,
+ client_secret=None,
+ scopes=None,
+ ):
"""
Args:
token (Optional(str)): The OAuth 2.0 access token. Can be None
@@ -124,35 +131,43 @@
@_helpers.copy_docstring(credentials.Credentials)
def refresh(self, request):
- if (self._refresh_token is None or
- self._token_uri is None or
- self._client_id is None or
- self._client_secret is None):
+ if (
+ self._refresh_token is None
+ or self._token_uri is None
+ or self._client_id is None
+ or self._client_secret is None
+ ):
raise exceptions.RefreshError(
- 'The credentials do not contain the necessary fields need to '
- 'refresh the access token. You must specify refresh_token, '
- 'token_uri, client_id, and client_secret.')
+ "The credentials do not contain the necessary fields need to "
+ "refresh the access token. You must specify refresh_token, "
+ "token_uri, client_id, and client_secret."
+ )
- access_token, refresh_token, expiry, grant_response = (
- _client.refresh_grant(
- request, self._token_uri, self._refresh_token, self._client_id,
- self._client_secret, self._scopes))
+ access_token, refresh_token, expiry, grant_response = _client.refresh_grant(
+ request,
+ self._token_uri,
+ self._refresh_token,
+ self._client_id,
+ self._client_secret,
+ self._scopes,
+ )
self.token = access_token
self.expiry = expiry
self._refresh_token = refresh_token
- self._id_token = grant_response.get('id_token')
+ self._id_token = grant_response.get("id_token")
- if self._scopes and 'scopes' in grant_response:
+ if self._scopes and "scopes" in grant_response:
requested_scopes = frozenset(self._scopes)
- granted_scopes = frozenset(grant_response['scopes'].split())
- scopes_requested_but_not_granted = (
- requested_scopes - granted_scopes)
+ granted_scopes = frozenset(grant_response["scopes"].split())
+ scopes_requested_but_not_granted = requested_scopes - granted_scopes
if scopes_requested_but_not_granted:
raise exceptions.RefreshError(
- 'Not all requested scopes were granted by the '
- 'authorization server, missing scopes {}.'.format(
- ', '.join(scopes_requested_but_not_granted)))
+ "Not all requested scopes were granted by the "
+ "authorization server, missing scopes {}.".format(
+ ", ".join(scopes_requested_but_not_granted)
+ )
+ )
@classmethod
def from_authorized_user_info(cls, info, scopes=None):
@@ -171,21 +186,23 @@
Raises:
ValueError: If the info is not in the expected format.
"""
- keys_needed = set(('refresh_token', 'client_id', 'client_secret'))
+ 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)))
+ "Authorized user info was not in the expected format, missing "
+ "fields {}.".format(", ".join(missing))
+ )
return cls(
None, # No access token, must be refreshed.
- refresh_token=info['refresh_token'],
+ refresh_token=info["refresh_token"],
token_uri=_GOOGLE_OAUTH2_TOKEN_ENDPOINT,
scopes=scopes,
- client_id=info['client_id'],
- client_secret=info['client_secret'])
+ client_id=info["client_id"],
+ client_secret=info["client_secret"],
+ )
@classmethod
def from_authorized_user_file(cls, filename, scopes=None):
@@ -203,6 +220,6 @@
Raises:
ValueError: If the file is not in the expected format.
"""
- with io.open(filename, 'r', encoding='utf-8') as json_file:
+ with io.open(filename, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
return cls.from_authorized_user_info(data, scopes)
diff --git a/google/oauth2/id_token.py b/google/oauth2/id_token.py
index 208ab62..bc48445 100644
--- a/google/oauth2/id_token.py
+++ b/google/oauth2/id_token.py
@@ -67,13 +67,14 @@
# The URL that provides public certificates for verifying ID tokens issued
# by Google's OAuth 2.0 authorization server.
-_GOOGLE_OAUTH2_CERTS_URL = 'https://www.googleapis.com/oauth2/v1/certs'
+_GOOGLE_OAUTH2_CERTS_URL = "https://www.googleapis.com/oauth2/v1/certs"
# The URL that provides public certificates for verifying ID tokens issued
# by Firebase and the Google APIs infrastructure
_GOOGLE_APIS_CERTS_URL = (
- 'https://www.googleapis.com/robot/v1/metadata/x509'
- '/securetoken@system.gserviceaccount.com')
+ "https://www.googleapis.com/robot/v1/metadata/x509"
+ "/securetoken@system.gserviceaccount.com"
+)
def _fetch_certs(request, certs_url):
@@ -91,17 +92,17 @@
Mapping[str, str]: A mapping of public key ID to x.509 certificate
data.
"""
- response = request(certs_url, method='GET')
+ response = request(certs_url, method="GET")
if response.status != http_client.OK:
raise exceptions.TransportError(
- 'Could not fetch certificates at {}'.format(certs_url))
+ "Could not fetch certificates at {}".format(certs_url)
+ )
- return json.loads(response.data.decode('utf-8'))
+ return json.loads(response.data.decode("utf-8"))
-def verify_token(id_token, request, audience=None,
- certs_url=_GOOGLE_OAUTH2_CERTS_URL):
+def verify_token(id_token, request, audience=None, certs_url=_GOOGLE_OAUTH2_CERTS_URL):
"""Verifies an ID token and returns the decoded token.
Args:
@@ -137,8 +138,8 @@
Mapping[str, Any]: The decoded token.
"""
return verify_token(
- id_token, request, audience=audience,
- certs_url=_GOOGLE_OAUTH2_CERTS_URL)
+ id_token, request, audience=audience, certs_url=_GOOGLE_OAUTH2_CERTS_URL
+ )
def verify_firebase_token(id_token, request, audience=None):
@@ -156,4 +157,5 @@
Mapping[str, Any]: The decoded token.
"""
return verify_token(
- id_token, request, audience=audience, certs_url=_GOOGLE_APIS_CERTS_URL)
+ id_token, request, audience=audience, certs_url=_GOOGLE_APIS_CERTS_URL
+ )
diff --git a/google/oauth2/service_account.py b/google/oauth2/service_account.py
index c60c565..17fdd51 100644
--- a/google/oauth2/service_account.py
+++ b/google/oauth2/service_account.py
@@ -82,9 +82,7 @@
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
-class Credentials(credentials.Signing,
- credentials.Scoped,
- credentials.Credentials):
+class Credentials(credentials.Signing, credentials.Scoped, credentials.Credentials):
"""Service account credentials
Usually, you'll create these credentials with one of the helper
@@ -116,8 +114,16 @@
delegated_credentials = credentials.with_subject(subject)
"""
- def __init__(self, signer, service_account_email, token_uri, scopes=None,
- subject=None, project_id=None, additional_claims=None):
+ def __init__(
+ self,
+ signer,
+ service_account_email,
+ token_uri,
+ scopes=None,
+ subject=None,
+ project_id=None,
+ additional_claims=None,
+ ):
"""
Args:
signer (google.auth.crypt.Signer): The signer used to sign JWTs.
@@ -169,9 +175,11 @@
"""
return cls(
signer,
- service_account_email=info['client_email'],
- token_uri=info['token_uri'],
- project_id=info.get('project_id'), **kwargs)
+ service_account_email=info["client_email"],
+ token_uri=info["token_uri"],
+ project_id=info.get("project_id"),
+ **kwargs
+ )
@classmethod
def from_service_account_info(cls, info, **kwargs):
@@ -190,7 +198,8 @@
ValueError: If the info is not in the expected format.
"""
signer = _service_account_info.from_dict(
- info, require=['client_email', 'token_uri'])
+ info, require=["client_email", "token_uri"]
+ )
return cls._from_signer_and_info(signer, info, **kwargs)
@classmethod
@@ -206,7 +215,8 @@
credentials.
"""
info, signer = _service_account_info.from_filename(
- filename, require=['client_email', 'token_uri'])
+ filename, require=["client_email", "token_uri"]
+ )
return cls._from_signer_and_info(signer, info, **kwargs)
@property
@@ -237,7 +247,8 @@
token_uri=self._token_uri,
subject=self._subject,
project_id=self._project_id,
- additional_claims=self._additional_claims.copy())
+ additional_claims=self._additional_claims.copy(),
+ )
def with_subject(self, subject):
"""Create a copy of these credentials with the specified subject.
@@ -256,7 +267,8 @@
token_uri=self._token_uri,
subject=subject,
project_id=self._project_id,
- additional_claims=self._additional_claims.copy())
+ additional_claims=self._additional_claims.copy(),
+ )
def with_claims(self, additional_claims):
"""Returns a copy of these credentials with modified claims.
@@ -280,7 +292,8 @@
token_uri=self._token_uri,
subject=self._subject,
project_id=self._project_id,
- additional_claims=new_additional_claims)
+ additional_claims=new_additional_claims,
+ )
def _make_authorization_grant_assertion(self):
"""Create the OAuth 2.0 assertion.
@@ -296,20 +309,20 @@
expiry = now + lifetime
payload = {
- 'iat': _helpers.datetime_to_secs(now),
- 'exp': _helpers.datetime_to_secs(expiry),
+ "iat": _helpers.datetime_to_secs(now),
+ "exp": _helpers.datetime_to_secs(expiry),
# The issuer must be the service account email.
- 'iss': self._service_account_email,
+ "iss": self._service_account_email,
# The audience must be the auth token endpoint's URI
- 'aud': self._token_uri,
- 'scope': _helpers.scopes_to_string(self._scopes or ())
+ "aud": self._token_uri,
+ "scope": _helpers.scopes_to_string(self._scopes or ()),
}
payload.update(self._additional_claims)
# The subject can be a user email for domain-wide delegation.
if self._subject:
- payload.setdefault('sub', self._subject)
+ payload.setdefault("sub", self._subject)
token = jwt.encode(self._signer, payload)
@@ -318,8 +331,7 @@
@_helpers.copy_docstring(credentials.Credentials)
def refresh(self, request):
assertion = self._make_authorization_grant_assertion()
- access_token, expiry, _ = _client.jwt_grant(
- request, self._token_uri, assertion)
+ access_token, expiry, _ = _client.jwt_grant(request, self._token_uri, assertion)
self.token = access_token
self.expiry = expiry
@@ -379,8 +391,15 @@
delegated_credentials = credentials.with_subject(subject)
"""
- def __init__(self, signer, service_account_email, token_uri,
- target_audience, additional_claims=None):
+
+ def __init__(
+ self,
+ signer,
+ service_account_email,
+ token_uri,
+ target_audience,
+ additional_claims=None,
+ ):
"""
Args:
signer (google.auth.crypt.Signer): The signer used to sign JWTs.
@@ -424,8 +443,8 @@
Raises:
ValueError: If the info is not in the expected format.
"""
- kwargs.setdefault('service_account_email', info['client_email'])
- kwargs.setdefault('token_uri', info['token_uri'])
+ kwargs.setdefault("service_account_email", info["client_email"])
+ kwargs.setdefault("token_uri", info["token_uri"])
return cls(signer, **kwargs)
@classmethod
@@ -445,7 +464,8 @@
ValueError: If the info is not in the expected format.
"""
signer = _service_account_info.from_dict(
- info, require=['client_email', 'token_uri'])
+ info, require=["client_email", "token_uri"]
+ )
return cls._from_signer_and_info(signer, info, **kwargs)
@classmethod
@@ -461,7 +481,8 @@
credentials.
"""
info, signer = _service_account_info.from_filename(
- filename, require=['client_email', 'token_uri'])
+ filename, require=["client_email", "token_uri"]
+ )
return cls._from_signer_and_info(signer, info, **kwargs)
def with_target_audience(self, target_audience):
@@ -481,7 +502,8 @@
service_account_email=self._service_account_email,
token_uri=self._token_uri,
target_audience=target_audience,
- additional_claims=self._additional_claims.copy())
+ additional_claims=self._additional_claims.copy(),
+ )
def _make_authorization_grant_assertion(self):
"""Create the OAuth 2.0 assertion.
@@ -497,15 +519,15 @@
expiry = now + lifetime
payload = {
- 'iat': _helpers.datetime_to_secs(now),
- 'exp': _helpers.datetime_to_secs(expiry),
+ "iat": _helpers.datetime_to_secs(now),
+ "exp": _helpers.datetime_to_secs(expiry),
# The issuer must be the service account email.
- 'iss': self.service_account_email,
+ "iss": self.service_account_email,
# The audience must be the auth token endpoint's URI
- 'aud': self._token_uri,
+ "aud": self._token_uri,
# The target audience specifies which service the ID token is
# intended for.
- 'target_audience': self._target_audience
+ "target_audience": self._target_audience,
}
payload.update(self._additional_claims)
@@ -518,7 +540,8 @@
def refresh(self, request):
assertion = self._make_authorization_grant_assertion()
access_token, expiry, _ = _client.id_token_jwt_grant(
- request, self._token_uri, assertion)
+ request, self._token_uri, assertion
+ )
self.token = access_token
self.expiry = expiry
diff --git a/setup.py b/setup.py
index 60c7df4..d303cb3 100644
--- a/setup.py
+++ b/setup.py
@@ -19,46 +19,46 @@
DEPENDENCIES = (
- 'cachetools>=2.0.0,<3.2',
- 'pyasn1-modules>=0.2.1',
- 'rsa>=3.1.4,<4.1',
- 'setuptools>=40.3.0',
- 'six>=1.9.0',
+ "cachetools>=2.0.0,<3.2",
+ "pyasn1-modules>=0.2.1",
+ "rsa>=3.1.4,<4.1",
+ "setuptools>=40.3.0",
+ "six>=1.9.0",
)
-with io.open('README.rst', 'r') as fh:
+with io.open("README.rst", "r") as fh:
long_description = fh.read()
setup(
- name='google-auth',
- version='1.6.3',
- author='Google Cloud Platform',
- author_email='jonwayne+google-auth@google.com',
- description='Google Authentication Library',
+ name="google-auth",
+ version="1.6.3",
+ author="Google Cloud Platform",
+ author_email="jonwayne+google-auth@google.com",
+ description="Google Authentication Library",
long_description=long_description,
- url='https://github.com/GoogleCloudPlatform/google-auth-library-python',
- packages=find_packages(exclude=('tests*', 'system_tests*')),
- namespace_packages=('google',),
+ url="https://github.com/GoogleCloudPlatform/google-auth-library-python",
+ packages=find_packages(exclude=("tests*", "system_tests*")),
+ namespace_packages=("google",),
install_requires=DEPENDENCIES,
- python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*',
- license='Apache 2.0',
- keywords='google auth oauth client',
+ python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*",
+ license="Apache 2.0",
+ keywords="google auth oauth client",
classifiers=[
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.4',
- 'Programming Language :: Python :: 3.5',
- 'Programming Language :: Python :: 3.6',
- 'Programming Language :: Python :: 3.7',
- 'Development Status :: 5 - Production/Stable',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: Apache Software License',
- 'Operating System :: POSIX',
- 'Operating System :: Microsoft :: Windows',
- 'Operating System :: MacOS :: MacOS X',
- 'Operating System :: OS Independent',
- 'Topic :: Internet :: WWW/HTTP',
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.4",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Development Status :: 5 - Production/Stable",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: Apache Software License",
+ "Operating System :: POSIX",
+ "Operating System :: Microsoft :: Windows",
+ "Operating System :: MacOS :: MacOS X",
+ "Operating System :: OS Independent",
+ "Topic :: Internet :: WWW/HTTP",
],
)
diff --git a/system_tests/app_engine_test_app/appengine_config.py b/system_tests/app_engine_test_app/appengine_config.py
index da02e10..6339909 100644
--- a/system_tests/app_engine_test_app/appengine_config.py
+++ b/system_tests/app_engine_test_app/appengine_config.py
@@ -15,7 +15,7 @@
from google.appengine.ext import vendor
# Add any libraries installed in the "lib" folder.
-vendor.add('lib')
+vendor.add("lib")
# Patch os.path.expanduser. This should be fixed in GAE
@@ -26,4 +26,5 @@
def patched_expanduser(path):
return path
+
os.path.expanduser = patched_expanduser
diff --git a/system_tests/app_engine_test_app/main.py b/system_tests/app_engine_test_app/main.py
index 122b505..a3354ac 100644
--- a/system_tests/app_engine_test_app/main.py
+++ b/system_tests/app_engine_test_app/main.py
@@ -42,8 +42,8 @@
Captured output:
{}
"""
-TOKEN_INFO_URL = 'https://www.googleapis.com/oauth2/v3/tokeninfo'
-EMAIL_SCOPE = 'https://www.googleapis.com/auth/userinfo.email'
+TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo"
+EMAIL_SCOPE = "https://www.googleapis.com/auth/userinfo.email"
HTTP = urllib3.contrib.appengine.AppEngineManager()
HTTP_REQUEST = google.auth.transport.urllib3.Request(HTTP)
@@ -58,13 +58,13 @@
assert scoped_credentials.token is not None
# Get token info and verify scope
- url = _helpers.update_query(TOKEN_INFO_URL, {
- 'access_token': scoped_credentials.token,
- })
- response = HTTP_REQUEST(url=url, method='GET')
- token_info = json.loads(response.data.decode('utf-8'))
+ url = _helpers.update_query(
+ TOKEN_INFO_URL, {"access_token": scoped_credentials.token}
+ )
+ response = HTTP_REQUEST(url=url, method="GET")
+ token_info = json.loads(response.data.decode("utf-8"))
- assert token_info['scope'] == EMAIL_SCOPE
+ assert token_info["scope"] == EMAIL_SCOPE
def test_default():
@@ -90,11 +90,11 @@
with capture() as capsys:
try:
func()
- return True, ''
+ return True, ""
except Exception as exc:
output = FAILED_TEST_TMPL.format(
- func.func_name, exc, traceback.format_exc(),
- capsys.getvalue())
+ func.func_name, exc, traceback.format_exc(), capsys.getvalue()
+ )
return False, output
@@ -106,7 +106,7 @@
otherwise, and any captured output from the tests.
"""
status = True
- output = ''
+ output = ""
tests = (test_credentials, test_default)
@@ -120,7 +120,7 @@
class MainHandler(webapp2.RequestHandler):
def get(self):
- self.response.headers['content-type'] = 'text/plain'
+ self.response.headers["content-type"] = "text/plain"
status, output = run_tests()
@@ -130,6 +130,4 @@
self.response.write(output)
-app = webapp2.WSGIApplication([
- ('/', MainHandler),
-], debug=True)
+app = webapp2.WSGIApplication([("/", MainHandler)], debug=True)
diff --git a/system_tests/conftest.py b/system_tests/conftest.py
index d0f7cc0..3f089c4 100644
--- a/system_tests/conftest.py
+++ b/system_tests/conftest.py
@@ -24,13 +24,13 @@
HERE = os.path.dirname(__file__)
-DATA_DIR = os.path.join(HERE, 'data')
-SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, 'service_account.json')
-AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, 'authorized_user.json')
+DATA_DIR = os.path.join(HERE, "data")
+SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, "service_account.json")
+AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json")
URLLIB3_HTTP = urllib3.PoolManager(retries=False)
REQUESTS_SESSION = requests.Session()
REQUESTS_SESSION.verify = False
-TOKEN_INFO_URL = 'https://www.googleapis.com/oauth2/v3/tokeninfo'
+TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo"
@pytest.fixture
@@ -45,33 +45,34 @@
yield AUTHORIZED_USER_FILE
-@pytest.fixture(params=['urllib3', 'requests'])
+@pytest.fixture(params=["urllib3", "requests"])
def http_request(request):
"""A transport.request object."""
- if request.param == 'urllib3':
+ if request.param == "urllib3":
yield google.auth.transport.urllib3.Request(URLLIB3_HTTP)
- elif request.param == 'requests':
+ elif request.param == "requests":
yield google.auth.transport.requests.Request(REQUESTS_SESSION)
@pytest.fixture
def token_info(http_request):
"""Returns a function that obtains OAuth2 token info."""
+
def _token_info(access_token=None, id_token=None):
query_params = {}
if access_token is not None:
- query_params['access_token'] = access_token
+ query_params["access_token"] = access_token
elif id_token is not None:
- query_params['id_token'] = id_token
+ query_params["id_token"] = id_token
else:
- raise ValueError('No token specified.')
+ raise ValueError("No token specified.")
url = _helpers.update_query(TOKEN_INFO_URL, query_params)
- response = http_request(url=url, method='GET')
+ response = http_request(url=url, method="GET")
- return json.loads(response.data.decode('utf-8'))
+ return json.loads(response.data.decode("utf-8"))
yield _token_info
@@ -79,9 +80,10 @@
@pytest.fixture
def verify_refresh(http_request):
"""Returns a function that verifies that credentials can be refreshed."""
+
def _verify_refresh(credentials):
if credentials.requires_scopes:
- credentials = credentials.with_scopes(['email', 'profile'])
+ credentials = credentials.with_scopes(["email", "profile"])
credentials.refresh(http_request)
@@ -95,8 +97,9 @@
"""Checks to make sure that requisite data files are available."""
if not os.path.isdir(DATA_DIR):
raise EnvironmentError(
- 'In order to run system tests, test data must exist in '
- 'system_tests/data. See CONTRIBUTING.rst for details.')
+ "In order to run system tests, test data must exist in "
+ "system_tests/data. See CONTRIBUTING.rst for details."
+ )
def pytest_configure(config):
diff --git a/system_tests/noxfile.py b/system_tests/noxfile.py
index fa0422a..5f9291a 100644
--- a/system_tests/noxfile.py
+++ b/system_tests/noxfile.py
@@ -30,31 +30,31 @@
HERE = os.path.abspath(os.path.dirname(__file__))
-DATA_DIR = os.path.join(HERE, 'data')
-SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, 'service_account.json')
-AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, 'authorized_user.json')
-EXPLICIT_CREDENTIALS_ENV = 'GOOGLE_APPLICATION_CREDENTIALS'
-EXPLICIT_PROJECT_ENV = 'GOOGLE_CLOUD_PROJECT'
-EXPECT_PROJECT_ENV = 'EXPECT_PROJECT_ID'
+DATA_DIR = os.path.join(HERE, "data")
+SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, "service_account.json")
+AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json")
+EXPLICIT_CREDENTIALS_ENV = "GOOGLE_APPLICATION_CREDENTIALS"
+EXPLICIT_PROJECT_ENV = "GOOGLE_CLOUD_PROJECT"
+EXPECT_PROJECT_ENV = "EXPECT_PROJECT_ID"
-SKIP_GAE_TEST_ENV = 'SKIP_APP_ENGINE_SYSTEM_TEST'
-GAE_APP_URL_TMPL = 'https://{}-dot-{}.appspot.com'
-GAE_TEST_APP_SERVICE = 'google-auth-system-tests'
+SKIP_GAE_TEST_ENV = "SKIP_APP_ENGINE_SYSTEM_TEST"
+GAE_APP_URL_TMPL = "https://{}-dot-{}.appspot.com"
+GAE_TEST_APP_SERVICE = "google-auth-system-tests"
# The download location for the Cloud SDK
-CLOUD_SDK_DIST_FILENAME = 'google-cloud-sdk.tar.gz'
-CLOUD_SDK_DOWNLOAD_URL = (
- 'https://dl.google.com/dl/cloudsdk/release/{}'.format(
- CLOUD_SDK_DIST_FILENAME))
+CLOUD_SDK_DIST_FILENAME = "google-cloud-sdk.tar.gz"
+CLOUD_SDK_DOWNLOAD_URL = "https://dl.google.com/dl/cloudsdk/release/{}".format(
+ CLOUD_SDK_DIST_FILENAME
+)
# This environment variable is recognized by the Cloud SDK and overrides
# the location of the SDK's configuration files (which is usually at
# ${HOME}/.config).
-CLOUD_SDK_CONFIG_ENV = 'CLOUDSDK_CONFIG'
+CLOUD_SDK_CONFIG_ENV = "CLOUDSDK_CONFIG"
# If set, this is where the environment setup will install the Cloud SDK.
# If unset, it will download the SDK to a temporary directory.
-CLOUD_SDK_ROOT = os.environ.get('CLOUD_SDK_ROOT')
+CLOUD_SDK_ROOT = os.environ.get("CLOUD_SDK_ROOT")
if CLOUD_SDK_ROOT is not None:
CLOUD_SDK_ROOT = py.path.local(CLOUD_SDK_ROOT)
@@ -63,15 +63,15 @@
CLOUD_SDK_ROOT = py.path.local.mkdtemp()
# The full path the cloud sdk install directory
-CLOUD_SDK_INSTALL_DIR = CLOUD_SDK_ROOT.join('google-cloud-sdk')
+CLOUD_SDK_INSTALL_DIR = CLOUD_SDK_ROOT.join("google-cloud-sdk")
# The full path to the gcloud cli executable.
-GCLOUD = str(CLOUD_SDK_INSTALL_DIR.join('bin', 'gcloud'))
+GCLOUD = str(CLOUD_SDK_INSTALL_DIR.join("bin", "gcloud"))
# gcloud requires Python 2 and doesn't work on 3, so we need to tell it
# where to find 2 when we're running in a 3 environment.
-CLOUD_SDK_PYTHON_ENV = 'CLOUDSDK_PYTHON'
-CLOUD_SDK_PYTHON = which('python2', None)
+CLOUD_SDK_PYTHON_ENV = "CLOUDSDK_PYTHON"
+CLOUD_SDK_PYTHON = which("python2", None)
# Cloud SDK helpers
@@ -87,46 +87,47 @@
session.env[CLOUD_SDK_PYTHON_ENV] = CLOUD_SDK_PYTHON
# This set the $PATH for the subprocesses so they can find the gcloud
# executable.
- session.env['PATH'] = (
- str(CLOUD_SDK_INSTALL_DIR.join('bin')) + os.pathsep +
- os.environ['PATH'])
+ session.env["PATH"] = (
+ str(CLOUD_SDK_INSTALL_DIR.join("bin")) + os.pathsep + os.environ["PATH"]
+ )
# If gcloud cli executable already exists, just update it.
if py.path.local(GCLOUD).exists():
- session.run(GCLOUD, 'components', 'update', '-q')
+ session.run(GCLOUD, "components", "update", "-q")
return
tar_path = CLOUD_SDK_ROOT.join(CLOUD_SDK_DIST_FILENAME)
# Download the release.
- session.run(
- 'wget', CLOUD_SDK_DOWNLOAD_URL, '-O', str(tar_path), silent=True)
+ session.run("wget", CLOUD_SDK_DOWNLOAD_URL, "-O", str(tar_path), silent=True)
# Extract the release.
- session.run(
- 'tar', 'xzf', str(tar_path), '-C', str(CLOUD_SDK_ROOT))
+ session.run("tar", "xzf", str(tar_path), "-C", str(CLOUD_SDK_ROOT))
session.run(tar_path.remove)
# Run the install script.
session.run(
- str(CLOUD_SDK_INSTALL_DIR.join('install.sh')),
- '--usage-reporting', 'false',
- '--path-update', 'false',
- '--command-completion', 'false',
- silent=True)
+ str(CLOUD_SDK_INSTALL_DIR.join("install.sh")),
+ "--usage-reporting",
+ "false",
+ "--path-update",
+ "false",
+ "--command-completion",
+ "false",
+ silent=True,
+ )
def copy_credentials(credentials_path):
"""Copies credentials into the SDK root as the application default
credentials."""
- dest = CLOUD_SDK_ROOT.join('application_default_credentials.json')
+ dest = CLOUD_SDK_ROOT.join("application_default_credentials.json")
if dest.exists():
dest.remove()
py.path.local(credentials_path).copy(dest)
-def configure_cloud_sdk(
- session, application_default_credentials, project=False):
+def configure_cloud_sdk(session, application_default_credentials, project=False):
"""Installs and configures the Cloud SDK with the given application default
credentials.
@@ -140,13 +141,13 @@
# change the application default credentials file, which is user
# credentials instead of service account credentials sometimes.
session.run(
- GCLOUD, 'auth', 'activate-service-account', '--key-file',
- SERVICE_ACCOUNT_FILE)
+ GCLOUD, "auth", "activate-service-account", "--key-file", SERVICE_ACCOUNT_FILE
+ )
if project:
- session.run(GCLOUD, 'config', 'set', 'project', 'example-project')
+ session.run(GCLOUD, "config", "set", "project", "example-project")
else:
- session.run(GCLOUD, 'config', 'unset', 'project')
+ session.run(GCLOUD, "config", "unset", "project")
# Copy the credentials file to the config root. This is needed because
# unfortunately gcloud doesn't provide a clean way to tell it to use
@@ -160,8 +161,8 @@
# that our credentials matches the format expected by gcloud.
# Silent is set to True to prevent leaking secrets in test logs.
session.run(
- GCLOUD, 'auth', 'application-default', 'print-access-token',
- silent=True)
+ GCLOUD, "auth", "application-default", "print-access-token", silent=True
+ )
# Test sesssions
@@ -169,99 +170,102 @@
def session_service_account(session):
session.virtualenv = False
- session.run('pytest', 'test_service_account.py')
+ session.run("pytest", "test_service_account.py")
def session_oauth2_credentials(session):
session.virtualenv = False
- session.run('pytest', 'test_oauth2_credentials.py')
+ session.run("pytest", "test_oauth2_credentials.py")
def session_default_explicit_service_account(session):
session.virtualenv = False
session.env[EXPLICIT_CREDENTIALS_ENV] = SERVICE_ACCOUNT_FILE
- session.env[EXPECT_PROJECT_ENV] = '1'
- session.run('pytest', 'test_default.py')
+ session.env[EXPECT_PROJECT_ENV] = "1"
+ session.run("pytest", "test_default.py")
def session_default_explicit_authorized_user(session):
session.virtualenv = False
session.env[EXPLICIT_CREDENTIALS_ENV] = AUTHORIZED_USER_FILE
- session.run('pytest', 'test_default.py')
+ session.run("pytest", "test_default.py")
def session_default_explicit_authorized_user_explicit_project(session):
session.virtualenv = False
session.env[EXPLICIT_CREDENTIALS_ENV] = AUTHORIZED_USER_FILE
- session.env[EXPLICIT_PROJECT_ENV] = 'example-project'
- session.env[EXPECT_PROJECT_ENV] = '1'
- session.run('pytest', 'test_default.py')
+ session.env[EXPLICIT_PROJECT_ENV] = "example-project"
+ session.env[EXPECT_PROJECT_ENV] = "1"
+ session.run("pytest", "test_default.py")
def session_default_cloud_sdk_service_account(session):
session.virtualenv = False
configure_cloud_sdk(session, SERVICE_ACCOUNT_FILE)
- session.env[EXPECT_PROJECT_ENV] = '1'
- session.run('pytest', 'test_default.py')
+ session.env[EXPECT_PROJECT_ENV] = "1"
+ session.run("pytest", "test_default.py")
def session_default_cloud_sdk_authorized_user(session):
session.virtualenv = False
configure_cloud_sdk(session, AUTHORIZED_USER_FILE)
- session.run('pytest', 'test_default.py')
+ session.run("pytest", "test_default.py")
def session_default_cloud_sdk_authorized_user_configured_project(session):
session.virtualenv = False
configure_cloud_sdk(session, AUTHORIZED_USER_FILE, project=True)
- session.env[EXPECT_PROJECT_ENV] = '1'
- session.run('pytest', 'test_default.py')
+ session.env[EXPECT_PROJECT_ENV] = "1"
+ session.run("pytest", "test_default.py")
def session_compute_engine(session):
session.virtualenv = False
- session.run('pytest', 'test_compute_engine.py')
+ session.run("pytest", "test_compute_engine.py")
def session_app_engine(session):
session.virtualenv = False
if SKIP_GAE_TEST_ENV in os.environ:
- session.log('Skipping App Engine tests.')
+ session.log("Skipping App Engine tests.")
return
# Unlike the default tests above, the App Engine system test require a
# 'real' gcloud sdk installation that is configured to deploy to an
# app engine project.
# Grab the project ID from the cloud sdk.
- project_id = subprocess.check_output([
- 'gcloud', 'config', 'list', 'project', '--format',
- 'value(core.project)']).decode('utf-8').strip()
+ project_id = (
+ subprocess.check_output(
+ ["gcloud", "config", "list", "project", "--format", "value(core.project)"]
+ )
+ .decode("utf-8")
+ .strip()
+ )
if not project_id:
session.error(
- 'The Cloud SDK must be installed and configured to deploy to App '
- 'Engine.')
+ "The Cloud SDK must be installed and configured to deploy to App " "Engine."
+ )
- application_url = GAE_APP_URL_TMPL.format(
- GAE_TEST_APP_SERVICE, project_id)
+ application_url = GAE_APP_URL_TMPL.format(GAE_TEST_APP_SERVICE, project_id)
# Vendor in the test application's dependencies
- session.chdir(os.path.join(HERE, 'app_engine_test_app'))
+ session.chdir(os.path.join(HERE, "app_engine_test_app"))
session.run(
- 'pip', 'install', '--target', 'lib', '-r', 'requirements.txt',
- silent=True)
+ "pip", "install", "--target", "lib", "-r", "requirements.txt", silent=True
+ )
# Deploy the application.
- session.run('gcloud', 'app', 'deploy', '-q', 'app.yaml')
+ session.run("gcloud", "app", "deploy", "-q", "app.yaml")
# Run the tests
- session.env['TEST_APP_URL'] = application_url
+ session.env["TEST_APP_URL"] = application_url
session.chdir(HERE)
- session.run('pytest', 'test_app_engine.py')
+ session.run("pytest", "test_app_engine.py")
def session_grpc(session):
session.virtualenv = False
session.env[EXPLICIT_CREDENTIALS_ENV] = SERVICE_ACCOUNT_FILE
- session.run('pytest', 'test_grpc.py')
+ session.run("pytest", "test_grpc.py")
diff --git a/system_tests/test_app_engine.py b/system_tests/test_app_engine.py
index 834f9c8..cdf2be4 100644
--- a/system_tests/test_app_engine.py
+++ b/system_tests/test_app_engine.py
@@ -14,9 +14,9 @@
import os
-TEST_APP_URL = os.environ['TEST_APP_URL']
+TEST_APP_URL = os.environ["TEST_APP_URL"]
def test_live_application(http_request):
- response = http_request(method='GET', url=TEST_APP_URL)
- assert response.status == 200, response.data.decode('utf-8')
+ response = http_request(method="GET", url=TEST_APP_URL)
+ assert response.status == 200, response.data.decode("utf-8")
diff --git a/system_tests/test_compute_engine.py b/system_tests/test_compute_engine.py
index 3873327..3fd420c 100644
--- a/system_tests/test_compute_engine.py
+++ b/system_tests/test_compute_engine.py
@@ -26,7 +26,7 @@
try:
_metadata.get_service_account_info(http_request)
except exceptions.TransportError:
- pytest.skip('Compute Engine metadata service is not available.')
+ pytest.skip("Compute Engine metadata service is not available.")
def test_refresh(http_request, token_info):
@@ -38,7 +38,7 @@
assert credentials.service_account_email is not None
info = token_info(credentials.token)
- info_scopes = _helpers.string_to_scopes(info['scope'])
+ info_scopes = _helpers.string_to_scopes(info["scope"])
assert set(info_scopes) == set(credentials.scopes)
diff --git a/system_tests/test_default.py b/system_tests/test_default.py
index 23f6543..22213e6 100644
--- a/system_tests/test_default.py
+++ b/system_tests/test_default.py
@@ -16,7 +16,7 @@
import google.auth
-EXPECT_PROJECT_ID = os.environ.get('EXPECT_PROJECT_ID')
+EXPECT_PROJECT_ID = os.environ.get("EXPECT_PROJECT_ID")
def test_application_default_credentials(verify_refresh):
diff --git a/system_tests/test_grpc.py b/system_tests/test_grpc.py
index 365bc91..ea52830 100644
--- a/system_tests/test_grpc.py
+++ b/system_tests/test_grpc.py
@@ -22,61 +22,58 @@
def test_grpc_request_with_regular_credentials(http_request):
credentials, project_id = google.auth.default()
credentials = google.auth.credentials.with_scopes_if_required(
- credentials, ['https://www.googleapis.com/auth/pubsub'])
+ credentials, ["https://www.googleapis.com/auth/pubsub"]
+ )
channel = google.auth.transport.grpc.secure_authorized_channel(
- credentials,
- http_request,
- publisher_client.PublisherClient.SERVICE_ADDRESS)
+ credentials, http_request, publisher_client.PublisherClient.SERVICE_ADDRESS
+ )
# Create a pub/sub client.
client = publisher_client.PublisherClient(channel=channel)
# list the topics and drain the iterator to test that an authorized API
# call works.
- list_topics_iter = client.list_topics(
- project='projects/{}'.format(project_id))
+ list_topics_iter = client.list_topics(project="projects/{}".format(project_id))
list(list_topics_iter)
def test_grpc_request_with_jwt_credentials():
credentials, project_id = google.auth.default()
- audience = 'https://{}/google.pubsub.v1.Publisher'.format(
- publisher_client.PublisherClient.SERVICE_ADDRESS)
+ audience = "https://{}/google.pubsub.v1.Publisher".format(
+ publisher_client.PublisherClient.SERVICE_ADDRESS
+ )
credentials = google.auth.jwt.Credentials.from_signing_credentials(
- credentials,
- audience=audience)
+ credentials, audience=audience
+ )
channel = google.auth.transport.grpc.secure_authorized_channel(
- credentials,
- None,
- publisher_client.PublisherClient.SERVICE_ADDRESS)
+ credentials, None, publisher_client.PublisherClient.SERVICE_ADDRESS
+ )
# Create a pub/sub client.
client = publisher_client.PublisherClient(channel=channel)
# list the topics and drain the iterator to test that an authorized API
# call works.
- list_topics_iter = client.list_topics(
- project='projects/{}'.format(project_id))
+ list_topics_iter = client.list_topics(project="projects/{}".format(project_id))
list(list_topics_iter)
def test_grpc_request_with_on_demand_jwt_credentials():
credentials, project_id = google.auth.default()
credentials = google.auth.jwt.OnDemandCredentials.from_signing_credentials(
- credentials)
+ credentials
+ )
channel = google.auth.transport.grpc.secure_authorized_channel(
- credentials,
- None,
- publisher_client.PublisherClient.SERVICE_ADDRESS)
+ credentials, None, publisher_client.PublisherClient.SERVICE_ADDRESS
+ )
# Create a pub/sub client.
client = publisher_client.PublisherClient(channel=channel)
# list the topics and drain the iterator to test that an authorized API
# call works.
- list_topics_iter = client.list_topics(
- project='projects/{}'.format(project_id))
+ list_topics_iter = client.list_topics(project="projects/{}".format(project_id))
list(list_topics_iter)
diff --git a/system_tests/test_oauth2_credentials.py b/system_tests/test_oauth2_credentials.py
index ded0630..a33b89f 100644
--- a/system_tests/test_oauth2_credentials.py
+++ b/system_tests/test_oauth2_credentials.py
@@ -17,19 +17,20 @@
from google.auth import _helpers
import google.oauth2.credentials
-GOOGLE_OAUTH2_TOKEN_ENDPOINT = 'https://accounts.google.com/o/oauth2/token'
+GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://accounts.google.com/o/oauth2/token"
def test_refresh(authorized_user_file, http_request, token_info):
- with open(authorized_user_file, 'r') as fh:
+ with open(authorized_user_file, "r") as fh:
info = json.load(fh)
credentials = google.oauth2.credentials.Credentials(
None, # No access token, must be refreshed.
- refresh_token=info['refresh_token'],
+ refresh_token=info["refresh_token"],
token_uri=GOOGLE_OAUTH2_TOKEN_ENDPOINT,
- client_id=info['client_id'],
- client_secret=info['client_secret'])
+ client_id=info["client_id"],
+ client_secret=info["client_secret"],
+ )
credentials.refresh(http_request)
@@ -37,7 +38,10 @@
info = token_info(credentials.token)
- info_scopes = _helpers.string_to_scopes(info['scope'])
- assert set(info_scopes) == set([
- 'https://www.googleapis.com/auth/userinfo.email',
- 'https://www.googleapis.com/auth/userinfo.profile'])
+ info_scopes = _helpers.string_to_scopes(info["scope"])
+ assert set(info_scopes) == set(
+ [
+ "https://www.googleapis.com/auth/userinfo.email",
+ "https://www.googleapis.com/auth/userinfo.profile",
+ ]
+ )
diff --git a/system_tests/test_service_account.py b/system_tests/test_service_account.py
index aad1497..7937601 100644
--- a/system_tests/test_service_account.py
+++ b/system_tests/test_service_account.py
@@ -21,8 +21,7 @@
@pytest.fixture
def credentials(service_account_file):
- yield service_account.Credentials.from_service_account_file(
- service_account_file)
+ yield service_account.Credentials.from_service_account_file(service_account_file)
def test_refresh_no_scopes(http_request, credentials):
@@ -31,7 +30,7 @@
def test_refresh_success(http_request, credentials, token_info):
- credentials = credentials.with_scopes(['email', 'profile'])
+ credentials = credentials.with_scopes(["email", "profile"])
credentials.refresh(http_request)
@@ -39,8 +38,11 @@
info = token_info(credentials.token)
- assert info['email'] == credentials.service_account_email
- info_scopes = _helpers.string_to_scopes(info['scope'])
- assert set(info_scopes) == set([
- 'https://www.googleapis.com/auth/userinfo.email',
- 'https://www.googleapis.com/auth/userinfo.profile'])
+ assert info["email"] == credentials.service_account_email
+ info_scopes = _helpers.string_to_scopes(info["scope"])
+ assert set(info_scopes) == set(
+ [
+ "https://www.googleapis.com/auth/userinfo.email",
+ "https://www.googleapis.com/auth/userinfo.profile",
+ ]
+ )
diff --git a/tests/compute_engine/test__metadata.py b/tests/compute_engine/test__metadata.py
index bf48882..bd06b74 100644
--- a/tests/compute_engine/test__metadata.py
+++ b/tests/compute_engine/test__metadata.py
@@ -27,7 +27,7 @@
from google.auth import transport
from google.auth.compute_engine import _metadata
-PATH = 'instance/service-accounts/default'
+PATH = "instance/service-accounts/default"
def make_request(data, status=http_client.OK, headers=None):
@@ -43,35 +43,35 @@
def test_ping_success():
- request = make_request('', headers=_metadata._METADATA_HEADERS)
+ request = make_request("", headers=_metadata._METADATA_HEADERS)
assert _metadata.ping(request)
request.assert_called_once_with(
- method='GET',
+ method="GET",
url=_metadata._METADATA_IP_ROOT,
headers=_metadata._METADATA_HEADERS,
- timeout=_metadata._METADATA_DEFAULT_TIMEOUT)
+ timeout=_metadata._METADATA_DEFAULT_TIMEOUT,
+ )
def test_ping_failure_bad_flavor():
- request = make_request(
- '', headers={_metadata._METADATA_FLAVOR_HEADER: 'meep'})
+ request = make_request("", headers={_metadata._METADATA_FLAVOR_HEADER: "meep"})
assert not _metadata.ping(request)
def test_ping_failure_connection_failed():
- request = make_request('')
+ request = make_request("")
request.side_effect = exceptions.TransportError()
assert not _metadata.ping(request)
def test_ping_success_custom_root():
- request = make_request('', headers=_metadata._METADATA_HEADERS)
+ request = make_request("", headers=_metadata._METADATA_HEADERS)
- fake_ip = '1.2.3.4'
+ fake_ip = "1.2.3.4"
os.environ[environment_vars.GCE_METADATA_IP] = fake_ip
reload_module(_metadata)
@@ -82,46 +82,47 @@
reload_module(_metadata)
request.assert_called_once_with(
- method='GET',
- url='http://' + fake_ip,
+ method="GET",
+ url="http://" + fake_ip,
headers=_metadata._METADATA_HEADERS,
- timeout=_metadata._METADATA_DEFAULT_TIMEOUT)
+ timeout=_metadata._METADATA_DEFAULT_TIMEOUT,
+ )
def test_get_success_json():
- key, value = 'foo', 'bar'
+ key, value = "foo", "bar"
data = json.dumps({key: value})
- request = make_request(
- data, headers={'content-type': 'application/json'})
+ request = make_request(data, headers={"content-type": "application/json"})
result = _metadata.get(request, PATH)
request.assert_called_once_with(
- method='GET',
+ method="GET",
url=_metadata._METADATA_ROOT + PATH,
- headers=_metadata._METADATA_HEADERS)
+ headers=_metadata._METADATA_HEADERS,
+ )
assert result[key] == value
def test_get_success_text():
- data = 'foobar'
- request = make_request(data, headers={'content-type': 'text/plain'})
+ data = "foobar"
+ request = make_request(data, headers={"content-type": "text/plain"})
result = _metadata.get(request, PATH)
request.assert_called_once_with(
- method='GET',
+ method="GET",
url=_metadata._METADATA_ROOT + PATH,
- headers=_metadata._METADATA_HEADERS)
+ headers=_metadata._METADATA_HEADERS,
+ )
assert result == data
def test_get_success_custom_root():
- request = make_request(
- '{}', headers={'content-type': 'application/json'})
+ request = make_request("{}", headers={"content-type": "application/json"})
- fake_root = 'another.metadata.service'
+ fake_root = "another.metadata.service"
os.environ[environment_vars.GCE_METADATA_ROOT] = fake_root
reload_module(_metadata)
@@ -132,83 +133,87 @@
reload_module(_metadata)
request.assert_called_once_with(
- method='GET',
- url='http://{}/computeMetadata/v1/{}'.format(fake_root, PATH),
- headers=_metadata._METADATA_HEADERS)
+ method="GET",
+ url="http://{}/computeMetadata/v1/{}".format(fake_root, PATH),
+ headers=_metadata._METADATA_HEADERS,
+ )
def test_get_failure():
- request = make_request(
- 'Metadata error', status=http_client.NOT_FOUND)
+ request = make_request("Metadata error", status=http_client.NOT_FOUND)
with pytest.raises(exceptions.TransportError) as excinfo:
_metadata.get(request, PATH)
- assert excinfo.match(r'Metadata error')
+ assert excinfo.match(r"Metadata error")
request.assert_called_once_with(
- method='GET',
+ method="GET",
url=_metadata._METADATA_ROOT + PATH,
- headers=_metadata._METADATA_HEADERS)
+ headers=_metadata._METADATA_HEADERS,
+ )
def test_get_failure_bad_json():
- request = make_request(
- '{', headers={'content-type': 'application/json'})
+ request = make_request("{", headers={"content-type": "application/json"})
with pytest.raises(exceptions.TransportError) as excinfo:
_metadata.get(request, PATH)
- assert excinfo.match(r'invalid JSON')
+ assert excinfo.match(r"invalid JSON")
request.assert_called_once_with(
- method='GET',
+ method="GET",
url=_metadata._METADATA_ROOT + PATH,
- headers=_metadata._METADATA_HEADERS)
+ headers=_metadata._METADATA_HEADERS,
+ )
def test_get_project_id():
- project = 'example-project'
- request = make_request(
- project, headers={'content-type': 'text/plain'})
+ project = "example-project"
+ request = make_request(project, headers={"content-type": "text/plain"})
project_id = _metadata.get_project_id(request)
request.assert_called_once_with(
- method='GET',
- url=_metadata._METADATA_ROOT + 'project/project-id',
- headers=_metadata._METADATA_HEADERS)
+ method="GET",
+ url=_metadata._METADATA_ROOT + "project/project-id",
+ headers=_metadata._METADATA_HEADERS,
+ )
assert project_id == project
-@mock.patch('google.auth._helpers.utcnow', return_value=datetime.datetime.min)
+@mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
def test_get_service_account_token(utcnow):
ttl = 500
request = make_request(
- json.dumps({'access_token': 'token', 'expires_in': ttl}),
- headers={'content-type': 'application/json'})
+ json.dumps({"access_token": "token", "expires_in": ttl}),
+ headers={"content-type": "application/json"},
+ )
token, expiry = _metadata.get_service_account_token(request)
request.assert_called_once_with(
- method='GET',
- url=_metadata._METADATA_ROOT + PATH + '/token',
- headers=_metadata._METADATA_HEADERS)
- assert token == 'token'
+ method="GET",
+ url=_metadata._METADATA_ROOT + PATH + "/token",
+ headers=_metadata._METADATA_HEADERS,
+ )
+ assert token == "token"
assert expiry == utcnow() + datetime.timedelta(seconds=ttl)
def test_get_service_account_info():
- key, value = 'foo', 'bar'
+ key, value = "foo", "bar"
request = make_request(
- json.dumps({key: value}),
- headers={'content-type': 'application/json'})
+ json.dumps({key: value}), headers={"content-type": "application/json"}
+ )
info = _metadata.get_service_account_info(request)
request.assert_called_once_with(
- method='GET',
- url=_metadata._METADATA_ROOT + PATH + '/?recursive=true',
- headers=_metadata._METADATA_HEADERS)
+ method="GET",
+ url=_metadata._METADATA_ROOT + PATH + "/?recursive=true",
+ headers=_metadata._METADATA_HEADERS,
+ )
assert info[key] == value
diff --git a/tests/compute_engine/test_credentials.py b/tests/compute_engine/test_credentials.py
index ee415db..ec9d13b 100644
--- a/tests/compute_engine/test_credentials.py
+++ b/tests/compute_engine/test_credentials.py
@@ -38,68 +38,72 @@
# Scopes aren't needed
assert not self.credentials.requires_scopes
# Service account email hasn't been populated
- assert self.credentials.service_account_email == 'default'
+ assert self.credentials.service_account_email == "default"
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.min + _helpers.CLOCK_SKEW)
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.min + _helpers.CLOCK_SKEW,
+ )
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
def test_refresh_success(self, get, utcnow):
- get.side_effect = [{
- # First request is for sevice account info.
- 'email': 'service-account@example.com',
- 'scopes': ['one', 'two']
- }, {
- # Second request is for the token.
- 'access_token': 'token',
- 'expires_in': 500
- }]
+ get.side_effect = [
+ {
+ # First request is for sevice account info.
+ "email": "service-account@example.com",
+ "scopes": ["one", "two"],
+ },
+ {
+ # Second request is for the token.
+ "access_token": "token",
+ "expires_in": 500,
+ },
+ ]
# Refresh credentials
self.credentials.refresh(None)
# Check that the credentials have the token and proper expiration
- assert self.credentials.token == 'token'
- assert self.credentials.expiry == (
- utcnow() + datetime.timedelta(seconds=500))
+ assert self.credentials.token == "token"
+ assert self.credentials.expiry == (utcnow() + datetime.timedelta(seconds=500))
# Check the credential info
- assert (self.credentials.service_account_email ==
- 'service-account@example.com')
- assert self.credentials._scopes == ['one', 'two']
+ assert self.credentials.service_account_email == "service-account@example.com"
+ assert self.credentials._scopes == ["one", "two"]
# Check that the credentials are valid (have a token and are not
# expired)
assert self.credentials.valid
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
def test_refresh_error(self, get):
- get.side_effect = exceptions.TransportError('http error')
+ get.side_effect = exceptions.TransportError("http error")
with pytest.raises(exceptions.RefreshError) as excinfo:
self.credentials.refresh(None)
- assert excinfo.match(r'http error')
+ assert excinfo.match(r"http error")
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
def test_before_request_refreshes(self, get):
- get.side_effect = [{
- # First request is for sevice account info.
- 'email': 'service-account@example.com',
- 'scopes': 'one two'
- }, {
- # Second request is for the token.
- 'access_token': 'token',
- 'expires_in': 500
- }]
+ get.side_effect = [
+ {
+ # First request is for sevice account info.
+ "email": "service-account@example.com",
+ "scopes": "one two",
+ },
+ {
+ # Second request is for the token.
+ "access_token": "token",
+ "expires_in": 500,
+ },
+ ]
# Credentials should start as invalid
assert not self.credentials.valid
# before_request should cause a refresh
request = mock.create_autospec(transport.Request, instance=True)
- self.credentials.before_request(
- request, 'GET', 'http://example.com?a=1#3', {})
+ self.credentials.before_request(request, "GET", "http://example.com?a=1#3", {})
# The refresh endpoint should've been called.
assert get.called
@@ -111,201 +115,207 @@
class TestIDTokenCredentials(object):
credentials = None
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
def test_default_state(self, get):
- get.side_effect = [{
- 'email': 'service-account@example.com',
- 'scope': ['one', 'two'],
- }]
+ get.side_effect = [
+ {"email": "service-account@example.com", "scope": ["one", "two"]}
+ ]
request = mock.create_autospec(transport.Request, instance=True)
self.credentials = credentials.IDTokenCredentials(
- request=request, target_audience="https://example.com")
+ request=request, target_audience="https://example.com"
+ )
assert not self.credentials.valid
# Expiration hasn't been set yet
assert not self.credentials.expired
# Service account email hasn't been populated
- assert (self.credentials.service_account_email
- == 'service-account@example.com')
+ assert self.credentials.service_account_email == "service-account@example.com"
# Signer is initialized
assert self.credentials.signer
- assert self.credentials.signer_email == 'service-account@example.com'
+ assert self.credentials.signer_email == "service-account@example.com"
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.utcfromtimestamp(0))
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
- @mock.patch('google.auth.iam.Signer.sign', autospec=True)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.utcfromtimestamp(0),
+ )
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
+ @mock.patch("google.auth.iam.Signer.sign", autospec=True)
def test_make_authorization_grant_assertion(self, sign, get, utcnow):
- get.side_effect = [{
- 'email': 'service-account@example.com',
- 'scopes': ['one', 'two']
- }]
- sign.side_effect = [b'signature']
+ get.side_effect = [
+ {"email": "service-account@example.com", "scopes": ["one", "two"]}
+ ]
+ sign.side_effect = [b"signature"]
request = mock.create_autospec(transport.Request, instance=True)
self.credentials = credentials.IDTokenCredentials(
- request=request, target_audience="https://audience.com")
+ request=request, target_audience="https://audience.com"
+ )
# Generate authorization grant:
token = self.credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, verify=False)
# The JWT token signature is 'signature' encoded in base 64:
- assert token.endswith(b'.c2lnbmF0dXJl')
+ assert token.endswith(b".c2lnbmF0dXJl")
# Check that the credentials have the token and proper expiration
assert payload == {
- 'aud': 'https://www.googleapis.com/oauth2/v4/token',
- 'exp': 3600,
- 'iat': 0,
- 'iss': 'service-account@example.com',
- 'target_audience': 'https://audience.com'}
+ "aud": "https://www.googleapis.com/oauth2/v4/token",
+ "exp": 3600,
+ "iat": 0,
+ "iss": "service-account@example.com",
+ "target_audience": "https://audience.com",
+ }
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.utcfromtimestamp(0))
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
- @mock.patch('google.auth.iam.Signer.sign', autospec=True)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.utcfromtimestamp(0),
+ )
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
+ @mock.patch("google.auth.iam.Signer.sign", autospec=True)
def test_with_service_account(self, sign, get, utcnow):
- sign.side_effect = [b'signature']
+ sign.side_effect = [b"signature"]
request = mock.create_autospec(transport.Request, instance=True)
self.credentials = credentials.IDTokenCredentials(
- request=request, target_audience="https://audience.com",
- service_account_email="service-account@other.com")
+ request=request,
+ target_audience="https://audience.com",
+ service_account_email="service-account@other.com",
+ )
# Generate authorization grant:
token = self.credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, verify=False)
# The JWT token signature is 'signature' encoded in base 64:
- assert token.endswith(b'.c2lnbmF0dXJl')
+ assert token.endswith(b".c2lnbmF0dXJl")
# Check that the credentials have the token and proper expiration
assert payload == {
- 'aud': 'https://www.googleapis.com/oauth2/v4/token',
- 'exp': 3600,
- 'iat': 0,
- 'iss': 'service-account@other.com',
- 'target_audience': 'https://audience.com'}
+ "aud": "https://www.googleapis.com/oauth2/v4/token",
+ "exp": 3600,
+ "iat": 0,
+ "iss": "service-account@other.com",
+ "target_audience": "https://audience.com",
+ }
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.utcfromtimestamp(0))
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
- @mock.patch('google.auth.iam.Signer.sign', autospec=True)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.utcfromtimestamp(0),
+ )
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
+ @mock.patch("google.auth.iam.Signer.sign", autospec=True)
def test_additional_claims(self, sign, get, utcnow):
- get.side_effect = [{
- 'email': 'service-account@example.com',
- 'scopes': ['one', 'two']
- }]
- sign.side_effect = [b'signature']
+ get.side_effect = [
+ {"email": "service-account@example.com", "scopes": ["one", "two"]}
+ ]
+ sign.side_effect = [b"signature"]
request = mock.create_autospec(transport.Request, instance=True)
self.credentials = credentials.IDTokenCredentials(
- request=request, target_audience="https://audience.com",
- additional_claims={'foo': 'bar'})
+ request=request,
+ target_audience="https://audience.com",
+ additional_claims={"foo": "bar"},
+ )
# Generate authorization grant:
token = self.credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, verify=False)
# The JWT token signature is 'signature' encoded in base 64:
- assert token.endswith(b'.c2lnbmF0dXJl')
+ assert token.endswith(b".c2lnbmF0dXJl")
# Check that the credentials have the token and proper expiration
assert payload == {
- 'aud': 'https://www.googleapis.com/oauth2/v4/token',
- 'exp': 3600,
- 'iat': 0,
- 'iss': 'service-account@example.com',
- 'target_audience': 'https://audience.com',
- 'foo': 'bar'}
+ "aud": "https://www.googleapis.com/oauth2/v4/token",
+ "exp": 3600,
+ "iat": 0,
+ "iss": "service-account@example.com",
+ "target_audience": "https://audience.com",
+ "foo": "bar",
+ }
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.utcfromtimestamp(0))
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
- @mock.patch('google.auth.iam.Signer.sign', autospec=True)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.utcfromtimestamp(0),
+ )
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
+ @mock.patch("google.auth.iam.Signer.sign", autospec=True)
def test_with_target_audience(self, sign, get, utcnow):
- get.side_effect = [{
- 'email': 'service-account@example.com',
- 'scopes': ['one', 'two']
- }]
- sign.side_effect = [b'signature']
+ get.side_effect = [
+ {"email": "service-account@example.com", "scopes": ["one", "two"]}
+ ]
+ sign.side_effect = [b"signature"]
request = mock.create_autospec(transport.Request, instance=True)
self.credentials = credentials.IDTokenCredentials(
- request=request, target_audience="https://audience.com")
- self.credentials = (
- self.credentials.with_target_audience("https://actually.not"))
+ request=request, target_audience="https://audience.com"
+ )
+ self.credentials = self.credentials.with_target_audience("https://actually.not")
# Generate authorization grant:
token = self.credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, verify=False)
# The JWT token signature is 'signature' encoded in base 64:
- assert token.endswith(b'.c2lnbmF0dXJl')
+ assert token.endswith(b".c2lnbmF0dXJl")
# Check that the credentials have the token and proper expiration
assert payload == {
- 'aud': 'https://www.googleapis.com/oauth2/v4/token',
- 'exp': 3600,
- 'iat': 0,
- 'iss': 'service-account@example.com',
- 'target_audience': 'https://actually.not'}
+ "aud": "https://www.googleapis.com/oauth2/v4/token",
+ "exp": 3600,
+ "iat": 0,
+ "iss": "service-account@example.com",
+ "target_audience": "https://actually.not",
+ }
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.utcfromtimestamp(0))
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
- @mock.patch('google.auth.iam.Signer.sign', autospec=True)
- @mock.patch('google.oauth2._client.id_token_jwt_grant', autospec=True)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.utcfromtimestamp(0),
+ )
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
+ @mock.patch("google.auth.iam.Signer.sign", autospec=True)
+ @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True)
def test_refresh_success(self, id_token_jwt_grant, sign, get, utcnow):
- get.side_effect = [{
- 'email': 'service-account@example.com',
- 'scopes': ['one', 'two']
- }]
- sign.side_effect = [b'signature']
- id_token_jwt_grant.side_effect = [(
- 'idtoken',
- datetime.datetime.utcfromtimestamp(3600),
- {},
- )]
+ get.side_effect = [
+ {"email": "service-account@example.com", "scopes": ["one", "two"]}
+ ]
+ sign.side_effect = [b"signature"]
+ id_token_jwt_grant.side_effect = [
+ ("idtoken", datetime.datetime.utcfromtimestamp(3600), {})
+ ]
request = mock.create_autospec(transport.Request, instance=True)
self.credentials = credentials.IDTokenCredentials(
- request=request, target_audience="https://audience.com")
+ request=request, target_audience="https://audience.com"
+ )
# Refresh credentials
self.credentials.refresh(None)
# Check that the credentials have the token and proper expiration
- assert self.credentials.token == 'idtoken'
- assert self.credentials.expiry == (
- datetime.datetime.utcfromtimestamp(3600))
+ assert self.credentials.token == "idtoken"
+ assert self.credentials.expiry == (datetime.datetime.utcfromtimestamp(3600))
# Check the credential info
- assert (self.credentials.service_account_email ==
- 'service-account@example.com')
+ assert self.credentials.service_account_email == "service-account@example.com"
# Check that the credentials are valid (have a token and are not
# expired)
assert self.credentials.valid
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.utcfromtimestamp(0))
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
- @mock.patch('google.auth.iam.Signer.sign', autospec=True)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.utcfromtimestamp(0),
+ )
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
+ @mock.patch("google.auth.iam.Signer.sign", autospec=True)
def test_refresh_error(self, sign, get, utcnow):
- get.side_effect = [{
- 'email': 'service-account@example.com',
- 'scopes': ['one', 'two'],
- }]
- sign.side_effect = [b'signature']
+ get.side_effect = [
+ {"email": "service-account@example.com", "scopes": ["one", "two"]}
+ ]
+ sign.side_effect = [b"signature"]
request = mock.create_autospec(transport.Request, instance=True)
response = mock.Mock()
@@ -314,43 +324,41 @@
request.side_effect = [response]
self.credentials = credentials.IDTokenCredentials(
- request=request, target_audience="https://audience.com")
+ request=request, target_audience="https://audience.com"
+ )
with pytest.raises(exceptions.RefreshError) as excinfo:
self.credentials.refresh(request)
- assert excinfo.match(r'http error')
+ assert excinfo.match(r"http error")
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.utcfromtimestamp(0))
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
- @mock.patch('google.auth.iam.Signer.sign', autospec=True)
- @mock.patch('google.oauth2._client.id_token_jwt_grant', autospec=True)
- def test_before_request_refreshes(
- self, id_token_jwt_grant, sign, get, utcnow):
- get.side_effect = [{
- 'email': 'service-account@example.com',
- 'scopes': 'one two'
- }]
- sign.side_effect = [b'signature']
- id_token_jwt_grant.side_effect = [(
- 'idtoken',
- datetime.datetime.utcfromtimestamp(3600),
- {},
- )]
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.utcfromtimestamp(0),
+ )
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
+ @mock.patch("google.auth.iam.Signer.sign", autospec=True)
+ @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True)
+ def test_before_request_refreshes(self, id_token_jwt_grant, sign, get, utcnow):
+ get.side_effect = [
+ {"email": "service-account@example.com", "scopes": "one two"}
+ ]
+ sign.side_effect = [b"signature"]
+ id_token_jwt_grant.side_effect = [
+ ("idtoken", datetime.datetime.utcfromtimestamp(3600), {})
+ ]
request = mock.create_autospec(transport.Request, instance=True)
self.credentials = credentials.IDTokenCredentials(
- request=request, target_audience="https://audience.com")
+ request=request, target_audience="https://audience.com"
+ )
# Credentials should start as invalid
assert not self.credentials.valid
# before_request should cause a refresh
request = mock.create_autospec(transport.Request, instance=True)
- self.credentials.before_request(
- request, 'GET', 'http://example.com?a=1#3', {})
+ self.credentials.before_request(request, "GET", "http://example.com?a=1#3", {})
# The refresh endpoint should've been called.
assert get.called
@@ -358,14 +366,13 @@
# Credentials should now be valid.
assert self.credentials.valid
- @mock.patch('google.auth.compute_engine._metadata.get', autospec=True)
- @mock.patch('google.auth.iam.Signer.sign', autospec=True)
+ @mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
+ @mock.patch("google.auth.iam.Signer.sign", autospec=True)
def test_sign_bytes(self, sign, get):
- get.side_effect = [{
- 'email': 'service-account@example.com',
- 'scopes': ['one', 'two']
- }]
- sign.side_effect = [b'signature']
+ get.side_effect = [
+ {"email": "service-account@example.com", "scopes": ["one", "two"]}
+ ]
+ sign.side_effect = [b"signature"]
request = mock.create_autospec(transport.Request, instance=True)
response = mock.Mock()
@@ -374,10 +381,11 @@
request.side_effect = [response]
self.credentials = credentials.IDTokenCredentials(
- request=request, target_audience="https://audience.com")
+ request=request, target_audience="https://audience.com"
+ )
# Generate authorization grant:
signature = self.credentials.sign_bytes(b"some bytes")
# The JWT token signature is 'signature' encoded in base 64:
- assert signature == b'signature'
+ assert signature == b"signature"
diff --git a/tests/conftest.py b/tests/conftest.py
index c9e3f84..2ccc132 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -24,14 +24,14 @@
Additionally mocks any non-existing modules specified in the dotted path.
"""
+
def _mock_non_existent_module(path):
- parts = path.split('.')
+ parts = path.split(".")
partial = []
for part in parts:
partial.append(part)
- current_module = '.'.join(partial)
+ current_module = ".".join(partial)
if current_module not in sys.modules:
- monkeypatch.setitem(
- sys.modules, current_module, mock.MagicMock())
+ monkeypatch.setitem(sys.modules, current_module, mock.MagicMock())
return _mock_non_existent_module
diff --git a/tests/crypt/test__cryptography_rsa.py b/tests/crypt/test__cryptography_rsa.py
index a7ebb64..10f926b 100644
--- a/tests/crypt/test__cryptography_rsa.py
+++ b/tests/crypt/test__cryptography_rsa.py
@@ -23,21 +23,21 @@
from google.auth.crypt import base
-DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "data")
# To generate privatekey.pem, privatekey.pub, and public_cert.pem:
# $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \
# > -keyout privatekey.pem
# $ openssl rsa -in privatekey.pem -pubout -out privatekey.pub
-with open(os.path.join(DATA_DIR, 'privatekey.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
PKCS1_KEY_BYTES = PRIVATE_KEY_BYTES
-with open(os.path.join(DATA_DIR, 'privatekey.pub'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.pub"), "rb") as fh:
PUBLIC_KEY_BYTES = fh.read()
-with open(os.path.join(DATA_DIR, 'public_cert.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "public_cert.pem"), "rb") as fh:
PUBLIC_CERT_BYTES = fh.read()
# To generate pem_from_pkcs12.pem and privatekey.p12:
@@ -46,22 +46,22 @@
# $ openssl pkcs12 -in privatekey.p12 -nocerts -nodes \
# > -out pem_from_pkcs12.pem
-with open(os.path.join(DATA_DIR, 'pem_from_pkcs12.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "pem_from_pkcs12.pem"), "rb") as fh:
PKCS8_KEY_BYTES = fh.read()
-with open(os.path.join(DATA_DIR, 'privatekey.p12'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.p12"), "rb") as fh:
PKCS12_KEY_BYTES = fh.read()
# The service account JSON file can be generated from the Google Cloud Console.
-SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, 'service_account.json')
+SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
-with open(SERVICE_ACCOUNT_JSON_FILE, 'r') as fh:
+with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
SERVICE_ACCOUNT_INFO = json.load(fh)
class TestRSAVerifier(object):
def test_verify_success(self):
- to_sign = b'foo'
+ to_sign = b"foo"
signer = _cryptography_rsa.RSASigner.from_string(PRIVATE_KEY_BYTES)
actual_signature = signer.sign(to_sign)
@@ -69,7 +69,7 @@
assert verifier.verify(to_sign, actual_signature)
def test_verify_unicode_success(self):
- to_sign = u'foo'
+ to_sign = u"foo"
signer = _cryptography_rsa.RSASigner.from_string(PRIVATE_KEY_BYTES)
actual_signature = signer.sign(to_sign)
@@ -78,10 +78,10 @@
def test_verify_failure(self):
verifier = _cryptography_rsa.RSAVerifier.from_string(PUBLIC_KEY_BYTES)
- bad_signature1 = b''
- assert not verifier.verify(b'foo', bad_signature1)
- bad_signature2 = b'a'
- assert not verifier.verify(b'foo', bad_signature2)
+ bad_signature1 = b""
+ assert not verifier.verify(b"foo", bad_signature1)
+ bad_signature2 = b"a"
+ assert not verifier.verify(b"foo", bad_signature2)
def test_from_string_pub_key(self):
verifier = _cryptography_rsa.RSAVerifier.from_string(PUBLIC_KEY_BYTES)
@@ -134,16 +134,16 @@
_cryptography_rsa.RSASigner.from_string(PKCS12_KEY_BYTES)
def test_from_string_bogus_key(self):
- key_bytes = 'bogus-key'
+ key_bytes = "bogus-key"
with pytest.raises(ValueError):
_cryptography_rsa.RSASigner.from_string(key_bytes)
def test_from_service_account_info(self):
signer = _cryptography_rsa.RSASigner.from_service_account_info(
- SERVICE_ACCOUNT_INFO)
+ SERVICE_ACCOUNT_INFO
+ )
- assert signer.key_id == SERVICE_ACCOUNT_INFO[
- base._JSON_FILE_PRIVATE_KEY_ID]
+ assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
assert isinstance(signer._key, rsa.RSAPrivateKey)
def test_from_service_account_info_missing_key(self):
@@ -154,8 +154,8 @@
def test_from_service_account_file(self):
signer = _cryptography_rsa.RSASigner.from_service_account_file(
- SERVICE_ACCOUNT_JSON_FILE)
+ SERVICE_ACCOUNT_JSON_FILE
+ )
- assert signer.key_id == SERVICE_ACCOUNT_INFO[
- base._JSON_FILE_PRIVATE_KEY_ID]
+ assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
assert isinstance(signer._key, rsa.RSAPrivateKey)
diff --git a/tests/crypt/test__python_rsa.py b/tests/crypt/test__python_rsa.py
index d13105f..08b9503 100644
--- a/tests/crypt/test__python_rsa.py
+++ b/tests/crypt/test__python_rsa.py
@@ -26,21 +26,21 @@
from google.auth.crypt import base
-DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "data")
# To generate privatekey.pem, privatekey.pub, and public_cert.pem:
# $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \
# > -keyout privatekey.pem
# $ openssl rsa -in privatekey.pem -pubout -out privatekey.pub
-with open(os.path.join(DATA_DIR, 'privatekey.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
PKCS1_KEY_BYTES = PRIVATE_KEY_BYTES
-with open(os.path.join(DATA_DIR, 'privatekey.pub'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.pub"), "rb") as fh:
PUBLIC_KEY_BYTES = fh.read()
-with open(os.path.join(DATA_DIR, 'public_cert.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "public_cert.pem"), "rb") as fh:
PUBLIC_CERT_BYTES = fh.read()
# To generate pem_from_pkcs12.pem and privatekey.p12:
@@ -49,22 +49,22 @@
# $ openssl pkcs12 -in privatekey.p12 -nocerts -nodes \
# > -out pem_from_pkcs12.pem
-with open(os.path.join(DATA_DIR, 'pem_from_pkcs12.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "pem_from_pkcs12.pem"), "rb") as fh:
PKCS8_KEY_BYTES = fh.read()
-with open(os.path.join(DATA_DIR, 'privatekey.p12'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.p12"), "rb") as fh:
PKCS12_KEY_BYTES = fh.read()
# The service account JSON file can be generated from the Google Cloud Console.
-SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, 'service_account.json')
+SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
-with open(SERVICE_ACCOUNT_JSON_FILE, 'r') as fh:
+with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
SERVICE_ACCOUNT_INFO = json.load(fh)
class TestRSAVerifier(object):
def test_verify_success(self):
- to_sign = b'foo'
+ to_sign = b"foo"
signer = _python_rsa.RSASigner.from_string(PRIVATE_KEY_BYTES)
actual_signature = signer.sign(to_sign)
@@ -72,7 +72,7 @@
assert verifier.verify(to_sign, actual_signature)
def test_verify_unicode_success(self):
- to_sign = u'foo'
+ to_sign = u"foo"
signer = _python_rsa.RSASigner.from_string(PRIVATE_KEY_BYTES)
actual_signature = signer.sign(to_sign)
@@ -81,10 +81,10 @@
def test_verify_failure(self):
verifier = _python_rsa.RSAVerifier.from_string(PUBLIC_KEY_BYTES)
- bad_signature1 = b''
- assert not verifier.verify(b'foo', bad_signature1)
- bad_signature2 = b'a'
- assert not verifier.verify(b'foo', bad_signature2)
+ bad_signature1 = b""
+ assert not verifier.verify(b"foo", bad_signature1)
+ bad_signature2 = b"a"
+ assert not verifier.verify(b"foo", bad_signature2)
def test_from_string_pub_key(self):
verifier = _python_rsa.RSAVerifier.from_string(PUBLIC_KEY_BYTES)
@@ -110,15 +110,15 @@
def test_from_string_pub_cert_failure(self):
cert_bytes = PUBLIC_CERT_BYTES
- true_der = rsa.pem.load_pem(cert_bytes, 'CERTIFICATE')
+ true_der = rsa.pem.load_pem(cert_bytes, "CERTIFICATE")
load_pem_patch = mock.patch(
- 'rsa.pem.load_pem', return_value=true_der + b'extra',
- autospec=True)
+ "rsa.pem.load_pem", return_value=true_der + b"extra", autospec=True
+ )
with load_pem_patch as load_pem:
with pytest.raises(ValueError):
_python_rsa.RSAVerifier.from_string(cert_bytes)
- load_pem.assert_called_once_with(cert_bytes, 'CERTIFICATE')
+ load_pem.assert_called_once_with(cert_bytes, "CERTIFICATE")
class TestRSASigner(object):
@@ -141,21 +141,21 @@
def test_from_string_pkcs8_extra_bytes(self):
key_bytes = PKCS8_KEY_BYTES
_, pem_bytes = pem.readPemBlocksFromFile(
- six.StringIO(_helpers.from_bytes(key_bytes)),
- _python_rsa._PKCS8_MARKER)
+ six.StringIO(_helpers.from_bytes(key_bytes)), _python_rsa._PKCS8_MARKER
+ )
- key_info, remaining = None, 'extra'
+ key_info, remaining = None, "extra"
decode_patch = mock.patch(
- 'pyasn1.codec.der.decoder.decode',
+ "pyasn1.codec.der.decoder.decode",
return_value=(key_info, remaining),
- autospec=True)
+ autospec=True,
+ )
with decode_patch as decode:
with pytest.raises(ValueError):
_python_rsa.RSASigner.from_string(key_bytes)
# Verify mock was called.
- decode.assert_called_once_with(
- pem_bytes, asn1Spec=_python_rsa._PKCS8_SPEC)
+ decode.assert_called_once_with(pem_bytes, asn1Spec=_python_rsa._PKCS8_SPEC)
def test_from_string_pkcs8_unicode(self):
key_bytes = _helpers.from_bytes(PKCS8_KEY_BYTES)
@@ -168,16 +168,14 @@
_python_rsa.RSASigner.from_string(PKCS12_KEY_BYTES)
def test_from_string_bogus_key(self):
- key_bytes = 'bogus-key'
+ key_bytes = "bogus-key"
with pytest.raises(ValueError):
_python_rsa.RSASigner.from_string(key_bytes)
def test_from_service_account_info(self):
- signer = _python_rsa.RSASigner.from_service_account_info(
- SERVICE_ACCOUNT_INFO)
+ signer = _python_rsa.RSASigner.from_service_account_info(SERVICE_ACCOUNT_INFO)
- assert signer.key_id == SERVICE_ACCOUNT_INFO[
- base._JSON_FILE_PRIVATE_KEY_ID]
+ assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
assert isinstance(signer._key, rsa.key.PrivateKey)
def test_from_service_account_info_missing_key(self):
@@ -188,8 +186,8 @@
def test_from_service_account_file(self):
signer = _python_rsa.RSASigner.from_service_account_file(
- SERVICE_ACCOUNT_JSON_FILE)
+ SERVICE_ACCOUNT_JSON_FILE
+ )
- assert signer.key_id == SERVICE_ACCOUNT_INFO[
- base._JSON_FILE_PRIVATE_KEY_ID]
+ assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
assert isinstance(signer._key, rsa.key.PrivateKey)
diff --git a/tests/crypt/test_crypt.py b/tests/crypt/test_crypt.py
index d8b1d00..16ff2e0 100644
--- a/tests/crypt/test_crypt.py
+++ b/tests/crypt/test_crypt.py
@@ -17,43 +17,42 @@
from google.auth import crypt
-DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "data")
# To generate privatekey.pem, privatekey.pub, and public_cert.pem:
# $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \
# > -keyout privatekey.pem
# $ openssl rsa -in privatekey.pem -pubout -out privatekey.pub
-with open(os.path.join(DATA_DIR, 'privatekey.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
-with open(os.path.join(DATA_DIR, 'public_cert.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "public_cert.pem"), "rb") as fh:
PUBLIC_CERT_BYTES = fh.read()
# To generate other_cert.pem:
# $ openssl req -new -newkey rsa:1024 -x509 -nodes -out other_cert.pem
-with open(os.path.join(DATA_DIR, 'other_cert.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "other_cert.pem"), "rb") as fh:
OTHER_CERT_BYTES = fh.read()
def test_verify_signature():
- to_sign = b'foo'
+ to_sign = b"foo"
signer = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES)
signature = signer.sign(to_sign)
- assert crypt.verify_signature(
- to_sign, signature, PUBLIC_CERT_BYTES)
+ assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)
# List of certs
assert crypt.verify_signature(
- to_sign, signature, [OTHER_CERT_BYTES, PUBLIC_CERT_BYTES])
+ to_sign, signature, [OTHER_CERT_BYTES, PUBLIC_CERT_BYTES]
+ )
def test_verify_signature_failure():
- to_sign = b'foo'
+ to_sign = b"foo"
signer = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES)
signature = signer.sign(to_sign)
- assert not crypt.verify_signature(
- to_sign, signature, OTHER_CERT_BYTES)
+ assert not crypt.verify_signature(to_sign, signature, OTHER_CERT_BYTES)
diff --git a/tests/oauth2/test__client.py b/tests/oauth2/test__client.py
index 6fc4c3b..c415a1f 100644
--- a/tests/oauth2/test__client.py
+++ b/tests/oauth2/test__client.py
@@ -30,42 +30,44 @@
from google.oauth2 import _client
-DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "data")
-with open(os.path.join(DATA_DIR, 'privatekey.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
-SIGNER = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, '1')
+SIGNER = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, "1")
-SCOPES_AS_LIST = ['https://www.googleapis.com/auth/pubsub',
- 'https://www.googleapis.com/auth/logging.write']
-SCOPES_AS_STRING = ('https://www.googleapis.com/auth/pubsub'
- ' https://www.googleapis.com/auth/logging.write')
+SCOPES_AS_LIST = [
+ "https://www.googleapis.com/auth/pubsub",
+ "https://www.googleapis.com/auth/logging.write",
+]
+SCOPES_AS_STRING = (
+ "https://www.googleapis.com/auth/pubsub"
+ " https://www.googleapis.com/auth/logging.write"
+)
def test__handle_error_response():
- response_data = json.dumps({
- 'error': 'help',
- 'error_description': 'I\'m alive'})
+ response_data = json.dumps({"error": "help", "error_description": "I'm alive"})
with pytest.raises(exceptions.RefreshError) as excinfo:
_client._handle_error_response(response_data)
- assert excinfo.match(r'help: I\'m alive')
+ assert excinfo.match(r"help: I\'m alive")
def test__handle_error_response_non_json():
- response_data = 'Help, I\'m alive'
+ response_data = "Help, I'm alive"
with pytest.raises(exceptions.RefreshError) as excinfo:
_client._handle_error_response(response_data)
- assert excinfo.match(r'Help, I\'m alive')
+ assert excinfo.match(r"Help, I\'m alive")
-@mock.patch('google.auth._helpers.utcnow', return_value=datetime.datetime.min)
+@mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
def test__parse_expiry(unused_utcnow):
- result = _client._parse_expiry({'expires_in': 500})
+ result = _client._parse_expiry({"expires_in": 500})
assert result == datetime.datetime.min + datetime.timedelta(seconds=500)
@@ -76,188 +78,214 @@
def make_request(response_data, status=http_client.OK):
response = mock.create_autospec(transport.Response, instance=True)
response.status = status
- response.data = json.dumps(response_data).encode('utf-8')
+ response.data = json.dumps(response_data).encode("utf-8")
request = mock.create_autospec(transport.Request)
request.return_value = response
return request
def test__token_endpoint_request():
- request = make_request({'test': 'response'})
+ request = make_request({"test": "response"})
result = _client._token_endpoint_request(
- request, 'http://example.com', {'test': 'params'})
+ request, "http://example.com", {"test": "params"}
+ )
# Check request call
request.assert_called_with(
- method='POST',
- url='http://example.com',
- headers={'content-type': 'application/x-www-form-urlencoded'},
- body='test=params')
+ method="POST",
+ url="http://example.com",
+ headers={"content-type": "application/x-www-form-urlencoded"},
+ body="test=params",
+ )
# Check result
- assert result == {'test': 'response'}
+ assert result == {"test": "response"}
def test__token_endpoint_request_error():
request = make_request({}, status=http_client.BAD_REQUEST)
with pytest.raises(exceptions.RefreshError):
- _client._token_endpoint_request(request, 'http://example.com', {})
+ _client._token_endpoint_request(request, "http://example.com", {})
def test__token_endpoint_request_internal_failure_error():
- request = make_request({'error': 'internal_failure',
- 'error_description': 'internal_failure'},
- status=http_client.BAD_REQUEST)
+ request = make_request(
+ {"error": "internal_failure", "error_description": "internal_failure"},
+ status=http_client.BAD_REQUEST,
+ )
with pytest.raises(exceptions.RefreshError):
_client._token_endpoint_request(
- request, 'http://example.com',
- {'error': 'internal_failure',
- 'error_description': 'internal_failure'})
+ request,
+ "http://example.com",
+ {"error": "internal_failure", "error_description": "internal_failure"},
+ )
def verify_request_params(request, params):
- request_body = request.call_args[1]['body']
+ request_body = request.call_args[1]["body"]
request_params = urllib.parse.parse_qs(request_body)
for key, value in six.iteritems(params):
assert request_params[key][0] == value
-@mock.patch('google.auth._helpers.utcnow', return_value=datetime.datetime.min)
+@mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
def test_jwt_grant(utcnow):
- request = make_request({
- 'access_token': 'token',
- 'expires_in': 500,
- 'extra': 'data'})
+ request = make_request(
+ {"access_token": "token", "expires_in": 500, "extra": "data"}
+ )
token, expiry, extra_data = _client.jwt_grant(
- request, 'http://example.com', 'assertion_value')
+ request, "http://example.com", "assertion_value"
+ )
# Check request call
- verify_request_params(request, {
- 'grant_type': _client._JWT_GRANT_TYPE,
- 'assertion': 'assertion_value'
- })
+ verify_request_params(
+ request, {"grant_type": _client._JWT_GRANT_TYPE, "assertion": "assertion_value"}
+ )
# Check result
- assert token == 'token'
+ assert token == "token"
assert expiry == utcnow() + datetime.timedelta(seconds=500)
- assert extra_data['extra'] == 'data'
+ assert extra_data["extra"] == "data"
def test_jwt_grant_no_access_token():
- request = make_request({
- # No access token.
- 'expires_in': 500,
- 'extra': 'data'})
+ request = make_request(
+ {
+ # No access token.
+ "expires_in": 500,
+ "extra": "data",
+ }
+ )
with pytest.raises(exceptions.RefreshError):
- _client.jwt_grant(request, 'http://example.com', 'assertion_value')
+ _client.jwt_grant(request, "http://example.com", "assertion_value")
def test_id_token_jwt_grant():
now = _helpers.utcnow()
id_token_expiry = _helpers.datetime_to_secs(now)
- id_token = jwt.encode(SIGNER, {'exp': id_token_expiry}).decode('utf-8')
- request = make_request({
- 'id_token': id_token,
- 'extra': 'data'})
+ id_token = jwt.encode(SIGNER, {"exp": id_token_expiry}).decode("utf-8")
+ request = make_request({"id_token": id_token, "extra": "data"})
token, expiry, extra_data = _client.id_token_jwt_grant(
- request, 'http://example.com', 'assertion_value')
+ request, "http://example.com", "assertion_value"
+ )
# Check request call
- verify_request_params(request, {
- 'grant_type': _client._JWT_GRANT_TYPE,
- 'assertion': 'assertion_value'
- })
+ verify_request_params(
+ request, {"grant_type": _client._JWT_GRANT_TYPE, "assertion": "assertion_value"}
+ )
# Check result
assert token == id_token
# JWT does not store microseconds
now = now.replace(microsecond=0)
assert expiry == now
- assert extra_data['extra'] == 'data'
+ assert extra_data["extra"] == "data"
def test_id_token_jwt_grant_no_access_token():
- request = make_request({
- # No access token.
- 'expires_in': 500,
- 'extra': 'data'})
+ request = make_request(
+ {
+ # No access token.
+ "expires_in": 500,
+ "extra": "data",
+ }
+ )
with pytest.raises(exceptions.RefreshError):
- _client.id_token_jwt_grant(
- request, 'http://example.com', 'assertion_value')
+ _client.id_token_jwt_grant(request, "http://example.com", "assertion_value")
-@mock.patch('google.auth._helpers.utcnow', return_value=datetime.datetime.min)
+@mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
def test_refresh_grant(unused_utcnow):
- request = make_request({
- 'access_token': 'token',
- 'refresh_token': 'new_refresh_token',
- 'expires_in': 500,
- 'extra': 'data'})
+ request = make_request(
+ {
+ "access_token": "token",
+ "refresh_token": "new_refresh_token",
+ "expires_in": 500,
+ "extra": "data",
+ }
+ )
token, refresh_token, expiry, extra_data = _client.refresh_grant(
- request, 'http://example.com', 'refresh_token', 'client_id',
- 'client_secret')
+ request, "http://example.com", "refresh_token", "client_id", "client_secret"
+ )
# Check request call
- verify_request_params(request, {
- 'grant_type': _client._REFRESH_GRANT_TYPE,
- 'refresh_token': 'refresh_token',
- 'client_id': 'client_id',
- 'client_secret': 'client_secret'
- })
+ verify_request_params(
+ request,
+ {
+ "grant_type": _client._REFRESH_GRANT_TYPE,
+ "refresh_token": "refresh_token",
+ "client_id": "client_id",
+ "client_secret": "client_secret",
+ },
+ )
# Check result
- assert token == 'token'
- assert refresh_token == 'new_refresh_token'
+ assert token == "token"
+ assert refresh_token == "new_refresh_token"
assert expiry == datetime.datetime.min + datetime.timedelta(seconds=500)
- assert extra_data['extra'] == 'data'
+ assert extra_data["extra"] == "data"
-@mock.patch('google.auth._helpers.utcnow', return_value=datetime.datetime.min)
+@mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
def test_refresh_grant_with_scopes(unused_utcnow):
- request = make_request({
- 'access_token': 'token',
- 'refresh_token': 'new_refresh_token',
- 'expires_in': 500,
- 'extra': 'data',
- 'scope': SCOPES_AS_STRING})
+ request = make_request(
+ {
+ "access_token": "token",
+ "refresh_token": "new_refresh_token",
+ "expires_in": 500,
+ "extra": "data",
+ "scope": SCOPES_AS_STRING,
+ }
+ )
token, refresh_token, expiry, extra_data = _client.refresh_grant(
- request, 'http://example.com', 'refresh_token', 'client_id',
- 'client_secret', SCOPES_AS_LIST)
+ request,
+ "http://example.com",
+ "refresh_token",
+ "client_id",
+ "client_secret",
+ SCOPES_AS_LIST,
+ )
# Check request call.
- verify_request_params(request, {
- 'grant_type': _client._REFRESH_GRANT_TYPE,
- 'refresh_token': 'refresh_token',
- 'client_id': 'client_id',
- 'client_secret': 'client_secret',
- 'scope': SCOPES_AS_STRING
- })
+ verify_request_params(
+ request,
+ {
+ "grant_type": _client._REFRESH_GRANT_TYPE,
+ "refresh_token": "refresh_token",
+ "client_id": "client_id",
+ "client_secret": "client_secret",
+ "scope": SCOPES_AS_STRING,
+ },
+ )
# Check result.
- assert token == 'token'
- assert refresh_token == 'new_refresh_token'
+ assert token == "token"
+ assert refresh_token == "new_refresh_token"
assert expiry == datetime.datetime.min + datetime.timedelta(seconds=500)
- assert extra_data['extra'] == 'data'
+ assert extra_data["extra"] == "data"
def test_refresh_grant_no_access_token():
- request = make_request({
- # No access token.
- 'refresh_token': 'new_refresh_token',
- 'expires_in': 500,
- 'extra': 'data'})
+ request = make_request(
+ {
+ # No access token.
+ "refresh_token": "new_refresh_token",
+ "expires_in": 500,
+ "extra": "data",
+ }
+ )
with pytest.raises(exceptions.RefreshError):
_client.refresh_grant(
- request, 'http://example.com', 'refresh_token', 'client_id',
- 'client_secret')
+ request, "http://example.com", "refresh_token", "client_id", "client_secret"
+ )
diff --git a/tests/oauth2/test_credentials.py b/tests/oauth2/test_credentials.py
index 3231509..8bfdd7e 100644
--- a/tests/oauth2/test_credentials.py
+++ b/tests/oauth2/test_credentials.py
@@ -25,26 +25,29 @@
from google.oauth2 import credentials
-DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "data")
-AUTH_USER_JSON_FILE = os.path.join(DATA_DIR, 'authorized_user.json')
+AUTH_USER_JSON_FILE = os.path.join(DATA_DIR, "authorized_user.json")
-with open(AUTH_USER_JSON_FILE, 'r') as fh:
+with open(AUTH_USER_JSON_FILE, "r") as fh:
AUTH_USER_INFO = json.load(fh)
class TestCredentials(object):
- TOKEN_URI = 'https://example.com/oauth2/token'
- REFRESH_TOKEN = 'refresh_token'
- CLIENT_ID = 'client_id'
- CLIENT_SECRET = 'client_secret'
+ TOKEN_URI = "https://example.com/oauth2/token"
+ REFRESH_TOKEN = "refresh_token"
+ CLIENT_ID = "client_id"
+ CLIENT_SECRET = "client_secret"
@classmethod
def make_credentials(cls):
return credentials.Credentials(
- token=None, refresh_token=cls.REFRESH_TOKEN,
- token_uri=cls.TOKEN_URI, client_id=cls.CLIENT_ID,
- client_secret=cls.CLIENT_SECRET)
+ token=None,
+ refresh_token=cls.REFRESH_TOKEN,
+ token_uri=cls.TOKEN_URI,
+ client_id=cls.CLIENT_ID,
+ client_secret=cls.CLIENT_SECRET,
+ )
def test_default_state(self):
credentials = self.make_credentials()
@@ -59,14 +62,15 @@
assert credentials.client_id == self.CLIENT_ID
assert credentials.client_secret == self.CLIENT_SECRET
- @mock.patch('google.oauth2._client.refresh_grant', autospec=True)
+ @mock.patch("google.oauth2._client.refresh_grant", autospec=True)
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.min + _helpers.CLOCK_SKEW)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.min + _helpers.CLOCK_SKEW,
+ )
def test_refresh_success(self, unused_utcnow, refresh_grant):
- token = 'token'
+ token = "token"
expiry = _helpers.utcnow() + datetime.timedelta(seconds=500)
- grant_response = {'id_token': mock.sentinel.id_token}
+ grant_response = {"id_token": mock.sentinel.id_token}
refresh_grant.return_value = (
# Access token
token,
@@ -75,7 +79,8 @@
# Expiry,
expiry,
# Extra data
- grant_response)
+ grant_response,
+ )
request = mock.create_autospec(transport.Request)
credentials = self.make_credentials()
@@ -85,8 +90,13 @@
# Check jwt grant call.
refresh_grant.assert_called_with(
- request, self.TOKEN_URI, self.REFRESH_TOKEN, self.CLIENT_ID,
- self.CLIENT_SECRET, None)
+ request,
+ self.TOKEN_URI,
+ self.REFRESH_TOKEN,
+ self.CLIENT_ID,
+ self.CLIENT_SECRET,
+ None,
+ )
# Check that the credentials have the token and expiry
assert credentials.token == token
@@ -99,24 +109,25 @@
def test_refresh_no_refresh_token(self):
request = mock.create_autospec(transport.Request)
- credentials_ = credentials.Credentials(
- token=None, refresh_token=None)
+ credentials_ = credentials.Credentials(token=None, refresh_token=None)
- with pytest.raises(exceptions.RefreshError, match='necessary fields'):
+ with pytest.raises(exceptions.RefreshError, match="necessary fields"):
credentials_.refresh(request)
request.assert_not_called()
- @mock.patch('google.oauth2._client.refresh_grant', autospec=True)
+ @mock.patch("google.oauth2._client.refresh_grant", autospec=True)
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.min + _helpers.CLOCK_SKEW)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.min + _helpers.CLOCK_SKEW,
+ )
def test_credentials_with_scopes_requested_refresh_success(
- self, unused_utcnow, refresh_grant):
- scopes = ['email', 'profile']
- token = 'token'
+ self, unused_utcnow, refresh_grant
+ ):
+ scopes = ["email", "profile"]
+ token = "token"
expiry = _helpers.utcnow() + datetime.timedelta(seconds=500)
- grant_response = {'id_token': mock.sentinel.id_token}
+ grant_response = {"id_token": mock.sentinel.id_token}
refresh_grant.return_value = (
# Access token
token,
@@ -125,21 +136,31 @@
# Expiry,
expiry,
# Extra data
- grant_response)
+ grant_response,
+ )
request = mock.create_autospec(transport.Request)
creds = credentials.Credentials(
- token=None, refresh_token=self.REFRESH_TOKEN,
- token_uri=self.TOKEN_URI, client_id=self.CLIENT_ID,
- client_secret=self.CLIENT_SECRET, scopes=scopes)
+ token=None,
+ refresh_token=self.REFRESH_TOKEN,
+ token_uri=self.TOKEN_URI,
+ client_id=self.CLIENT_ID,
+ client_secret=self.CLIENT_SECRET,
+ scopes=scopes,
+ )
# Refresh credentials
creds.refresh(request)
# Check jwt grant call.
refresh_grant.assert_called_with(
- request, self.TOKEN_URI, self.REFRESH_TOKEN, self.CLIENT_ID,
- self.CLIENT_SECRET, scopes)
+ request,
+ self.TOKEN_URI,
+ self.REFRESH_TOKEN,
+ self.CLIENT_ID,
+ self.CLIENT_SECRET,
+ scopes,
+ )
# Check that the credentials have the token and expiry
assert creds.token == token
@@ -151,17 +172,21 @@
# expired.)
assert creds.valid
- @mock.patch('google.oauth2._client.refresh_grant', autospec=True)
+ @mock.patch("google.oauth2._client.refresh_grant", autospec=True)
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.min + _helpers.CLOCK_SKEW)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.min + _helpers.CLOCK_SKEW,
+ )
def test_credentials_with_scopes_returned_refresh_success(
- self, unused_utcnow, refresh_grant):
- scopes = ['email', 'profile']
- token = 'token'
+ self, unused_utcnow, refresh_grant
+ ):
+ scopes = ["email", "profile"]
+ token = "token"
expiry = _helpers.utcnow() + datetime.timedelta(seconds=500)
- grant_response = {'id_token': mock.sentinel.id_token,
- 'scopes': ' '.join(scopes)}
+ grant_response = {
+ "id_token": mock.sentinel.id_token,
+ "scopes": " ".join(scopes),
+ }
refresh_grant.return_value = (
# Access token
token,
@@ -170,21 +195,31 @@
# Expiry,
expiry,
# Extra data
- grant_response)
+ grant_response,
+ )
request = mock.create_autospec(transport.Request)
creds = credentials.Credentials(
- token=None, refresh_token=self.REFRESH_TOKEN,
- token_uri=self.TOKEN_URI, client_id=self.CLIENT_ID,
- client_secret=self.CLIENT_SECRET, scopes=scopes)
+ token=None,
+ refresh_token=self.REFRESH_TOKEN,
+ token_uri=self.TOKEN_URI,
+ client_id=self.CLIENT_ID,
+ client_secret=self.CLIENT_SECRET,
+ scopes=scopes,
+ )
# Refresh credentials
creds.refresh(request)
# Check jwt grant call.
refresh_grant.assert_called_with(
- request, self.TOKEN_URI, self.REFRESH_TOKEN, self.CLIENT_ID,
- self.CLIENT_SECRET, scopes)
+ request,
+ self.TOKEN_URI,
+ self.REFRESH_TOKEN,
+ self.CLIENT_ID,
+ self.CLIENT_SECRET,
+ scopes,
+ )
# Check that the credentials have the token and expiry
assert creds.token == token
@@ -196,18 +231,22 @@
# expired.)
assert creds.valid
- @mock.patch('google.oauth2._client.refresh_grant', autospec=True)
+ @mock.patch("google.oauth2._client.refresh_grant", autospec=True)
@mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.min + _helpers.CLOCK_SKEW)
+ "google.auth._helpers.utcnow",
+ return_value=datetime.datetime.min + _helpers.CLOCK_SKEW,
+ )
def test_credentials_with_scopes_refresh_failure_raises_refresh_error(
- self, unused_utcnow, refresh_grant):
- scopes = ['email', 'profile']
- scopes_returned = ['email']
- token = 'token'
+ self, unused_utcnow, refresh_grant
+ ):
+ scopes = ["email", "profile"]
+ scopes_returned = ["email"]
+ token = "token"
expiry = _helpers.utcnow() + datetime.timedelta(seconds=500)
- grant_response = {'id_token': mock.sentinel.id_token,
- 'scopes': ' '.join(scopes_returned)}
+ grant_response = {
+ "id_token": mock.sentinel.id_token,
+ "scopes": " ".join(scopes_returned),
+ }
refresh_grant.return_value = (
# Access token
token,
@@ -216,23 +255,34 @@
# Expiry,
expiry,
# Extra data
- grant_response)
+ grant_response,
+ )
request = mock.create_autospec(transport.Request)
creds = credentials.Credentials(
- token=None, refresh_token=self.REFRESH_TOKEN,
- token_uri=self.TOKEN_URI, client_id=self.CLIENT_ID,
- client_secret=self.CLIENT_SECRET, scopes=scopes)
+ token=None,
+ refresh_token=self.REFRESH_TOKEN,
+ token_uri=self.TOKEN_URI,
+ client_id=self.CLIENT_ID,
+ client_secret=self.CLIENT_SECRET,
+ scopes=scopes,
+ )
# Refresh credentials
- with pytest.raises(exceptions.RefreshError,
- match='Not all requested scopes were granted'):
+ with pytest.raises(
+ exceptions.RefreshError, match="Not all requested scopes were granted"
+ ):
creds.refresh(request)
# Check jwt grant call.
refresh_grant.assert_called_with(
- request, self.TOKEN_URI, self.REFRESH_TOKEN, self.CLIENT_ID,
- self.CLIENT_SECRET, scopes)
+ request,
+ self.TOKEN_URI,
+ self.REFRESH_TOKEN,
+ self.CLIENT_ID,
+ self.CLIENT_SECRET,
+ scopes,
+ )
# Check that the credentials have the token and expiry
assert creds.token == token
@@ -248,37 +298,36 @@
info = AUTH_USER_INFO.copy()
creds = credentials.Credentials.from_authorized_user_info(info)
- assert creds.client_secret == info['client_secret']
- assert creds.client_id == info['client_id']
- assert creds.refresh_token == info['refresh_token']
+ assert creds.client_secret == info["client_secret"]
+ assert creds.client_id == info["client_id"]
+ assert creds.refresh_token == info["refresh_token"]
assert creds.token_uri == credentials._GOOGLE_OAUTH2_TOKEN_ENDPOINT
assert creds.scopes is None
- scopes = ['email', 'profile']
- creds = credentials.Credentials.from_authorized_user_info(
- info, scopes)
- assert creds.client_secret == info['client_secret']
- assert creds.client_id == info['client_id']
- assert creds.refresh_token == info['refresh_token']
+ scopes = ["email", "profile"]
+ creds = credentials.Credentials.from_authorized_user_info(info, scopes)
+ assert creds.client_secret == info["client_secret"]
+ assert creds.client_id == info["client_id"]
+ assert creds.refresh_token == info["refresh_token"]
assert creds.token_uri == credentials._GOOGLE_OAUTH2_TOKEN_ENDPOINT
assert creds.scopes == scopes
def test_from_authorized_user_file(self):
info = AUTH_USER_INFO.copy()
- creds = credentials.Credentials.from_authorized_user_file(
- AUTH_USER_JSON_FILE)
- assert creds.client_secret == info['client_secret']
- assert creds.client_id == info['client_id']
- assert creds.refresh_token == info['refresh_token']
+ creds = credentials.Credentials.from_authorized_user_file(AUTH_USER_JSON_FILE)
+ assert creds.client_secret == info["client_secret"]
+ assert creds.client_id == info["client_id"]
+ assert creds.refresh_token == info["refresh_token"]
assert creds.token_uri == credentials._GOOGLE_OAUTH2_TOKEN_ENDPOINT
assert creds.scopes is None
- scopes = ['email', 'profile']
+ scopes = ["email", "profile"]
creds = credentials.Credentials.from_authorized_user_file(
- AUTH_USER_JSON_FILE, scopes)
- assert creds.client_secret == info['client_secret']
- assert creds.client_id == info['client_id']
- assert creds.refresh_token == info['refresh_token']
+ AUTH_USER_JSON_FILE, scopes
+ )
+ assert creds.client_secret == info["client_secret"]
+ assert creds.client_id == info["client_id"]
+ assert creds.refresh_token == info["refresh_token"]
assert creds.token_uri == credentials._GOOGLE_OAUTH2_TOKEN_ENDPOINT
assert creds.scopes == scopes
diff --git a/tests/oauth2/test_id_token.py b/tests/oauth2/test_id_token.py
index 360f92f..980a8e9 100644
--- a/tests/oauth2/test_id_token.py
+++ b/tests/oauth2/test_id_token.py
@@ -27,7 +27,7 @@
response.status = status
if data is not None:
- response.data = json.dumps(data).encode('utf-8')
+ response.data = json.dumps(data).encode("utf-8")
request = mock.create_autospec(transport.Request)
request.return_value = response
@@ -35,12 +35,12 @@
def test__fetch_certs_success():
- certs = {'1': 'cert'}
+ certs = {"1": "cert"}
request = make_request(200, certs)
returned_certs = id_token._fetch_certs(request, mock.sentinel.cert_url)
- request.assert_called_once_with(mock.sentinel.cert_url, method='GET')
+ request.assert_called_once_with(mock.sentinel.cert_url, method="GET")
assert returned_certs == certs
@@ -50,66 +50,67 @@
with pytest.raises(exceptions.TransportError):
id_token._fetch_certs(request, mock.sentinel.cert_url)
- request.assert_called_once_with(mock.sentinel.cert_url, method='GET')
+ request.assert_called_once_with(mock.sentinel.cert_url, method="GET")
-@mock.patch('google.auth.jwt.decode', autospec=True)
-@mock.patch('google.oauth2.id_token._fetch_certs', autospec=True)
+@mock.patch("google.auth.jwt.decode", autospec=True)
+@mock.patch("google.oauth2.id_token._fetch_certs", autospec=True)
def test_verify_token(_fetch_certs, decode):
result = id_token.verify_token(mock.sentinel.token, mock.sentinel.request)
assert result == decode.return_value
_fetch_certs.assert_called_once_with(
- mock.sentinel.request, id_token._GOOGLE_OAUTH2_CERTS_URL)
+ mock.sentinel.request, id_token._GOOGLE_OAUTH2_CERTS_URL
+ )
decode.assert_called_once_with(
- mock.sentinel.token,
- certs=_fetch_certs.return_value,
- audience=None)
+ mock.sentinel.token, certs=_fetch_certs.return_value, audience=None
+ )
-@mock.patch('google.auth.jwt.decode', autospec=True)
-@mock.patch('google.oauth2.id_token._fetch_certs', autospec=True)
+@mock.patch("google.auth.jwt.decode", autospec=True)
+@mock.patch("google.oauth2.id_token._fetch_certs", autospec=True)
def test_verify_token_args(_fetch_certs, decode):
result = id_token.verify_token(
mock.sentinel.token,
mock.sentinel.request,
audience=mock.sentinel.audience,
- certs_url=mock.sentinel.certs_url)
+ certs_url=mock.sentinel.certs_url,
+ )
assert result == decode.return_value
- _fetch_certs.assert_called_once_with(
- mock.sentinel.request, mock.sentinel.certs_url)
+ _fetch_certs.assert_called_once_with(mock.sentinel.request, mock.sentinel.certs_url)
decode.assert_called_once_with(
mock.sentinel.token,
certs=_fetch_certs.return_value,
- audience=mock.sentinel.audience)
+ audience=mock.sentinel.audience,
+ )
-@mock.patch('google.oauth2.id_token.verify_token', autospec=True)
+@mock.patch("google.oauth2.id_token.verify_token", autospec=True)
def test_verify_oauth2_token(verify_token):
result = id_token.verify_oauth2_token(
- mock.sentinel.token,
- mock.sentinel.request,
- audience=mock.sentinel.audience)
+ mock.sentinel.token, mock.sentinel.request, audience=mock.sentinel.audience
+ )
assert result == verify_token.return_value
verify_token.assert_called_once_with(
mock.sentinel.token,
mock.sentinel.request,
audience=mock.sentinel.audience,
- certs_url=id_token._GOOGLE_OAUTH2_CERTS_URL)
+ certs_url=id_token._GOOGLE_OAUTH2_CERTS_URL,
+ )
-@mock.patch('google.oauth2.id_token.verify_token', autospec=True)
+@mock.patch("google.oauth2.id_token.verify_token", autospec=True)
def test_verify_firebase_token(verify_token):
result = id_token.verify_firebase_token(
- mock.sentinel.token,
- mock.sentinel.request,
- audience=mock.sentinel.audience)
+ mock.sentinel.token, mock.sentinel.request, audience=mock.sentinel.audience
+ )
assert result == verify_token.return_value
verify_token.assert_called_once_with(
mock.sentinel.token,
mock.sentinel.request,
audience=mock.sentinel.audience,
- certs_url=id_token._GOOGLE_APIS_CERTS_URL)
+ certs_url=id_token._GOOGLE_APIS_CERTS_URL,
+ )
diff --git a/tests/oauth2/test_service_account.py b/tests/oauth2/test_service_account.py
index 54ac0f5..0f9d460 100644
--- a/tests/oauth2/test_service_account.py
+++ b/tests/oauth2/test_service_account.py
@@ -25,58 +25,58 @@
from google.oauth2 import service_account
-DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "data")
-with open(os.path.join(DATA_DIR, 'privatekey.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
-with open(os.path.join(DATA_DIR, 'public_cert.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "public_cert.pem"), "rb") as fh:
PUBLIC_CERT_BYTES = fh.read()
-with open(os.path.join(DATA_DIR, 'other_cert.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "other_cert.pem"), "rb") as fh:
OTHER_CERT_BYTES = fh.read()
-SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, 'service_account.json')
+SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
-with open(SERVICE_ACCOUNT_JSON_FILE, 'r') as fh:
+with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
SERVICE_ACCOUNT_INFO = json.load(fh)
-SIGNER = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, '1')
+SIGNER = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, "1")
class TestCredentials(object):
- SERVICE_ACCOUNT_EMAIL = 'service-account@example.com'
- TOKEN_URI = 'https://example.com/oauth2/token'
+ SERVICE_ACCOUNT_EMAIL = "service-account@example.com"
+ TOKEN_URI = "https://example.com/oauth2/token"
@classmethod
def make_credentials(cls):
return service_account.Credentials(
- SIGNER, cls.SERVICE_ACCOUNT_EMAIL, cls.TOKEN_URI)
+ SIGNER, cls.SERVICE_ACCOUNT_EMAIL, cls.TOKEN_URI
+ )
def test_from_service_account_info(self):
credentials = service_account.Credentials.from_service_account_info(
- SERVICE_ACCOUNT_INFO)
+ SERVICE_ACCOUNT_INFO
+ )
- assert (credentials._signer.key_id ==
- SERVICE_ACCOUNT_INFO['private_key_id'])
- assert (credentials.service_account_email ==
- SERVICE_ACCOUNT_INFO['client_email'])
- assert credentials._token_uri == SERVICE_ACCOUNT_INFO['token_uri']
+ assert credentials._signer.key_id == SERVICE_ACCOUNT_INFO["private_key_id"]
+ assert credentials.service_account_email == SERVICE_ACCOUNT_INFO["client_email"]
+ assert credentials._token_uri == SERVICE_ACCOUNT_INFO["token_uri"]
def test_from_service_account_info_args(self):
info = SERVICE_ACCOUNT_INFO.copy()
- scopes = ['email', 'profile']
- subject = 'subject'
- additional_claims = {'meta': 'data'}
+ scopes = ["email", "profile"]
+ subject = "subject"
+ additional_claims = {"meta": "data"}
credentials = service_account.Credentials.from_service_account_info(
- info, scopes=scopes, subject=subject,
- additional_claims=additional_claims)
+ info, scopes=scopes, subject=subject, additional_claims=additional_claims
+ )
- assert credentials.service_account_email == info['client_email']
- assert credentials.project_id == info['project_id']
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._token_uri == info['token_uri']
+ assert credentials.service_account_email == info["client_email"]
+ assert credentials.project_id == info["project_id"]
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._token_uri == info["token_uri"]
assert credentials._scopes == scopes
assert credentials._subject == subject
assert credentials._additional_claims == additional_claims
@@ -85,27 +85,31 @@
info = SERVICE_ACCOUNT_INFO.copy()
credentials = service_account.Credentials.from_service_account_file(
- SERVICE_ACCOUNT_JSON_FILE)
+ SERVICE_ACCOUNT_JSON_FILE
+ )
- assert credentials.service_account_email == info['client_email']
- assert credentials.project_id == info['project_id']
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._token_uri == info['token_uri']
+ assert credentials.service_account_email == info["client_email"]
+ assert credentials.project_id == info["project_id"]
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._token_uri == info["token_uri"]
def test_from_service_account_file_args(self):
info = SERVICE_ACCOUNT_INFO.copy()
- scopes = ['email', 'profile']
- subject = 'subject'
- additional_claims = {'meta': 'data'}
+ scopes = ["email", "profile"]
+ subject = "subject"
+ additional_claims = {"meta": "data"}
credentials = service_account.Credentials.from_service_account_file(
- SERVICE_ACCOUNT_JSON_FILE, subject=subject,
- scopes=scopes, additional_claims=additional_claims)
+ SERVICE_ACCOUNT_JSON_FILE,
+ subject=subject,
+ scopes=scopes,
+ additional_claims=additional_claims,
+ )
- assert credentials.service_account_email == info['client_email']
- assert credentials.project_id == info['project_id']
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._token_uri == info['token_uri']
+ assert credentials.service_account_email == info["client_email"]
+ assert credentials.project_id == info["project_id"]
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._token_uri == info["token_uri"]
assert credentials._scopes == scopes
assert credentials._subject == subject
assert credentials._additional_claims == additional_claims
@@ -120,7 +124,7 @@
def test_sign_bytes(self):
credentials = self.make_credentials()
- to_sign = b'123'
+ to_sign = b"123"
signature = credentials.sign_bytes(to_sign)
assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)
@@ -134,46 +138,47 @@
def test_create_scoped(self):
credentials = self.make_credentials()
- scopes = ['email', 'profile']
+ scopes = ["email", "profile"]
credentials = credentials.with_scopes(scopes)
assert credentials._scopes == scopes
def test_with_claims(self):
credentials = self.make_credentials()
- new_credentials = credentials.with_claims({'meep': 'moop'})
- assert new_credentials._additional_claims == {'meep': 'moop'}
+ new_credentials = credentials.with_claims({"meep": "moop"})
+ assert new_credentials._additional_claims == {"meep": "moop"}
def test__make_authorization_grant_assertion(self):
credentials = self.make_credentials()
token = credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, PUBLIC_CERT_BYTES)
- assert payload['iss'] == self.SERVICE_ACCOUNT_EMAIL
- assert payload['aud'] == self.TOKEN_URI
+ assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL
+ assert payload["aud"] == self.TOKEN_URI
def test__make_authorization_grant_assertion_scoped(self):
credentials = self.make_credentials()
- scopes = ['email', 'profile']
+ scopes = ["email", "profile"]
credentials = credentials.with_scopes(scopes)
token = credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, PUBLIC_CERT_BYTES)
- assert payload['scope'] == 'email profile'
+ assert payload["scope"] == "email profile"
def test__make_authorization_grant_assertion_subject(self):
credentials = self.make_credentials()
- subject = 'user@example.com'
+ subject = "user@example.com"
credentials = credentials.with_subject(subject)
token = credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, PUBLIC_CERT_BYTES)
- assert payload['sub'] == subject
+ assert payload["sub"] == subject
- @mock.patch('google.oauth2._client.jwt_grant', autospec=True)
+ @mock.patch("google.oauth2._client.jwt_grant", autospec=True)
def test_refresh_success(self, jwt_grant):
credentials = self.make_credentials()
- token = 'token'
+ token = "token"
jwt_grant.return_value = (
token,
_helpers.utcnow() + datetime.timedelta(seconds=500),
- {})
+ {},
+ )
request = mock.create_autospec(transport.Request, instance=True)
# Refresh credentials
@@ -196,20 +201,22 @@
# expired)
assert credentials.valid
- @mock.patch('google.oauth2._client.jwt_grant', autospec=True)
+ @mock.patch("google.oauth2._client.jwt_grant", autospec=True)
def test_before_request_refreshes(self, jwt_grant):
credentials = self.make_credentials()
- token = 'token'
+ token = "token"
jwt_grant.return_value = (
- token, _helpers.utcnow() + datetime.timedelta(seconds=500), None)
+ token,
+ _helpers.utcnow() + datetime.timedelta(seconds=500),
+ None,
+ )
request = mock.create_autospec(transport.Request, instance=True)
# Credentials should start as invalid
assert not credentials.valid
# before_request should cause a refresh
- credentials.before_request(
- request, 'GET', 'http://example.com?a=1#3', {})
+ credentials.before_request(request, "GET", "http://example.com?a=1#3", {})
# The refresh endpoint should've been called.
assert jwt_grant.called
@@ -219,40 +226,36 @@
class TestIDTokenCredentials(object):
- SERVICE_ACCOUNT_EMAIL = 'service-account@example.com'
- TOKEN_URI = 'https://example.com/oauth2/token'
- TARGET_AUDIENCE = 'https://example.com'
+ SERVICE_ACCOUNT_EMAIL = "service-account@example.com"
+ TOKEN_URI = "https://example.com/oauth2/token"
+ TARGET_AUDIENCE = "https://example.com"
@classmethod
def make_credentials(cls):
return service_account.IDTokenCredentials(
- SIGNER, cls.SERVICE_ACCOUNT_EMAIL, cls.TOKEN_URI,
- cls.TARGET_AUDIENCE)
+ SIGNER, cls.SERVICE_ACCOUNT_EMAIL, cls.TOKEN_URI, cls.TARGET_AUDIENCE
+ )
def test_from_service_account_info(self):
- credentials = (
- service_account.IDTokenCredentials.from_service_account_info(
- SERVICE_ACCOUNT_INFO,
- target_audience=self.TARGET_AUDIENCE))
+ credentials = service_account.IDTokenCredentials.from_service_account_info(
+ SERVICE_ACCOUNT_INFO, target_audience=self.TARGET_AUDIENCE
+ )
- assert (credentials._signer.key_id ==
- SERVICE_ACCOUNT_INFO['private_key_id'])
- assert (credentials.service_account_email ==
- SERVICE_ACCOUNT_INFO['client_email'])
- assert credentials._token_uri == SERVICE_ACCOUNT_INFO['token_uri']
+ assert credentials._signer.key_id == SERVICE_ACCOUNT_INFO["private_key_id"]
+ assert credentials.service_account_email == SERVICE_ACCOUNT_INFO["client_email"]
+ assert credentials._token_uri == SERVICE_ACCOUNT_INFO["token_uri"]
assert credentials._target_audience == self.TARGET_AUDIENCE
def test_from_service_account_file(self):
info = SERVICE_ACCOUNT_INFO.copy()
- credentials = (
- service_account.IDTokenCredentials.from_service_account_file(
- SERVICE_ACCOUNT_JSON_FILE,
- target_audience=self.TARGET_AUDIENCE))
+ credentials = service_account.IDTokenCredentials.from_service_account_file(
+ SERVICE_ACCOUNT_JSON_FILE, target_audience=self.TARGET_AUDIENCE
+ )
- assert credentials.service_account_email == info['client_email']
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._token_uri == info['token_uri']
+ assert credentials.service_account_email == info["client_email"]
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._token_uri == info["token_uri"]
assert credentials._target_audience == self.TARGET_AUDIENCE
def test_default_state(self):
@@ -263,7 +266,7 @@
def test_sign_bytes(self):
credentials = self.make_credentials()
- to_sign = b'123'
+ to_sign = b"123"
signature = credentials.sign_bytes(to_sign)
assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)
@@ -277,26 +280,26 @@
def test_with_target_audience(self):
credentials = self.make_credentials()
- new_credentials = credentials.with_target_audience(
- 'https://new.example.com')
- assert new_credentials._target_audience == 'https://new.example.com'
+ new_credentials = credentials.with_target_audience("https://new.example.com")
+ assert new_credentials._target_audience == "https://new.example.com"
def test__make_authorization_grant_assertion(self):
credentials = self.make_credentials()
token = credentials._make_authorization_grant_assertion()
payload = jwt.decode(token, PUBLIC_CERT_BYTES)
- assert payload['iss'] == self.SERVICE_ACCOUNT_EMAIL
- assert payload['aud'] == self.TOKEN_URI
- assert payload['target_audience'] == self.TARGET_AUDIENCE
+ assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL
+ assert payload["aud"] == self.TOKEN_URI
+ assert payload["target_audience"] == self.TARGET_AUDIENCE
- @mock.patch('google.oauth2._client.id_token_jwt_grant', autospec=True)
+ @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True)
def test_refresh_success(self, id_token_jwt_grant):
credentials = self.make_credentials()
- token = 'token'
+ token = "token"
id_token_jwt_grant.return_value = (
token,
_helpers.utcnow() + datetime.timedelta(seconds=500),
- {})
+ {},
+ )
request = mock.create_autospec(transport.Request, instance=True)
# Refresh credentials
@@ -319,20 +322,22 @@
# expired)
assert credentials.valid
- @mock.patch('google.oauth2._client.id_token_jwt_grant', autospec=True)
+ @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True)
def test_before_request_refreshes(self, id_token_jwt_grant):
credentials = self.make_credentials()
- token = 'token'
+ token = "token"
id_token_jwt_grant.return_value = (
- token, _helpers.utcnow() + datetime.timedelta(seconds=500), None)
+ token,
+ _helpers.utcnow() + datetime.timedelta(seconds=500),
+ None,
+ )
request = mock.create_autospec(transport.Request, instance=True)
# Credentials should start as invalid
assert not credentials.valid
# before_request should cause a refresh
- credentials.before_request(
- request, 'GET', 'http://example.com?a=1#3', {})
+ credentials.before_request(request, "GET", "http://example.com?a=1#3", {})
# The refresh endpoint should've been called.
assert id_token_jwt_grant.called
diff --git a/tests/test__cloud_sdk.py b/tests/test__cloud_sdk.py
index 58c7270..c5c5c27 100644
--- a/tests/test__cloud_sdk.py
+++ b/tests/test__cloud_sdk.py
@@ -25,29 +25,33 @@
import google.oauth2.credentials
-DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
-AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, 'authorized_user.json')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
+AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json")
with io.open(AUTHORIZED_USER_FILE) as fh:
AUTHORIZED_USER_FILE_DATA = json.load(fh)
-SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, 'service_account.json')
+SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, "service_account.json")
with io.open(SERVICE_ACCOUNT_FILE) as fh:
SERVICE_ACCOUNT_FILE_DATA = json.load(fh)
-with io.open(os.path.join(DATA_DIR, 'cloud_sdk_config.json'), 'rb') as fh:
+with io.open(os.path.join(DATA_DIR, "cloud_sdk_config.json"), "rb") as fh:
CLOUD_SDK_CONFIG_FILE_DATA = fh.read()
-@pytest.mark.parametrize('data, expected_project_id', [
- (CLOUD_SDK_CONFIG_FILE_DATA, 'example-project'),
- (b'I am some bad json', None),
- (b'{}', None)
-])
+@pytest.mark.parametrize(
+ "data, expected_project_id",
+ [
+ (CLOUD_SDK_CONFIG_FILE_DATA, "example-project"),
+ (b"I am some bad json", None),
+ (b"{}", None),
+ ],
+)
def test_get_project_id(data, expected_project_id):
check_output_patch = mock.patch(
- 'subprocess.check_output', autospec=True, return_value=data)
+ "subprocess.check_output", autospec=True, return_value=data
+ )
with check_output_patch as check_output:
project_id = _cloud_sdk.get_project_id()
@@ -57,100 +61,99 @@
@mock.patch(
- 'subprocess.check_output', autospec=True,
- side_effect=subprocess.CalledProcessError(-1, None))
+ "subprocess.check_output",
+ autospec=True,
+ side_effect=subprocess.CalledProcessError(-1, None),
+)
def test_get_project_id_call_error(check_output):
project_id = _cloud_sdk.get_project_id()
assert project_id is None
assert check_output.called
-@mock.patch('os.name', new='nt')
+@mock.patch("os.name", new="nt")
def test_get_project_id_windows():
check_output_patch = mock.patch(
- 'subprocess.check_output', autospec=True,
- return_value=CLOUD_SDK_CONFIG_FILE_DATA)
+ "subprocess.check_output",
+ autospec=True,
+ return_value=CLOUD_SDK_CONFIG_FILE_DATA,
+ )
with check_output_patch as check_output:
project_id = _cloud_sdk.get_project_id()
- assert project_id == 'example-project'
+ assert project_id == "example-project"
assert check_output.called
# Make sure the executable is `gcloud.cmd`.
args = check_output.call_args[0]
command = args[0]
executable = command[0]
- assert executable == 'gcloud.cmd'
+ assert executable == "gcloud.cmd"
-@mock.patch(
- 'google.auth._cloud_sdk.get_config_path', autospec=True)
+@mock.patch("google.auth._cloud_sdk.get_config_path", autospec=True)
def test_get_application_default_credentials_path(get_config_dir):
- config_path = 'config_path'
+ config_path = "config_path"
get_config_dir.return_value = config_path
credentials_path = _cloud_sdk.get_application_default_credentials_path()
assert credentials_path == os.path.join(
- config_path, _cloud_sdk._CREDENTIALS_FILENAME)
+ config_path, _cloud_sdk._CREDENTIALS_FILENAME
+ )
def test_get_config_path_env_var(monkeypatch):
- config_path_sentinel = 'config_path'
- monkeypatch.setenv(
- environment_vars.CLOUD_SDK_CONFIG_DIR, config_path_sentinel)
+ config_path_sentinel = "config_path"
+ monkeypatch.setenv(environment_vars.CLOUD_SDK_CONFIG_DIR, config_path_sentinel)
config_path = _cloud_sdk.get_config_path()
assert config_path == config_path_sentinel
-@mock.patch('os.path.expanduser')
+@mock.patch("os.path.expanduser")
def test_get_config_path_unix(expanduser):
expanduser.side_effect = lambda path: path
config_path = _cloud_sdk.get_config_path()
- assert os.path.split(config_path) == (
- '~/.config', _cloud_sdk._CONFIG_DIRECTORY)
+ assert os.path.split(config_path) == ("~/.config", _cloud_sdk._CONFIG_DIRECTORY)
-@mock.patch('os.name', new='nt')
+@mock.patch("os.name", new="nt")
def test_get_config_path_windows(monkeypatch):
- appdata = 'appdata'
+ appdata = "appdata"
monkeypatch.setenv(_cloud_sdk._WINDOWS_CONFIG_ROOT_ENV_VAR, appdata)
config_path = _cloud_sdk.get_config_path()
- assert os.path.split(config_path) == (
- appdata, _cloud_sdk._CONFIG_DIRECTORY)
+ assert os.path.split(config_path) == (appdata, _cloud_sdk._CONFIG_DIRECTORY)
-@mock.patch('os.name', new='nt')
+@mock.patch("os.name", new="nt")
def test_get_config_path_no_appdata(monkeypatch):
monkeypatch.delenv(_cloud_sdk._WINDOWS_CONFIG_ROOT_ENV_VAR, raising=False)
- monkeypatch.setenv('SystemDrive', 'G:')
+ monkeypatch.setenv("SystemDrive", "G:")
config_path = _cloud_sdk.get_config_path()
- assert os.path.split(config_path) == (
- 'G:/\\', _cloud_sdk._CONFIG_DIRECTORY)
+ assert os.path.split(config_path) == ("G:/\\", _cloud_sdk._CONFIG_DIRECTORY)
def test_load_authorized_user_credentials():
- credentials = _cloud_sdk.load_authorized_user_credentials(
- AUTHORIZED_USER_FILE_DATA)
+ credentials = _cloud_sdk.load_authorized_user_credentials(AUTHORIZED_USER_FILE_DATA)
assert isinstance(credentials, google.oauth2.credentials.Credentials)
assert credentials.token is None
- assert (credentials._refresh_token ==
- AUTHORIZED_USER_FILE_DATA['refresh_token'])
- assert credentials._client_id == AUTHORIZED_USER_FILE_DATA['client_id']
- assert (credentials._client_secret ==
- AUTHORIZED_USER_FILE_DATA['client_secret'])
- assert (credentials._token_uri ==
- google.oauth2.credentials._GOOGLE_OAUTH2_TOKEN_ENDPOINT)
+ assert credentials._refresh_token == AUTHORIZED_USER_FILE_DATA["refresh_token"]
+ assert credentials._client_id == AUTHORIZED_USER_FILE_DATA["client_id"]
+ assert credentials._client_secret == AUTHORIZED_USER_FILE_DATA["client_secret"]
+ assert (
+ credentials._token_uri
+ == google.oauth2.credentials._GOOGLE_OAUTH2_TOKEN_ENDPOINT
+ )
def test_load_authorized_user_credentials_bad_format():
with pytest.raises(ValueError) as excinfo:
_cloud_sdk.load_authorized_user_credentials({})
- assert excinfo.match(r'missing fields')
+ assert excinfo.match(r"missing fields")
diff --git a/tests/test__default.py b/tests/test__default.py
index d143479..2c86f3f 100644
--- a/tests/test__default.py
+++ b/tests/test__default.py
@@ -27,94 +27,96 @@
import google.oauth2.credentials
-DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
-AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, 'authorized_user.json')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
+AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json")
with open(AUTHORIZED_USER_FILE) as fh:
AUTHORIZED_USER_FILE_DATA = json.load(fh)
AUTHORIZED_USER_CLOUD_SDK_FILE = os.path.join(
- DATA_DIR, 'authorized_user_cloud_sdk.json')
+ DATA_DIR, "authorized_user_cloud_sdk.json"
+)
-SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, 'service_account.json')
+SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, "service_account.json")
with open(SERVICE_ACCOUNT_FILE) as fh:
SERVICE_ACCOUNT_FILE_DATA = json.load(fh)
LOAD_FILE_PATCH = mock.patch(
- 'google.auth._default._load_credentials_from_file', return_value=(
- mock.sentinel.credentials, mock.sentinel.project_id), autospec=True)
+ "google.auth._default._load_credentials_from_file",
+ return_value=(mock.sentinel.credentials, mock.sentinel.project_id),
+ autospec=True,
+)
def test__load_credentials_from_missing_file():
with pytest.raises(exceptions.DefaultCredentialsError) as excinfo:
- _default._load_credentials_from_file('')
+ _default._load_credentials_from_file("")
- assert excinfo.match(r'not found')
+ assert excinfo.match(r"not found")
def test__load_credentials_from_file_invalid_json(tmpdir):
- jsonfile = tmpdir.join('invalid.json')
- jsonfile.write('{')
+ jsonfile = tmpdir.join("invalid.json")
+ jsonfile.write("{")
with pytest.raises(exceptions.DefaultCredentialsError) as excinfo:
_default._load_credentials_from_file(str(jsonfile))
- assert excinfo.match(r'not a valid json file')
+ assert excinfo.match(r"not a valid json file")
def test__load_credentials_from_file_invalid_type(tmpdir):
- jsonfile = tmpdir.join('invalid.json')
- jsonfile.write(json.dumps({'type': 'not-a-real-type'}))
+ jsonfile = tmpdir.join("invalid.json")
+ jsonfile.write(json.dumps({"type": "not-a-real-type"}))
with pytest.raises(exceptions.DefaultCredentialsError) as excinfo:
_default._load_credentials_from_file(str(jsonfile))
- assert excinfo.match(r'does not have a valid type')
+ assert excinfo.match(r"does not have a valid type")
def test__load_credentials_from_file_authorized_user():
- credentials, project_id = _default._load_credentials_from_file(
- AUTHORIZED_USER_FILE)
+ credentials, project_id = _default._load_credentials_from_file(AUTHORIZED_USER_FILE)
assert isinstance(credentials, google.oauth2.credentials.Credentials)
assert project_id is None
def test__load_credentials_from_file_authorized_user_bad_format(tmpdir):
- filename = tmpdir.join('authorized_user_bad.json')
- filename.write(json.dumps({'type': 'authorized_user'}))
+ filename = tmpdir.join("authorized_user_bad.json")
+ filename.write(json.dumps({"type": "authorized_user"}))
with pytest.raises(exceptions.DefaultCredentialsError) as excinfo:
_default._load_credentials_from_file(str(filename))
- assert excinfo.match(r'Failed to load authorized user')
- assert excinfo.match(r'missing fields')
+ assert excinfo.match(r"Failed to load authorized user")
+ assert excinfo.match(r"missing fields")
def test__load_credentials_from_file_authorized_user_cloud_sdk():
- with pytest.warns(UserWarning, match='Cloud SDK'):
+ with pytest.warns(UserWarning, match="Cloud SDK"):
credentials, project_id = _default._load_credentials_from_file(
- AUTHORIZED_USER_CLOUD_SDK_FILE)
+ AUTHORIZED_USER_CLOUD_SDK_FILE
+ )
assert isinstance(credentials, google.oauth2.credentials.Credentials)
assert project_id is None
def test__load_credentials_from_file_service_account():
- credentials, project_id = _default._load_credentials_from_file(
- SERVICE_ACCOUNT_FILE)
+ credentials, project_id = _default._load_credentials_from_file(SERVICE_ACCOUNT_FILE)
assert isinstance(credentials, service_account.Credentials)
- assert project_id == SERVICE_ACCOUNT_FILE_DATA['project_id']
+ assert project_id == SERVICE_ACCOUNT_FILE_DATA["project_id"]
def test__load_credentials_from_file_service_account_bad_format(tmpdir):
- filename = tmpdir.join('serivce_account_bad.json')
- filename.write(json.dumps({'type': 'service_account'}))
+ filename = tmpdir.join("serivce_account_bad.json")
+ filename.write(json.dumps({"type": "service_account"}))
with pytest.raises(exceptions.DefaultCredentialsError) as excinfo:
_default._load_credentials_from_file(str(filename))
- assert excinfo.match(r'Failed to load service account')
- assert excinfo.match(r'missing fields')
+ assert excinfo.match(r"Failed to load service account")
+ assert excinfo.match(r"missing fields")
@mock.patch.dict(os.environ, {}, clear=True)
@@ -124,19 +126,19 @@
@LOAD_FILE_PATCH
def test__get_explicit_environ_credentials(load, monkeypatch):
- monkeypatch.setenv(environment_vars.CREDENTIALS, 'filename')
+ monkeypatch.setenv(environment_vars.CREDENTIALS, "filename")
credentials, project_id = _default._get_explicit_environ_credentials()
assert credentials is mock.sentinel.credentials
assert project_id is mock.sentinel.project_id
- load.assert_called_with('filename')
+ load.assert_called_with("filename")
@LOAD_FILE_PATCH
def test__get_explicit_environ_credentials_no_project_id(load, monkeypatch):
load.return_value = mock.sentinel.credentials, None
- monkeypatch.setenv(environment_vars.CREDENTIALS, 'filename')
+ monkeypatch.setenv(environment_vars.CREDENTIALS, "filename")
credentials, project_id = _default._get_explicit_environ_credentials()
@@ -146,8 +148,8 @@
@LOAD_FILE_PATCH
@mock.patch(
- 'google.auth._cloud_sdk.get_application_default_credentials_path',
- autospec=True)
+ "google.auth._cloud_sdk.get_application_default_credentials_path", autospec=True
+)
def test__get_gcloud_sdk_credentials(get_adc_path, load):
get_adc_path.return_value = SERVICE_ACCOUNT_FILE
@@ -159,10 +161,10 @@
@mock.patch(
- 'google.auth._cloud_sdk.get_application_default_credentials_path',
- autospec=True)
+ "google.auth._cloud_sdk.get_application_default_credentials_path", autospec=True
+)
def test__get_gcloud_sdk_credentials_non_existent(get_adc_path, tmpdir):
- non_existent = tmpdir.join('non-existent')
+ non_existent = tmpdir.join("non-existent")
get_adc_path.return_value = str(non_existent)
credentials, project_id = _default._get_gcloud_sdk_credentials()
@@ -172,12 +174,13 @@
@mock.patch(
- 'google.auth._cloud_sdk.get_project_id',
- return_value=mock.sentinel.project_id, autospec=True)
-@mock.patch('os.path.isfile', return_value=True, autospec=True)
+ "google.auth._cloud_sdk.get_project_id",
+ return_value=mock.sentinel.project_id,
+ autospec=True,
+)
+@mock.patch("os.path.isfile", return_value=True, autospec=True)
@LOAD_FILE_PATCH
-def test__get_gcloud_sdk_credentials_project_id(
- load, unused_isfile, get_project_id):
+def test__get_gcloud_sdk_credentials_project_id(load, unused_isfile, get_project_id):
# Don't return a project ID from load file, make the function check
# the Cloud SDK project.
load.return_value = mock.sentinel.credentials, None
@@ -189,13 +192,10 @@
assert get_project_id.called
-@mock.patch(
- 'google.auth._cloud_sdk.get_project_id',
- return_value=None, autospec=True)
-@mock.patch('os.path.isfile', return_value=True)
+@mock.patch("google.auth._cloud_sdk.get_project_id", return_value=None, autospec=True)
+@mock.patch("os.path.isfile", return_value=True)
@LOAD_FILE_PATCH
-def test__get_gcloud_sdk_credentials_no_project_id(
- load, unused_isfile, get_project_id):
+def test__get_gcloud_sdk_credentials_no_project_id(load, unused_isfile, get_project_id):
# Don't return a project ID from load file, make the function check
# the Cloud SDK project.
load.return_value = mock.sentinel.credentials, None
@@ -212,6 +212,7 @@
See https://cloud.google.com/appengine/docs/standard/python/refdocs\
/google.appengine.api.app_identity.app_identity
"""
+
def get_application_id(self):
raise NotImplementedError()
@@ -219,10 +220,8 @@
@pytest.fixture
def app_identity(monkeypatch):
"""Mocks the app_identity module for google.auth.app_engine."""
- app_identity_module = mock.create_autospec(
- _AppIdentityModule, instance=True)
- monkeypatch.setattr(
- app_engine, 'app_identity', app_identity_module)
+ app_identity_module = mock.create_autospec(_AppIdentityModule, instance=True)
+ monkeypatch.setattr(app_engine, "app_identity", app_identity_module)
yield app_identity_module
@@ -237,8 +236,9 @@
def test__get_gae_credentials_no_app_engine():
import sys
- with mock.patch.dict('sys.modules'):
- sys.modules['google.auth.app_engine'] = None
+
+ with mock.patch.dict("sys.modules"):
+ sys.modules["google.auth.app_engine"] = None
credentials, project_id = _default._get_gae_credentials()
assert credentials is None
assert project_id is None
@@ -249,21 +249,23 @@
@mock.patch(
- 'google.auth.compute_engine._metadata.ping', return_value=True,
- autospec=True)
+ "google.auth.compute_engine._metadata.ping", return_value=True, autospec=True
+)
@mock.patch(
- 'google.auth.compute_engine._metadata.get_project_id',
- return_value='example-project', autospec=True)
+ "google.auth.compute_engine._metadata.get_project_id",
+ return_value="example-project",
+ autospec=True,
+)
def test__get_gce_credentials(unused_get, unused_ping):
credentials, project_id = _default._get_gce_credentials()
assert isinstance(credentials, compute_engine.Credentials)
- assert project_id == 'example-project'
+ assert project_id == "example-project"
@mock.patch(
- 'google.auth.compute_engine._metadata.ping', return_value=False,
- autospec=True)
+ "google.auth.compute_engine._metadata.ping", return_value=False, autospec=True
+)
def test__get_gce_credentials_no_ping(unused_ping):
credentials, project_id = _default._get_gce_credentials()
@@ -272,11 +274,13 @@
@mock.patch(
- 'google.auth.compute_engine._metadata.ping', return_value=True,
- autospec=True)
+ "google.auth.compute_engine._metadata.ping", return_value=True, autospec=True
+)
@mock.patch(
- 'google.auth.compute_engine._metadata.get_project_id',
- side_effect=exceptions.TransportError(), autospec=True)
+ "google.auth.compute_engine._metadata.get_project_id",
+ side_effect=exceptions.TransportError(),
+ autospec=True,
+)
def test__get_gce_credentials_no_project_id(unused_get, unused_ping):
credentials, project_id = _default._get_gce_credentials()
@@ -286,110 +290,125 @@
def test__get_gce_credentials_no_compute_engine():
import sys
- with mock.patch.dict('sys.modules'):
- sys.modules['google.auth.compute_engine'] = None
+
+ with mock.patch.dict("sys.modules"):
+ sys.modules["google.auth.compute_engine"] = None
credentials, project_id = _default._get_gce_credentials()
assert credentials is None
assert project_id is None
@mock.patch(
- 'google.auth.compute_engine._metadata.ping', return_value=False,
- autospec=True)
+ "google.auth.compute_engine._metadata.ping", return_value=False, autospec=True
+)
def test__get_gce_credentials_explicit_request(ping):
_default._get_gce_credentials(mock.sentinel.request)
ping.assert_called_with(request=mock.sentinel.request)
@mock.patch(
- 'google.auth._default._get_explicit_environ_credentials',
+ "google.auth._default._get_explicit_environ_credentials",
return_value=(mock.sentinel.credentials, mock.sentinel.project_id),
- autospec=True)
+ autospec=True,
+)
def test_default_early_out(unused_get):
- assert _default.default() == (
- mock.sentinel.credentials, mock.sentinel.project_id)
+ assert _default.default() == (mock.sentinel.credentials, mock.sentinel.project_id)
@mock.patch(
- 'google.auth._default._get_explicit_environ_credentials',
+ "google.auth._default._get_explicit_environ_credentials",
return_value=(mock.sentinel.credentials, mock.sentinel.project_id),
- autospec=True)
+ autospec=True,
+)
def test_default_explict_project_id(unused_get, monkeypatch):
- monkeypatch.setenv(environment_vars.PROJECT, 'explicit-env')
- assert _default.default() == (
- mock.sentinel.credentials, 'explicit-env')
+ monkeypatch.setenv(environment_vars.PROJECT, "explicit-env")
+ assert _default.default() == (mock.sentinel.credentials, "explicit-env")
@mock.patch(
- 'google.auth._default._get_explicit_environ_credentials',
+ "google.auth._default._get_explicit_environ_credentials",
return_value=(mock.sentinel.credentials, mock.sentinel.project_id),
- autospec=True)
+ autospec=True,
+)
def test_default_explict_legacy_project_id(unused_get, monkeypatch):
- monkeypatch.setenv(environment_vars.LEGACY_PROJECT, 'explicit-env')
- assert _default.default() == (
- mock.sentinel.credentials, 'explicit-env')
+ monkeypatch.setenv(environment_vars.LEGACY_PROJECT, "explicit-env")
+ assert _default.default() == (mock.sentinel.credentials, "explicit-env")
+@mock.patch("logging.Logger.warning", autospec=True)
@mock.patch(
- 'logging.Logger.warning',
- autospec=True)
+ "google.auth._default._get_explicit_environ_credentials",
+ return_value=(mock.sentinel.credentials, None),
+ autospec=True,
+)
@mock.patch(
- 'google.auth._default._get_explicit_environ_credentials',
- return_value=(mock.sentinel.credentials, None), autospec=True)
+ "google.auth._default._get_gcloud_sdk_credentials",
+ return_value=(mock.sentinel.credentials, None),
+ autospec=True,
+)
@mock.patch(
- 'google.auth._default._get_gcloud_sdk_credentials',
- return_value=(mock.sentinel.credentials, None), autospec=True)
+ "google.auth._default._get_gae_credentials",
+ return_value=(mock.sentinel.credentials, None),
+ autospec=True,
+)
@mock.patch(
- 'google.auth._default._get_gae_credentials',
- return_value=(mock.sentinel.credentials, None), autospec=True)
-@mock.patch(
- 'google.auth._default._get_gce_credentials',
- return_value=(mock.sentinel.credentials, None), autospec=True)
+ "google.auth._default._get_gce_credentials",
+ return_value=(mock.sentinel.credentials, None),
+ autospec=True,
+)
def test_default_without_project_id(
- unused_gce, unused_gae, unused_sdk, unused_explicit, logger_warning):
- assert _default.default() == (
- mock.sentinel.credentials, None)
+ unused_gce, unused_gae, unused_sdk, unused_explicit, logger_warning
+):
+ assert _default.default() == (mock.sentinel.credentials, None)
logger_warning.assert_called_with(mock.ANY, mock.ANY, mock.ANY)
@mock.patch(
- 'google.auth._default._get_explicit_environ_credentials',
- return_value=(None, None), autospec=True)
+ "google.auth._default._get_explicit_environ_credentials",
+ return_value=(None, None),
+ autospec=True,
+)
@mock.patch(
- 'google.auth._default._get_gcloud_sdk_credentials',
- return_value=(None, None), autospec=True)
+ "google.auth._default._get_gcloud_sdk_credentials",
+ return_value=(None, None),
+ autospec=True,
+)
@mock.patch(
- 'google.auth._default._get_gae_credentials',
- return_value=(None, None), autospec=True)
+ "google.auth._default._get_gae_credentials",
+ return_value=(None, None),
+ autospec=True,
+)
@mock.patch(
- 'google.auth._default._get_gce_credentials',
- return_value=(None, None), autospec=True)
+ "google.auth._default._get_gce_credentials",
+ return_value=(None, None),
+ autospec=True,
+)
def test_default_fail(unused_gce, unused_gae, unused_sdk, unused_explicit):
with pytest.raises(exceptions.DefaultCredentialsError):
assert _default.default()
@mock.patch(
- 'google.auth._default._get_explicit_environ_credentials',
+ "google.auth._default._get_explicit_environ_credentials",
return_value=(mock.sentinel.credentials, mock.sentinel.project_id),
- autospec=True)
-@mock.patch(
- 'google.auth.credentials.with_scopes_if_required', autospec=True)
+ autospec=True,
+)
+@mock.patch("google.auth.credentials.with_scopes_if_required", autospec=True)
def test_default_scoped(with_scopes, unused_get):
- scopes = ['one', 'two']
+ scopes = ["one", "two"]
credentials, project_id = _default.default(scopes=scopes)
assert credentials == with_scopes.return_value
assert project_id == mock.sentinel.project_id
- with_scopes.assert_called_once_with(
- mock.sentinel.credentials, scopes)
+ with_scopes.assert_called_once_with(mock.sentinel.credentials, scopes)
@mock.patch(
- 'google.auth._default._get_explicit_environ_credentials',
+ "google.auth._default._get_explicit_environ_credentials",
return_value=(mock.sentinel.credentials, mock.sentinel.project_id),
- autospec=True)
+ autospec=True,
+)
def test_default_no_app_engine_compute_engine_module(unused_get):
"""
google.auth.compute_engine and google.auth.app_engine are both optional
@@ -397,8 +416,11 @@
that default fails gracefully if these modules are absent
"""
import sys
- with mock.patch.dict('sys.modules'):
- sys.modules['google.auth.compute_engine'] = None
- sys.modules['google.auth.app_engine'] = None
+
+ with mock.patch.dict("sys.modules"):
+ sys.modules["google.auth.compute_engine"] = None
+ sys.modules["google.auth.app_engine"] = None
assert _default.default() == (
- mock.sentinel.credentials, mock.sentinel.project_id)
+ mock.sentinel.credentials,
+ mock.sentinel.project_id,
+ )
diff --git a/tests/test__helpers.py b/tests/test__helpers.py
index 79bdef3..3714af7 100644
--- a/tests/test__helpers.py
+++ b/tests/test__helpers.py
@@ -56,20 +56,18 @@
def test_datetime_to_secs():
- assert _helpers.datetime_to_secs(
- datetime.datetime(1970, 1, 1)) == 0
- assert _helpers.datetime_to_secs(
- datetime.datetime(1990, 5, 29)) == 643939200
+ assert _helpers.datetime_to_secs(datetime.datetime(1970, 1, 1)) == 0
+ assert _helpers.datetime_to_secs(datetime.datetime(1990, 5, 29)) == 643939200
def test_to_bytes_with_bytes():
- value = b'bytes-val'
+ value = b"bytes-val"
assert _helpers.to_bytes(value) == value
def test_to_bytes_with_unicode():
- value = u'string-val'
- encoded_value = b'string-val'
+ value = u"string-val"
+ encoded_value = b"string-val"
assert _helpers.to_bytes(value) == encoded_value
@@ -79,13 +77,13 @@
def test_from_bytes_with_unicode():
- value = u'bytes-val'
+ value = u"bytes-val"
assert _helpers.from_bytes(value) == value
def test_from_bytes_with_bytes():
- value = b'string-val'
- decoded_value = u'string-val'
+ value = b"string-val"
+ decoded_value = u"string-val"
assert _helpers.from_bytes(value) == decoded_value
@@ -101,53 +99,49 @@
def test_update_query_params_no_params():
- uri = 'http://www.google.com'
- updated = _helpers.update_query(uri, {'a': 'b'})
- assert updated == uri + '?a=b'
+ uri = "http://www.google.com"
+ updated = _helpers.update_query(uri, {"a": "b"})
+ assert updated == uri + "?a=b"
def test_update_query_existing_params():
- uri = 'http://www.google.com?x=y'
- updated = _helpers.update_query(uri, {'a': 'b', 'c': 'd&'})
- _assert_query(updated, {'x': ['y'], 'a': ['b'], 'c': ['d&']})
+ uri = "http://www.google.com?x=y"
+ updated = _helpers.update_query(uri, {"a": "b", "c": "d&"})
+ _assert_query(updated, {"x": ["y"], "a": ["b"], "c": ["d&"]})
def test_update_query_replace_param():
- base_uri = 'http://www.google.com'
- uri = base_uri + '?x=a'
- updated = _helpers.update_query(uri, {'x': 'b', 'y': 'c'})
- _assert_query(updated, {'x': ['b'], 'y': ['c']})
+ base_uri = "http://www.google.com"
+ uri = base_uri + "?x=a"
+ updated = _helpers.update_query(uri, {"x": "b", "y": "c"})
+ _assert_query(updated, {"x": ["b"], "y": ["c"]})
def test_update_query_remove_param():
- base_uri = 'http://www.google.com'
- uri = base_uri + '?x=a'
- updated = _helpers.update_query(uri, {'y': 'c'}, remove=['x'])
- _assert_query(updated, {'y': ['c']})
+ base_uri = "http://www.google.com"
+ uri = base_uri + "?x=a"
+ updated = _helpers.update_query(uri, {"y": "c"}, remove=["x"])
+ _assert_query(updated, {"y": ["c"]})
def test_scopes_to_string():
cases = [
- ('', ()),
- ('', []),
- ('', ('',)),
- ('', ['', ]),
- ('a', ('a',)),
- ('b', ['b', ]),
- ('a b', ['a', 'b']),
- ('a b', ('a', 'b')),
- ('a b', (s for s in ['a', 'b'])),
+ ("", ()),
+ ("", []),
+ ("", ("",)),
+ ("", [""]),
+ ("a", ("a",)),
+ ("b", ["b"]),
+ ("a b", ["a", "b"]),
+ ("a b", ("a", "b")),
+ ("a b", (s for s in ["a", "b"])),
]
for expected, case in cases:
assert _helpers.scopes_to_string(case) == expected
def test_string_to_scopes():
- cases = [
- ('', []),
- ('a', ['a']),
- ('a b c d e f', ['a', 'b', 'c', 'd', 'e', 'f']),
- ]
+ cases = [("", []), ("a", ["a"]), ("a b c d e f", ["a", "b", "c", "d", "e", "f"])]
for case, expected in cases:
assert _helpers.string_to_scopes(case) == expected
@@ -155,14 +149,14 @@
def test_padded_urlsafe_b64decode():
cases = [
- ('YQ==', b'a'),
- ('YQ', b'a'),
- ('YWE=', b'aa'),
- ('YWE', b'aa'),
- ('YWFhYQ==', b'aaaa'),
- ('YWFhYQ', b'aaaa'),
- ('YWFhYWE=', b'aaaaa'),
- ('YWFhYWE', b'aaaaa'),
+ ("YQ==", b"a"),
+ ("YQ", b"a"),
+ ("YWE=", b"aa"),
+ ("YWE", b"aa"),
+ ("YWFhYQ==", b"aaaa"),
+ ("YWFhYQ", b"aaaa"),
+ ("YWFhYWE=", b"aaaaa"),
+ ("YWFhYWE", b"aaaaa"),
]
for case, expected in cases:
@@ -170,12 +164,7 @@
def test_unpadded_urlsafe_b64encode():
- cases = [
- (b'', b''),
- (b'a', b'YQ'),
- (b'aa', b'YWE'),
- (b'aaa', b'YWFh'),
- ]
+ cases = [(b"", b""), (b"a", b"YQ"), (b"aa", b"YWE"), (b"aaa", b"YWFh")]
for case, expected in cases:
assert _helpers.unpadded_urlsafe_b64encode(case) == expected
diff --git a/tests/test__oauth2client.py b/tests/test__oauth2client.py
index 832b24f..520f943 100644
--- a/tests/test__oauth2client.py
+++ b/tests/test__oauth2client.py
@@ -26,17 +26,23 @@
from google.auth import _oauth2client
-DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
-SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, 'service_account.json')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
+SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
def test__convert_oauth2_credentials():
old_credentials = oauth2client.client.OAuth2Credentials(
- 'access_token', 'client_id', 'client_secret', 'refresh_token',
- datetime.datetime.min, 'token_uri', 'user_agent', scopes='one two')
+ "access_token",
+ "client_id",
+ "client_secret",
+ "refresh_token",
+ datetime.datetime.min,
+ "token_uri",
+ "user_agent",
+ scopes="one two",
+ )
- new_credentials = _oauth2client._convert_oauth2_credentials(
- old_credentials)
+ new_credentials = _oauth2client._convert_oauth2_credentials(old_credentials)
assert new_credentials.token == old_credentials.access_token
assert new_credentials._refresh_token == old_credentials.refresh_token
@@ -48,68 +54,74 @@
def test__convert_service_account_credentials():
old_class = oauth2client.service_account.ServiceAccountCredentials
- old_credentials = old_class.from_json_keyfile_name(
- SERVICE_ACCOUNT_JSON_FILE)
+ old_credentials = old_class.from_json_keyfile_name(SERVICE_ACCOUNT_JSON_FILE)
new_credentials = _oauth2client._convert_service_account_credentials(
- old_credentials)
+ old_credentials
+ )
- assert (new_credentials.service_account_email ==
- old_credentials.service_account_email)
+ assert (
+ new_credentials.service_account_email == old_credentials.service_account_email
+ )
assert new_credentials._signer.key_id == old_credentials._private_key_id
assert new_credentials._token_uri == old_credentials.token_uri
def test__convert_service_account_credentials_with_jwt():
old_class = oauth2client.service_account._JWTAccessCredentials
- old_credentials = old_class.from_json_keyfile_name(
- SERVICE_ACCOUNT_JSON_FILE)
+ old_credentials = old_class.from_json_keyfile_name(SERVICE_ACCOUNT_JSON_FILE)
new_credentials = _oauth2client._convert_service_account_credentials(
- old_credentials)
+ old_credentials
+ )
- assert (new_credentials.service_account_email ==
- old_credentials.service_account_email)
+ assert (
+ new_credentials.service_account_email == old_credentials.service_account_email
+ )
assert new_credentials._signer.key_id == old_credentials._private_key_id
assert new_credentials._token_uri == old_credentials.token_uri
def test__convert_gce_app_assertion_credentials():
old_credentials = oauth2client.contrib.gce.AppAssertionCredentials(
- email='some_email')
+ email="some_email"
+ )
new_credentials = _oauth2client._convert_gce_app_assertion_credentials(
- old_credentials)
+ old_credentials
+ )
- assert (new_credentials.service_account_email ==
- old_credentials.service_account_email)
+ assert (
+ new_credentials.service_account_email == old_credentials.service_account_email
+ )
@pytest.fixture
def mock_oauth2client_gae_imports(mock_non_existent_module):
- mock_non_existent_module('google.appengine.api.app_identity')
- mock_non_existent_module('google.appengine.ext.ndb')
- mock_non_existent_module('google.appengine.ext.webapp.util')
- mock_non_existent_module('webapp2')
+ mock_non_existent_module("google.appengine.api.app_identity")
+ mock_non_existent_module("google.appengine.ext.ndb")
+ mock_non_existent_module("google.appengine.ext.webapp.util")
+ mock_non_existent_module("webapp2")
-@mock.patch('google.auth.app_engine.app_identity')
+@mock.patch("google.auth.app_engine.app_identity")
def test__convert_appengine_app_assertion_credentials(
- app_identity, mock_oauth2client_gae_imports):
+ app_identity, mock_oauth2client_gae_imports
+):
import oauth2client.contrib.appengine
- service_account_id = 'service_account_id'
+ service_account_id = "service_account_id"
old_credentials = oauth2client.contrib.appengine.AppAssertionCredentials(
- scope='one two', service_account_id=service_account_id)
+ scope="one two", service_account_id=service_account_id
+ )
- new_credentials = (
- _oauth2client._convert_appengine_app_assertion_credentials(
- old_credentials))
+ new_credentials = _oauth2client._convert_appengine_app_assertion_credentials(
+ old_credentials
+ )
- assert new_credentials.scopes == ['one', 'two']
- assert (new_credentials._service_account_id ==
- old_credentials.service_account_id)
+ assert new_credentials.scopes == ["one", "two"]
+ assert new_credentials._service_account_id == old_credentials.service_account_id
class FakeCredentials(object):
@@ -117,10 +129,10 @@
def test_convert_success():
- convert_function = mock.Mock(spec=['__call__'])
+ convert_function = mock.Mock(spec=["__call__"])
conversion_map_patch = mock.patch.object(
- _oauth2client, '_CLASS_CONVERSION_MAP',
- {FakeCredentials: convert_function})
+ _oauth2client, "_CLASS_CONVERSION_MAP", {FakeCredentials: convert_function}
+ )
credentials = FakeCredentials()
with conversion_map_patch:
@@ -132,9 +144,9 @@
def test_convert_not_found():
with pytest.raises(ValueError) as excinfo:
- _oauth2client.convert('a string is not a real credentials class')
+ _oauth2client.convert("a string is not a real credentials class")
- assert excinfo.match('Unable to convert')
+ assert excinfo.match("Unable to convert")
@pytest.fixture
@@ -144,14 +156,15 @@
def test_import_has_app_engine(
- mock_oauth2client_gae_imports, reset__oauth2client_module):
+ mock_oauth2client_gae_imports, reset__oauth2client_module
+):
reload_module(_oauth2client)
assert _oauth2client._HAS_APPENGINE
def test_import_without_oauth2client(monkeypatch, reset__oauth2client_module):
- monkeypatch.setitem(sys.modules, 'oauth2client', None)
+ monkeypatch.setitem(sys.modules, "oauth2client", None)
with pytest.raises(ImportError) as excinfo:
reload_module(_oauth2client)
- assert excinfo.match('oauth2client')
+ assert excinfo.match("oauth2client")
diff --git a/tests/test__service_account_info.py b/tests/test__service_account_info.py
index ef41e27..4419f67 100644
--- a/tests/test__service_account_info.py
+++ b/tests/test__service_account_info.py
@@ -22,42 +22,41 @@
from google.auth import crypt
-DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
-SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, 'service_account.json')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
+SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
-with open(SERVICE_ACCOUNT_JSON_FILE, 'r') as fh:
+with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
SERVICE_ACCOUNT_INFO = json.load(fh)
def test_from_dict():
signer = _service_account_info.from_dict(SERVICE_ACCOUNT_INFO)
assert isinstance(signer, crypt.RSASigner)
- assert signer.key_id == SERVICE_ACCOUNT_INFO['private_key_id']
+ assert signer.key_id == SERVICE_ACCOUNT_INFO["private_key_id"]
def test_from_dict_bad_private_key():
info = SERVICE_ACCOUNT_INFO.copy()
- info['private_key'] = 'garbage'
+ info["private_key"] = "garbage"
with pytest.raises(ValueError) as excinfo:
_service_account_info.from_dict(info)
- assert excinfo.match(r'key')
+ assert excinfo.match(r"key")
def test_from_dict_bad_format():
with pytest.raises(ValueError) as excinfo:
- _service_account_info.from_dict({}, require=('meep',))
+ _service_account_info.from_dict({}, require=("meep",))
- assert excinfo.match(r'missing fields')
+ assert excinfo.match(r"missing fields")
def test_from_filename():
- info, signer = _service_account_info.from_filename(
- SERVICE_ACCOUNT_JSON_FILE)
+ info, signer = _service_account_info.from_filename(SERVICE_ACCOUNT_JSON_FILE)
for key, value in six.iteritems(SERVICE_ACCOUNT_INFO):
assert info[key] == value
assert isinstance(signer, crypt.RSASigner)
- assert signer.key_id == SERVICE_ACCOUNT_INFO['private_key_id']
+ assert signer.key_id == SERVICE_ACCOUNT_INFO["private_key_id"]
diff --git a/tests/test_app_engine.py b/tests/test_app_engine.py
index 70fa5ca..9559a2c 100644
--- a/tests/test_app_engine.py
+++ b/tests/test_app_engine.py
@@ -25,6 +25,7 @@
See https://cloud.google.com/appengine/docs/standard/python/refdocs
/google.appengine.api.app_identity.app_identity
"""
+
def get_application_id(self):
raise NotImplementedError()
@@ -41,10 +42,8 @@
@pytest.fixture
def app_identity(monkeypatch):
"""Mocks the app_identity module for google.auth.app_engine."""
- app_identity_module = mock.create_autospec(
- _AppIdentityModule, instance=True)
- monkeypatch.setattr(
- app_engine, 'app_identity', app_identity_module)
+ app_identity_module = mock.create_autospec(_AppIdentityModule, instance=True)
+ monkeypatch.setattr(app_engine, "app_identity", app_identity_module)
yield app_identity_module
@@ -57,13 +56,15 @@
with pytest.raises(EnvironmentError) as excinfo:
assert app_engine.get_project_id()
- assert excinfo.match(r'App Engine APIs are not available')
+ assert excinfo.match(r"App Engine APIs are not available")
class TestSigner(object):
def test_key_id(self, app_identity):
app_identity.sign_blob.return_value = (
- mock.sentinel.key_id, mock.sentinel.signature)
+ mock.sentinel.key_id,
+ mock.sentinel.signature,
+ )
signer = app_engine.Signer()
@@ -71,10 +72,12 @@
def test_sign(self, app_identity):
app_identity.sign_blob.return_value = (
- mock.sentinel.key_id, mock.sentinel.signature)
+ mock.sentinel.key_id,
+ mock.sentinel.signature,
+ )
signer = app_engine.Signer()
- to_sign = b'123'
+ to_sign = b"123"
signature = signer.sign(to_sign)
@@ -87,7 +90,7 @@
with pytest.raises(EnvironmentError) as excinfo:
app_engine.Credentials()
- assert excinfo.match(r'App Engine APIs are not available')
+ assert excinfo.match(r"App Engine APIs are not available")
def test_default_state(self, app_identity):
credentials = app_engine.Credentials()
@@ -106,52 +109,52 @@
assert not credentials.scopes
assert credentials.requires_scopes
- scoped_credentials = credentials.with_scopes(['email'])
+ scoped_credentials = credentials.with_scopes(["email"])
- assert scoped_credentials.has_scopes(['email'])
+ assert scoped_credentials.has_scopes(["email"])
assert not scoped_credentials.requires_scopes
def test_service_account_email_implicit(self, app_identity):
app_identity.get_service_account_name.return_value = (
- mock.sentinel.service_account_email)
+ mock.sentinel.service_account_email
+ )
credentials = app_engine.Credentials()
- assert (credentials.service_account_email ==
- mock.sentinel.service_account_email)
+ assert credentials.service_account_email == mock.sentinel.service_account_email
assert app_identity.get_service_account_name.called
def test_service_account_email_explicit(self, app_identity):
credentials = app_engine.Credentials(
- service_account_id=mock.sentinel.service_account_email)
+ service_account_id=mock.sentinel.service_account_email
+ )
- assert (credentials.service_account_email ==
- mock.sentinel.service_account_email)
+ assert credentials.service_account_email == mock.sentinel.service_account_email
assert not app_identity.get_service_account_name.called
- @mock.patch(
- 'google.auth._helpers.utcnow',
- return_value=datetime.datetime.min)
+ @mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
def test_refresh(self, utcnow, app_identity):
- token = 'token'
+ token = "token"
ttl = 643942923
app_identity.get_access_token.return_value = token, ttl
- credentials = app_engine.Credentials(scopes=['email'])
+ credentials = app_engine.Credentials(scopes=["email"])
credentials.refresh(None)
app_identity.get_access_token.assert_called_with(
- credentials.scopes, credentials._service_account_id)
+ credentials.scopes, credentials._service_account_id
+ )
assert credentials.token == token
- assert credentials.expiry == datetime.datetime(
- 1990, 5, 29, 1, 2, 3)
+ assert credentials.expiry == datetime.datetime(1990, 5, 29, 1, 2, 3)
assert credentials.valid
assert not credentials.expired
def test_sign_bytes(self, app_identity):
app_identity.sign_blob.return_value = (
- mock.sentinel.key_id, mock.sentinel.signature)
+ mock.sentinel.key_id,
+ mock.sentinel.signature,
+ )
credentials = app_engine.Credentials()
- to_sign = b'123'
+ to_sign = b"123"
signature = credentials.sign_bytes(to_sign)
diff --git a/tests/test_credentials.py b/tests/test_credentials.py
index b302989..2a89b01 100644
--- a/tests/test_credentials.py
+++ b/tests/test_credentials.py
@@ -35,7 +35,7 @@
def test_expired_and_valid():
credentials = CredentialsImpl()
- credentials.token = 'token'
+ credentials.token = "token"
assert credentials.valid
assert not credentials.expired
@@ -43,9 +43,8 @@
# Set the expiration to one second more than now plus the clock skew
# accomodation. These credentials should be valid.
credentials.expiry = (
- datetime.datetime.utcnow() +
- _helpers.CLOCK_SKEW +
- datetime.timedelta(seconds=1))
+ datetime.datetime.utcnow() + _helpers.CLOCK_SKEW + datetime.timedelta(seconds=1)
+ )
assert credentials.valid
assert not credentials.expired
@@ -60,23 +59,23 @@
def test_before_request():
credentials = CredentialsImpl()
- request = 'token'
+ request = "token"
headers = {}
# First call should call refresh, setting the token.
- credentials.before_request(request, 'http://example.com', 'GET', headers)
+ credentials.before_request(request, "http://example.com", "GET", headers)
assert credentials.valid
- assert credentials.token == 'token'
- assert headers['authorization'] == 'Bearer token'
+ assert credentials.token == "token"
+ assert headers["authorization"] == "Bearer token"
- request = 'token2'
+ request = "token2"
headers = {}
# Second call shouldn't call refresh.
- credentials.before_request(request, 'http://example.com', 'GET', headers)
+ credentials.before_request(request, "http://example.com", "GET", headers)
assert credentials.valid
- assert credentials.token == 'token'
- assert headers['authorization'] == 'Bearer token'
+ assert credentials.token == "token"
+ assert headers["authorization"] == "Bearer token"
def test_anonymous_credentials_ctor():
@@ -100,21 +99,20 @@
anon.apply(headers)
assert headers == {}
with pytest.raises(ValueError):
- anon.apply(headers, token='TOKEN')
+ anon.apply(headers, token="TOKEN")
def test_anonymous_credentials_before_request():
anon = credentials.AnonymousCredentials()
request = object()
- method = 'GET'
- url = 'https://example.com/api/endpoint'
+ method = "GET"
+ url = "https://example.com/api/endpoint"
headers = {}
anon.before_request(request, method, url, headers)
assert headers == {}
-class ReadOnlyScopedCredentialsImpl(
- credentials.ReadOnlyScoped, CredentialsImpl):
+class ReadOnlyScopedCredentialsImpl(credentials.ReadOnlyScoped, CredentialsImpl):
@property
def requires_scopes(self):
return super(ReadOnlyScopedCredentialsImpl, self).requires_scopes
@@ -127,12 +125,12 @@
def test_readonly_scoped_credentials_scopes():
credentials = ReadOnlyScopedCredentialsImpl()
- credentials._scopes = ['one', 'two']
- assert credentials.scopes == ['one', 'two']
- assert credentials.has_scopes(['one'])
- assert credentials.has_scopes(['two'])
- assert credentials.has_scopes(['one', 'two'])
- assert not credentials.has_scopes(['three'])
+ credentials._scopes = ["one", "two"]
+ assert credentials.scopes == ["one", "two"]
+ assert credentials.has_scopes(["one"])
+ assert credentials.has_scopes(["two"])
+ assert credentials.has_scopes(["one", "two"])
+ assert not credentials.has_scopes(["three"])
def test_readonly_scoped_credentials_requires_scopes():
@@ -156,16 +154,18 @@
def test_create_scoped_if_required_scoped():
unscoped_credentials = RequiresScopedCredentialsImpl()
scoped_credentials = credentials.with_scopes_if_required(
- unscoped_credentials, ['one', 'two'])
+ unscoped_credentials, ["one", "two"]
+ )
assert scoped_credentials is not unscoped_credentials
assert not scoped_credentials.requires_scopes
- assert scoped_credentials.has_scopes(['one', 'two'])
+ assert scoped_credentials.has_scopes(["one", "two"])
def test_create_scoped_if_required_not_scopes():
unscoped_credentials = CredentialsImpl()
scoped_credentials = credentials.with_scopes_if_required(
- unscoped_credentials, ['one', 'two'])
+ unscoped_credentials, ["one", "two"]
+ )
assert scoped_credentials is unscoped_credentials
diff --git a/tests/test_iam.py b/tests/test_iam.py
index cc09085..52ab9bd 100644
--- a/tests/test_iam.py
+++ b/tests/test_iam.py
@@ -32,7 +32,7 @@
response.status = status
if data is not None:
- response.data = json.dumps(data).encode('utf-8')
+ response.data = json.dumps(data).encode("utf-8")
request = mock.create_autospec(transport.Request)
request.return_value = response
@@ -43,7 +43,7 @@
class CredentialsImpl(google.auth.credentials.Credentials):
def __init__(self):
super(CredentialsImpl, self).__init__()
- self.token = 'token'
+ self.token = "token"
# Force refresh
self.expiry = datetime.datetime.min + _helpers.CLOCK_SKEW
@@ -57,35 +57,33 @@
def test_constructor(self):
request = mock.sentinel.request
credentials = mock.create_autospec(
- google.auth.credentials.Credentials, instance=True)
+ google.auth.credentials.Credentials, instance=True
+ )
- signer = iam.Signer(
- request, credentials, mock.sentinel.service_account_email)
+ signer = iam.Signer(request, credentials, mock.sentinel.service_account_email)
assert signer._request == mock.sentinel.request
assert signer._credentials == credentials
- assert (signer._service_account_email ==
- mock.sentinel.service_account_email)
+ assert signer._service_account_email == mock.sentinel.service_account_email
def test_key_id(self):
signer = iam.Signer(
mock.sentinel.request,
mock.sentinel.credentials,
- mock.sentinel.service_account_email)
+ mock.sentinel.service_account_email,
+ )
assert signer.key_id is None
def test_sign_bytes(self):
- signature = b'DEADBEEF'
- encoded_signature = base64.b64encode(signature).decode('utf-8')
- request = make_request(
- http_client.OK, data={'signature': encoded_signature})
+ signature = b"DEADBEEF"
+ encoded_signature = base64.b64encode(signature).decode("utf-8")
+ request = make_request(http_client.OK, data={"signature": encoded_signature})
credentials = make_credentials()
- signer = iam.Signer(
- request, credentials, mock.sentinel.service_account_email)
+ signer = iam.Signer(request, credentials, mock.sentinel.service_account_email)
- returned_signature = signer.sign('123')
+ returned_signature = signer.sign("123")
assert returned_signature == signature
@@ -93,8 +91,7 @@
request = make_request(http_client.UNAUTHORIZED)
credentials = make_credentials()
- signer = iam.Signer(
- request, credentials, mock.sentinel.service_account_email)
+ signer = iam.Signer(request, credentials, mock.sentinel.service_account_email)
with pytest.raises(exceptions.TransportError):
- signer.sign('123')
+ signer.sign("123")
diff --git a/tests/test_impersonated_credentials.py b/tests/test_impersonated_credentials.py
index 9945401..1cfcc7c 100644
--- a/tests/test_impersonated_credentials.py
+++ b/tests/test_impersonated_credentials.py
@@ -28,35 +28,38 @@
from google.auth.impersonated_credentials import Credentials
from google.oauth2 import service_account
-DATA_DIR = os.path.join(os.path.dirname(__file__), '', 'data')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "", "data")
-with open(os.path.join(DATA_DIR, 'privatekey.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
-SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, 'service_account.json')
+SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
-ID_TOKEN_DATA = ('eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmMzc1ODkwOGI3OTIyOTNhZDk3N2Ew'
- 'Yjk5MWQ5OGE3N2Y0ZWVlY2QiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwc'
- 'zovL2Zvby5iYXIiLCJhenAiOiIxMDIxMDE1NTA4MzQyMDA3MDg1NjgiLCJle'
- 'HAiOjE1NjQ0NzUwNTEsImlhdCI6MTU2NDQ3MTQ1MSwiaXNzIjoiaHR0cHM6L'
- 'y9hY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTAyMTAxNTUwODM0MjAwN'
- 'zA4NTY4In0.redacted')
+ID_TOKEN_DATA = (
+ "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmMzc1ODkwOGI3OTIyOTNhZDk3N2Ew"
+ "Yjk5MWQ5OGE3N2Y0ZWVlY2QiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwc"
+ "zovL2Zvby5iYXIiLCJhenAiOiIxMDIxMDE1NTA4MzQyMDA3MDg1NjgiLCJle"
+ "HAiOjE1NjQ0NzUwNTEsImlhdCI6MTU2NDQ3MTQ1MSwiaXNzIjoiaHR0cHM6L"
+ "y9hY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTAyMTAxNTUwODM0MjAwN"
+ "zA4NTY4In0.redacted"
+)
ID_TOKEN_EXPIRY = 1564475051
-with open(SERVICE_ACCOUNT_JSON_FILE, 'r') as fh:
+with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
SERVICE_ACCOUNT_INFO = json.load(fh)
-SIGNER = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, '1')
-TOKEN_URI = 'https://example.com/oauth2/token'
+SIGNER = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, "1")
+TOKEN_URI = "https://example.com/oauth2/token"
@pytest.fixture
def mock_donor_credentials():
- with mock.patch('google.oauth2._client.jwt_grant', autospec=True) as grant:
+ with mock.patch("google.oauth2._client.jwt_grant", autospec=True) as grant:
grant.return_value = (
"source token",
_helpers.utcnow() + datetime.timedelta(seconds=500),
- {})
+ {},
+ )
yield grant
@@ -71,54 +74,51 @@
@pytest.fixture
def mock_authorizedsession_sign():
- with mock.patch('google.auth.transport.requests.AuthorizedSession.request',
- autospec=True) as auth_session:
- data = {
- "keyId": "1",
- "signedBlob": "c2lnbmF0dXJl"
- }
+ with mock.patch(
+ "google.auth.transport.requests.AuthorizedSession.request", autospec=True
+ ) as auth_session:
+ data = {"keyId": "1", "signedBlob": "c2lnbmF0dXJl"}
auth_session.return_value = MockResponse(data, http_client.OK)
yield auth_session
@pytest.fixture
def mock_authorizedsession_idtoken():
- with mock.patch('google.auth.transport.requests.AuthorizedSession.request',
- autospec=True) as auth_session:
- data = {
- "token": ID_TOKEN_DATA
- }
+ with mock.patch(
+ "google.auth.transport.requests.AuthorizedSession.request", autospec=True
+ ) as auth_session:
+ data = {"token": ID_TOKEN_DATA}
auth_session.return_value = MockResponse(data, http_client.OK)
yield auth_session
class TestImpersonatedCredentials(object):
- SERVICE_ACCOUNT_EMAIL = 'service-account@example.com'
- TARGET_PRINCIPAL = 'impersonated@project.iam.gserviceaccount.com'
- TARGET_SCOPES = ['https://www.googleapis.com/auth/devstorage.read_only']
+ SERVICE_ACCOUNT_EMAIL = "service-account@example.com"
+ TARGET_PRINCIPAL = "impersonated@project.iam.gserviceaccount.com"
+ TARGET_SCOPES = ["https://www.googleapis.com/auth/devstorage.read_only"]
DELEGATES = []
LIFETIME = 3600
SOURCE_CREDENTIALS = service_account.Credentials(
- SIGNER, SERVICE_ACCOUNT_EMAIL, TOKEN_URI)
+ SIGNER, SERVICE_ACCOUNT_EMAIL, TOKEN_URI
+ )
- def make_credentials(self, lifetime=LIFETIME,
- target_principal=TARGET_PRINCIPAL):
+ def make_credentials(self, lifetime=LIFETIME, target_principal=TARGET_PRINCIPAL):
return Credentials(
source_credentials=self.SOURCE_CREDENTIALS,
target_principal=target_principal,
target_scopes=self.TARGET_SCOPES,
delegates=self.DELEGATES,
- lifetime=lifetime)
+ lifetime=lifetime,
+ )
def test_default_state(self):
credentials = self.make_credentials()
assert not credentials.valid
assert credentials.expired
- def make_request(self, data, status=http_client.OK,
- headers=None, side_effect=None):
+ def make_request(self, data, status=http_client.OK, headers=None, side_effect=None):
response = mock.create_autospec(transport.Response, instance=False)
response.status = status
response.data = _helpers.to_bytes(data)
@@ -132,40 +132,34 @@
def test_refresh_success(self, mock_donor_credentials):
credentials = self.make_credentials(lifetime=None)
- token = 'token'
+ token = "token"
expire_time = (
- _helpers.utcnow().replace(microsecond=0) +
- datetime.timedelta(seconds=500)).isoformat('T') + 'Z'
- response_body = {
- "accessToken": token,
- "expireTime": expire_time
- }
+ _helpers.utcnow().replace(microsecond=0) + datetime.timedelta(seconds=500)
+ ).isoformat("T") + "Z"
+ response_body = {"accessToken": token, "expireTime": expire_time}
request = self.make_request(
- data=json.dumps(response_body),
- status=http_client.OK)
+ data=json.dumps(response_body), status=http_client.OK
+ )
credentials.refresh(request)
assert credentials.valid
assert not credentials.expired
- def test_refresh_failure_malformed_expire_time(
- self, mock_donor_credentials):
+ def test_refresh_failure_malformed_expire_time(self, mock_donor_credentials):
credentials = self.make_credentials(lifetime=None)
- token = 'token'
+ token = "token"
- expire_time = (
- _helpers.utcnow() + datetime.timedelta(seconds=500)).isoformat('T')
- response_body = {
- "accessToken": token,
- "expireTime": expire_time
- }
+ expire_time = (_helpers.utcnow() + datetime.timedelta(seconds=500)).isoformat(
+ "T"
+ )
+ response_body = {"accessToken": token, "expireTime": expire_time}
request = self.make_request(
- data=json.dumps(response_body),
- status=http_client.OK)
+ data=json.dumps(response_body), status=http_client.OK
+ )
with pytest.raises(exceptions.RefreshError) as excinfo:
credentials.refresh(request)
@@ -180,15 +174,15 @@
response_body = {
"error": {
- "code": 403,
- "message": "The caller does not have permission",
- "status": "PERMISSION_DENIED"
+ "code": 403,
+ "message": "The caller does not have permission",
+ "status": "PERMISSION_DENIED",
}
}
request = self.make_request(
- data=json.dumps(response_body),
- status=http_client.UNAUTHORIZED)
+ data=json.dumps(response_body), status=http_client.UNAUTHORIZED
+ )
with pytest.raises(exceptions.RefreshError) as excinfo:
credentials.refresh(request)
@@ -204,8 +198,8 @@
response_body = {}
request = self.make_request(
- data=json.dumps(response_body),
- status=http_client.HTTPException)
+ data=json.dumps(response_body), status=http_client.HTTPException
+ )
with pytest.raises(exceptions.RefreshError) as excinfo:
credentials.refresh(request)
@@ -221,31 +215,24 @@
def test_signer(self):
credentials = self.make_credentials()
- assert isinstance(credentials.signer,
- impersonated_credentials.Credentials)
+ assert isinstance(credentials.signer, impersonated_credentials.Credentials)
def test_signer_email(self):
- credentials = self.make_credentials(
- target_principal=self.TARGET_PRINCIPAL)
+ credentials = self.make_credentials(target_principal=self.TARGET_PRINCIPAL)
assert credentials.signer_email == self.TARGET_PRINCIPAL
def test_service_account_email(self):
- credentials = self.make_credentials(
- target_principal=self.TARGET_PRINCIPAL)
+ credentials = self.make_credentials(target_principal=self.TARGET_PRINCIPAL)
assert credentials.service_account_email == self.TARGET_PRINCIPAL
- def test_sign_bytes(self, mock_donor_credentials,
- mock_authorizedsession_sign):
+ def test_sign_bytes(self, mock_donor_credentials, mock_authorizedsession_sign):
credentials = self.make_credentials(lifetime=None)
- token = 'token'
+ token = "token"
expire_time = (
- _helpers.utcnow().replace(microsecond=0) +
- datetime.timedelta(seconds=500)).isoformat('T') + 'Z'
- token_response_body = {
- "accessToken": token,
- "expireTime": expire_time
- }
+ _helpers.utcnow().replace(microsecond=0) + datetime.timedelta(seconds=500)
+ ).isoformat("T") + "Z"
+ token_response_body = {"accessToken": token, "expireTime": expire_time}
response = mock.create_autospec(transport.Response, instance=False)
response.status = http_client.OK
@@ -259,26 +246,24 @@
assert credentials.valid
assert not credentials.expired
- signature = credentials.sign_bytes(b'signed bytes')
- assert signature == b'signature'
+ signature = credentials.sign_bytes(b"signed bytes")
+ assert signature == b"signature"
- def test_id_token_success(self, mock_donor_credentials,
- mock_authorizedsession_idtoken):
+ def test_id_token_success(
+ self, mock_donor_credentials, mock_authorizedsession_idtoken
+ ):
credentials = self.make_credentials(lifetime=None)
- token = 'token'
- target_audience = 'https://foo.bar'
+ token = "token"
+ target_audience = "https://foo.bar"
expire_time = (
- _helpers.utcnow().replace(microsecond=0) +
- datetime.timedelta(seconds=500)).isoformat('T') + 'Z'
- response_body = {
- "accessToken": token,
- "expireTime": expire_time
- }
+ _helpers.utcnow().replace(microsecond=0) + datetime.timedelta(seconds=500)
+ ).isoformat("T") + "Z"
+ response_body = {"accessToken": token, "expireTime": expire_time}
request = self.make_request(
- data=json.dumps(response_body),
- status=http_client.OK)
+ data=json.dumps(response_body), status=http_client.OK
+ )
credentials.refresh(request)
@@ -286,30 +271,28 @@
assert not credentials.expired
id_creds = impersonated_credentials.IDTokenCredentials(
- credentials, target_audience=target_audience)
+ credentials, target_audience=target_audience
+ )
id_creds.refresh(request)
assert id_creds.token == ID_TOKEN_DATA
- assert id_creds.expiry == datetime.datetime.fromtimestamp(
- ID_TOKEN_EXPIRY)
+ assert id_creds.expiry == datetime.datetime.fromtimestamp(ID_TOKEN_EXPIRY)
- def test_id_token_from_credential(self, mock_donor_credentials,
- mock_authorizedsession_idtoken):
+ def test_id_token_from_credential(
+ self, mock_donor_credentials, mock_authorizedsession_idtoken
+ ):
credentials = self.make_credentials(lifetime=None)
- token = 'token'
- target_audience = 'https://foo.bar'
+ token = "token"
+ target_audience = "https://foo.bar"
expire_time = (
- _helpers.utcnow().replace(microsecond=0) +
- datetime.timedelta(seconds=500)).isoformat('T') + 'Z'
- response_body = {
- "accessToken": token,
- "expireTime": expire_time
- }
+ _helpers.utcnow().replace(microsecond=0) + datetime.timedelta(seconds=500)
+ ).isoformat("T") + "Z"
+ response_body = {"accessToken": token, "expireTime": expire_time}
request = self.make_request(
- data=json.dumps(response_body),
- status=http_client.OK)
+ data=json.dumps(response_body), status=http_client.OK
+ )
credentials.refresh(request)
@@ -317,72 +300,66 @@
assert not credentials.expired
id_creds = impersonated_credentials.IDTokenCredentials(
- credentials, target_audience=target_audience)
+ credentials, target_audience=target_audience
+ )
id_creds = id_creds.from_credentials(target_credentials=credentials)
id_creds.refresh(request)
assert id_creds.token == ID_TOKEN_DATA
- def test_id_token_with_target_audience(self, mock_donor_credentials,
- mock_authorizedsession_idtoken):
+ def test_id_token_with_target_audience(
+ self, mock_donor_credentials, mock_authorizedsession_idtoken
+ ):
credentials = self.make_credentials(lifetime=None)
- token = 'token'
- target_audience = 'https://foo.bar'
+ token = "token"
+ target_audience = "https://foo.bar"
expire_time = (
- _helpers.utcnow().replace(microsecond=0) +
- datetime.timedelta(seconds=500)).isoformat('T') + 'Z'
- response_body = {
- "accessToken": token,
- "expireTime": expire_time
- }
+ _helpers.utcnow().replace(microsecond=0) + datetime.timedelta(seconds=500)
+ ).isoformat("T") + "Z"
+ response_body = {"accessToken": token, "expireTime": expire_time}
request = self.make_request(
- data=json.dumps(response_body),
- status=http_client.OK)
+ data=json.dumps(response_body), status=http_client.OK
+ )
credentials.refresh(request)
assert credentials.valid
assert not credentials.expired
- id_creds = impersonated_credentials.IDTokenCredentials(
- credentials)
- id_creds = id_creds.with_target_audience(
- target_audience=target_audience)
+ id_creds = impersonated_credentials.IDTokenCredentials(credentials)
+ id_creds = id_creds.with_target_audience(target_audience=target_audience)
id_creds.refresh(request)
assert id_creds.token == ID_TOKEN_DATA
- assert id_creds.expiry == datetime.datetime.fromtimestamp(
- ID_TOKEN_EXPIRY)
+ assert id_creds.expiry == datetime.datetime.fromtimestamp(ID_TOKEN_EXPIRY)
- def test_id_token_invalid_cred(self, mock_donor_credentials,
- mock_authorizedsession_idtoken):
+ def test_id_token_invalid_cred(
+ self, mock_donor_credentials, mock_authorizedsession_idtoken
+ ):
credentials = None
with pytest.raises(exceptions.GoogleAuthError) as excinfo:
impersonated_credentials.IDTokenCredentials(credentials)
- assert excinfo.match('Provided Credential must be'
- ' impersonated_credentials')
+ assert excinfo.match("Provided Credential must be" " impersonated_credentials")
- def test_id_token_with_include_email(self, mock_donor_credentials,
- mock_authorizedsession_idtoken):
+ def test_id_token_with_include_email(
+ self, mock_donor_credentials, mock_authorizedsession_idtoken
+ ):
credentials = self.make_credentials(lifetime=None)
- token = 'token'
- target_audience = 'https://foo.bar'
+ token = "token"
+ target_audience = "https://foo.bar"
expire_time = (
- _helpers.utcnow().replace(microsecond=0) +
- datetime.timedelta(seconds=500)).isoformat('T') + 'Z'
- response_body = {
- "accessToken": token,
- "expireTime": expire_time
- }
+ _helpers.utcnow().replace(microsecond=0) + datetime.timedelta(seconds=500)
+ ).isoformat("T") + "Z"
+ response_body = {"accessToken": token, "expireTime": expire_time}
request = self.make_request(
- data=json.dumps(response_body),
- status=http_client.OK)
+ data=json.dumps(response_body), status=http_client.OK
+ )
credentials.refresh(request)
@@ -390,7 +367,8 @@
assert not credentials.expired
id_creds = impersonated_credentials.IDTokenCredentials(
- credentials, target_audience=target_audience)
+ credentials, target_audience=target_audience
+ )
id_creds = id_creds.with_include_email(True)
id_creds.refresh(request)
diff --git a/tests/test_jwt.py b/tests/test_jwt.py
index 4a64717..b0c6e48 100644
--- a/tests/test_jwt.py
+++ b/tests/test_jwt.py
@@ -26,41 +26,45 @@
from google.auth import jwt
-DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
+DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
-with open(os.path.join(DATA_DIR, 'privatekey.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
-with open(os.path.join(DATA_DIR, 'public_cert.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "public_cert.pem"), "rb") as fh:
PUBLIC_CERT_BYTES = fh.read()
-with open(os.path.join(DATA_DIR, 'other_cert.pem'), 'rb') as fh:
+with open(os.path.join(DATA_DIR, "other_cert.pem"), "rb") as fh:
OTHER_CERT_BYTES = fh.read()
-SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, 'service_account.json')
+SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
-with open(SERVICE_ACCOUNT_JSON_FILE, 'r') as fh:
+with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
SERVICE_ACCOUNT_INFO = json.load(fh)
@pytest.fixture
def signer():
- return crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, '1')
+ return crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, "1")
def test_encode_basic(signer):
- test_payload = {'test': 'value'}
+ test_payload = {"test": "value"}
encoded = jwt.encode(signer, test_payload)
header, payload, _, _ = jwt._unverified_decode(encoded)
assert payload == test_payload
- assert header == {'typ': 'JWT', 'alg': 'RS256', 'kid': signer.key_id}
+ assert header == {"typ": "JWT", "alg": "RS256", "kid": signer.key_id}
def test_encode_extra_headers(signer):
- encoded = jwt.encode(signer, {}, header={'extra': 'value'})
+ encoded = jwt.encode(signer, {}, header={"extra": "value"})
header = jwt.decode_header(encoded)
assert header == {
- 'typ': 'JWT', 'alg': 'RS256', 'kid': signer.key_id, 'extra': 'value'}
+ "typ": "JWT",
+ "alg": "RS256",
+ "kid": signer.key_id,
+ "extra": "value",
+ }
@pytest.fixture
@@ -68,11 +72,11 @@
def factory(claims=None, key_id=None):
now = _helpers.datetime_to_secs(_helpers.utcnow())
payload = {
- 'aud': 'audience@example.com',
- 'iat': now,
- 'exp': now + 300,
- 'user': 'billy bob',
- 'metadata': {'meta': 'data'}
+ "aud": "audience@example.com",
+ "iat": now,
+ "exp": now + 300,
+ "user": "billy bob",
+ "metadata": {"meta": "data"},
}
payload.update(claims or {})
@@ -83,154 +87,168 @@
key_id = None
return jwt.encode(signer, payload, key_id=key_id)
+
return factory
def test_decode_valid(token_factory):
payload = jwt.decode(token_factory(), certs=PUBLIC_CERT_BYTES)
- assert payload['aud'] == 'audience@example.com'
- assert payload['user'] == 'billy bob'
- assert payload['metadata']['meta'] == 'data'
+ assert payload["aud"] == "audience@example.com"
+ assert payload["user"] == "billy bob"
+ assert payload["metadata"]["meta"] == "data"
def test_decode_valid_with_audience(token_factory):
payload = jwt.decode(
- token_factory(), certs=PUBLIC_CERT_BYTES,
- audience='audience@example.com')
- assert payload['aud'] == 'audience@example.com'
- assert payload['user'] == 'billy bob'
- assert payload['metadata']['meta'] == 'data'
+ token_factory(), certs=PUBLIC_CERT_BYTES, audience="audience@example.com"
+ )
+ assert payload["aud"] == "audience@example.com"
+ assert payload["user"] == "billy bob"
+ assert payload["metadata"]["meta"] == "data"
def test_decode_valid_unverified(token_factory):
payload = jwt.decode(token_factory(), certs=OTHER_CERT_BYTES, verify=False)
- assert payload['aud'] == 'audience@example.com'
- assert payload['user'] == 'billy bob'
- assert payload['metadata']['meta'] == 'data'
+ assert payload["aud"] == "audience@example.com"
+ assert payload["user"] == "billy bob"
+ assert payload["metadata"]["meta"] == "data"
def test_decode_bad_token_wrong_number_of_segments():
with pytest.raises(ValueError) as excinfo:
- jwt.decode('1.2', PUBLIC_CERT_BYTES)
- assert excinfo.match(r'Wrong number of segments')
+ jwt.decode("1.2", PUBLIC_CERT_BYTES)
+ assert excinfo.match(r"Wrong number of segments")
def test_decode_bad_token_not_base64():
with pytest.raises((ValueError, TypeError)) as excinfo:
- jwt.decode('1.2.3', PUBLIC_CERT_BYTES)
- assert excinfo.match(r'Incorrect padding|more than a multiple of 4')
+ jwt.decode("1.2.3", PUBLIC_CERT_BYTES)
+ assert excinfo.match(r"Incorrect padding|more than a multiple of 4")
def test_decode_bad_token_not_json():
- token = b'.'.join([base64.urlsafe_b64encode(b'123!')] * 3)
+ token = b".".join([base64.urlsafe_b64encode(b"123!")] * 3)
with pytest.raises(ValueError) as excinfo:
jwt.decode(token, PUBLIC_CERT_BYTES)
- assert excinfo.match(r'Can\'t parse segment')
+ assert excinfo.match(r"Can\'t parse segment")
def test_decode_bad_token_no_iat_or_exp(signer):
- token = jwt.encode(signer, {'test': 'value'})
+ token = jwt.encode(signer, {"test": "value"})
with pytest.raises(ValueError) as excinfo:
jwt.decode(token, PUBLIC_CERT_BYTES)
- assert excinfo.match(r'Token does not contain required claim')
+ assert excinfo.match(r"Token does not contain required claim")
def test_decode_bad_token_too_early(token_factory):
- token = token_factory(claims={
- 'iat': _helpers.datetime_to_secs(
- _helpers.utcnow() + datetime.timedelta(hours=1))
- })
+ token = token_factory(
+ claims={
+ "iat": _helpers.datetime_to_secs(
+ _helpers.utcnow() + datetime.timedelta(hours=1)
+ )
+ }
+ )
with pytest.raises(ValueError) as excinfo:
jwt.decode(token, PUBLIC_CERT_BYTES)
- assert excinfo.match(r'Token used too early')
+ assert excinfo.match(r"Token used too early")
def test_decode_bad_token_expired(token_factory):
- token = token_factory(claims={
- 'exp': _helpers.datetime_to_secs(
- _helpers.utcnow() - datetime.timedelta(hours=1))
- })
+ token = token_factory(
+ claims={
+ "exp": _helpers.datetime_to_secs(
+ _helpers.utcnow() - datetime.timedelta(hours=1)
+ )
+ }
+ )
with pytest.raises(ValueError) as excinfo:
jwt.decode(token, PUBLIC_CERT_BYTES)
- assert excinfo.match(r'Token expired')
+ assert excinfo.match(r"Token expired")
def test_decode_bad_token_wrong_audience(token_factory):
token = token_factory()
- audience = 'audience2@example.com'
+ audience = "audience2@example.com"
with pytest.raises(ValueError) as excinfo:
jwt.decode(token, PUBLIC_CERT_BYTES, audience=audience)
- assert excinfo.match(r'Token has wrong audience')
+ assert excinfo.match(r"Token has wrong audience")
def test_decode_wrong_cert(token_factory):
with pytest.raises(ValueError) as excinfo:
jwt.decode(token_factory(), OTHER_CERT_BYTES)
- assert excinfo.match(r'Could not verify token signature')
+ assert excinfo.match(r"Could not verify token signature")
def test_decode_multicert_bad_cert(token_factory):
- certs = {'1': OTHER_CERT_BYTES, '2': PUBLIC_CERT_BYTES}
+ certs = {"1": OTHER_CERT_BYTES, "2": PUBLIC_CERT_BYTES}
with pytest.raises(ValueError) as excinfo:
jwt.decode(token_factory(), certs)
- assert excinfo.match(r'Could not verify token signature')
+ assert excinfo.match(r"Could not verify token signature")
def test_decode_no_cert(token_factory):
- certs = {'2': PUBLIC_CERT_BYTES}
+ certs = {"2": PUBLIC_CERT_BYTES}
with pytest.raises(ValueError) as excinfo:
jwt.decode(token_factory(), certs)
- assert excinfo.match(r'Certificate for key id 1 not found')
+ assert excinfo.match(r"Certificate for key id 1 not found")
def test_decode_no_key_id(token_factory):
token = token_factory(key_id=False)
- certs = {'2': PUBLIC_CERT_BYTES}
+ certs = {"2": PUBLIC_CERT_BYTES}
payload = jwt.decode(token, certs)
- assert payload['user'] == 'billy bob'
+ assert payload["user"] == "billy bob"
def test_roundtrip_explicit_key_id(token_factory):
- token = token_factory(key_id='3')
- certs = {'2': OTHER_CERT_BYTES, '3': PUBLIC_CERT_BYTES}
+ token = token_factory(key_id="3")
+ certs = {"2": OTHER_CERT_BYTES, "3": PUBLIC_CERT_BYTES}
payload = jwt.decode(token, certs)
- assert payload['user'] == 'billy bob'
+ assert payload["user"] == "billy bob"
class TestCredentials(object):
- SERVICE_ACCOUNT_EMAIL = 'service-account@example.com'
- SUBJECT = 'subject'
- AUDIENCE = 'audience'
- ADDITIONAL_CLAIMS = {'meta': 'data'}
+ SERVICE_ACCOUNT_EMAIL = "service-account@example.com"
+ SUBJECT = "subject"
+ AUDIENCE = "audience"
+ ADDITIONAL_CLAIMS = {"meta": "data"}
credentials = None
@pytest.fixture(autouse=True)
def credentials_fixture(self, signer):
self.credentials = jwt.Credentials(
- signer, self.SERVICE_ACCOUNT_EMAIL, self.SERVICE_ACCOUNT_EMAIL,
- self.AUDIENCE)
+ signer,
+ self.SERVICE_ACCOUNT_EMAIL,
+ self.SERVICE_ACCOUNT_EMAIL,
+ self.AUDIENCE,
+ )
def test_from_service_account_info(self):
- with open(SERVICE_ACCOUNT_JSON_FILE, 'r') as fh:
+ with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
info = json.load(fh)
credentials = jwt.Credentials.from_service_account_info(
- info, audience=self.AUDIENCE)
+ info, audience=self.AUDIENCE
+ )
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._issuer == info['client_email']
- assert credentials._subject == info['client_email']
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._issuer == info["client_email"]
+ assert credentials._subject == info["client_email"]
assert credentials._audience == self.AUDIENCE
def test_from_service_account_info_args(self):
info = SERVICE_ACCOUNT_INFO.copy()
credentials = jwt.Credentials.from_service_account_info(
- info, subject=self.SUBJECT, audience=self.AUDIENCE,
- additional_claims=self.ADDITIONAL_CLAIMS)
+ info,
+ subject=self.SUBJECT,
+ audience=self.AUDIENCE,
+ additional_claims=self.ADDITIONAL_CLAIMS,
+ )
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._issuer == info['client_email']
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._issuer == info["client_email"]
assert credentials._subject == self.SUBJECT
assert credentials._audience == self.AUDIENCE
assert credentials._additional_claims == self.ADDITIONAL_CLAIMS
@@ -239,33 +257,37 @@
info = SERVICE_ACCOUNT_INFO.copy()
credentials = jwt.Credentials.from_service_account_file(
- SERVICE_ACCOUNT_JSON_FILE, audience=self.AUDIENCE)
+ SERVICE_ACCOUNT_JSON_FILE, audience=self.AUDIENCE
+ )
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._issuer == info['client_email']
- assert credentials._subject == info['client_email']
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._issuer == info["client_email"]
+ assert credentials._subject == info["client_email"]
assert credentials._audience == self.AUDIENCE
def test_from_service_account_file_args(self):
info = SERVICE_ACCOUNT_INFO.copy()
credentials = jwt.Credentials.from_service_account_file(
- SERVICE_ACCOUNT_JSON_FILE, subject=self.SUBJECT,
- audience=self.AUDIENCE, additional_claims=self.ADDITIONAL_CLAIMS)
+ SERVICE_ACCOUNT_JSON_FILE,
+ subject=self.SUBJECT,
+ audience=self.AUDIENCE,
+ additional_claims=self.ADDITIONAL_CLAIMS,
+ )
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._issuer == info['client_email']
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._issuer == info["client_email"]
assert credentials._subject == self.SUBJECT
assert credentials._audience == self.AUDIENCE
assert credentials._additional_claims == self.ADDITIONAL_CLAIMS
def test_from_signing_credentials(self):
jwt_from_signing = self.credentials.from_signing_credentials(
- self.credentials,
- audience=mock.sentinel.new_audience)
+ self.credentials, audience=mock.sentinel.new_audience
+ )
jwt_from_info = jwt.Credentials.from_service_account_info(
- SERVICE_ACCOUNT_INFO,
- audience=mock.sentinel.new_audience)
+ SERVICE_ACCOUNT_INFO, audience=mock.sentinel.new_audience
+ )
assert isinstance(jwt_from_signing, jwt.Credentials)
assert jwt_from_signing._signer.key_id == jwt_from_info._signer.key_id
@@ -279,19 +301,17 @@
assert not self.credentials.expired
def test_with_claims(self):
- new_audience = 'new_audience'
- new_credentials = self.credentials.with_claims(
- audience=new_audience)
+ new_audience = "new_audience"
+ new_credentials = self.credentials.with_claims(audience=new_audience)
assert new_credentials._signer == self.credentials._signer
assert new_credentials._issuer == self.credentials._issuer
assert new_credentials._subject == self.credentials._subject
assert new_credentials._audience == new_audience
- assert (new_credentials._additional_claims ==
- self.credentials._additional_claims)
+ assert new_credentials._additional_claims == self.credentials._additional_claims
def test_sign_bytes(self):
- to_sign = b'123'
+ to_sign = b"123"
signature = self.credentials.sign_bytes(to_sign)
assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)
@@ -299,12 +319,11 @@
assert isinstance(self.credentials.signer, crypt.RSASigner)
def test_signer_email(self):
- assert (self.credentials.signer_email ==
- SERVICE_ACCOUNT_INFO['client_email'])
+ assert self.credentials.signer_email == SERVICE_ACCOUNT_INFO["client_email"]
def _verify_token(self, token):
payload = jwt.decode(token, PUBLIC_CERT_BYTES)
- assert payload['iss'] == self.SERVICE_ACCOUNT_EMAIL
+ assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL
return payload
def test_refresh(self):
@@ -318,7 +337,7 @@
self.credentials.refresh(None)
assert not self.credentials.expired
- with mock.patch('google.auth._helpers.utcnow') as now:
+ with mock.patch("google.auth._helpers.utcnow") as now:
one_day = datetime.timedelta(days=1)
now.return_value = self.credentials.expiry + one_day
assert self.credentials.expired
@@ -328,55 +347,58 @@
self.credentials.refresh(None)
self.credentials.before_request(
- None, 'GET', 'http://example.com?a=1#3', headers)
+ None, "GET", "http://example.com?a=1#3", headers
+ )
- header_value = headers['authorization']
- _, token = header_value.split(' ')
+ header_value = headers["authorization"]
+ _, token = header_value.split(" ")
# Since the audience is set, it should use the existing token.
- assert token.encode('utf-8') == self.credentials.token
+ assert token.encode("utf-8") == self.credentials.token
payload = self._verify_token(token)
- assert payload['aud'] == self.AUDIENCE
+ assert payload["aud"] == self.AUDIENCE
def test_before_request_refreshes(self):
assert not self.credentials.valid
- self.credentials.before_request(
- None, 'GET', 'http://example.com?a=1#3', {})
+ self.credentials.before_request(None, "GET", "http://example.com?a=1#3", {})
assert self.credentials.valid
class TestOnDemandCredentials(object):
- SERVICE_ACCOUNT_EMAIL = 'service-account@example.com'
- SUBJECT = 'subject'
- ADDITIONAL_CLAIMS = {'meta': 'data'}
+ SERVICE_ACCOUNT_EMAIL = "service-account@example.com"
+ SUBJECT = "subject"
+ ADDITIONAL_CLAIMS = {"meta": "data"}
credentials = None
@pytest.fixture(autouse=True)
def credentials_fixture(self, signer):
self.credentials = jwt.OnDemandCredentials(
- signer, self.SERVICE_ACCOUNT_EMAIL, self.SERVICE_ACCOUNT_EMAIL,
- max_cache_size=2)
+ signer,
+ self.SERVICE_ACCOUNT_EMAIL,
+ self.SERVICE_ACCOUNT_EMAIL,
+ max_cache_size=2,
+ )
def test_from_service_account_info(self):
- with open(SERVICE_ACCOUNT_JSON_FILE, 'r') as fh:
+ with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
info = json.load(fh)
credentials = jwt.OnDemandCredentials.from_service_account_info(info)
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._issuer == info['client_email']
- assert credentials._subject == info['client_email']
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._issuer == info["client_email"]
+ assert credentials._subject == info["client_email"]
def test_from_service_account_info_args(self):
info = SERVICE_ACCOUNT_INFO.copy()
credentials = jwt.OnDemandCredentials.from_service_account_info(
- info, subject=self.SUBJECT,
- additional_claims=self.ADDITIONAL_CLAIMS)
+ info, subject=self.SUBJECT, additional_claims=self.ADDITIONAL_CLAIMS
+ )
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._issuer == info['client_email']
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._issuer == info["client_email"]
assert credentials._subject == self.SUBJECT
assert credentials._additional_claims == self.ADDITIONAL_CLAIMS
@@ -384,29 +406,32 @@
info = SERVICE_ACCOUNT_INFO.copy()
credentials = jwt.OnDemandCredentials.from_service_account_file(
- SERVICE_ACCOUNT_JSON_FILE)
+ SERVICE_ACCOUNT_JSON_FILE
+ )
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._issuer == info['client_email']
- assert credentials._subject == info['client_email']
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._issuer == info["client_email"]
+ assert credentials._subject == info["client_email"]
def test_from_service_account_file_args(self):
info = SERVICE_ACCOUNT_INFO.copy()
credentials = jwt.OnDemandCredentials.from_service_account_file(
- SERVICE_ACCOUNT_JSON_FILE, subject=self.SUBJECT,
- additional_claims=self.ADDITIONAL_CLAIMS)
+ SERVICE_ACCOUNT_JSON_FILE,
+ subject=self.SUBJECT,
+ additional_claims=self.ADDITIONAL_CLAIMS,
+ )
- assert credentials._signer.key_id == info['private_key_id']
- assert credentials._issuer == info['client_email']
+ assert credentials._signer.key_id == info["private_key_id"]
+ assert credentials._issuer == info["client_email"]
assert credentials._subject == self.SUBJECT
assert credentials._additional_claims == self.ADDITIONAL_CLAIMS
def test_from_signing_credentials(self):
- jwt_from_signing = self.credentials.from_signing_credentials(
- self.credentials)
+ jwt_from_signing = self.credentials.from_signing_credentials(self.credentials)
jwt_from_info = jwt.OnDemandCredentials.from_service_account_info(
- SERVICE_ACCOUNT_INFO)
+ SERVICE_ACCOUNT_INFO
+ )
assert isinstance(jwt_from_signing, jwt.OnDemandCredentials)
assert jwt_from_signing._signer.key_id == jwt_from_info._signer.key_id
@@ -420,9 +445,8 @@
assert not self.credentials.expired
def test_with_claims(self):
- new_claims = {'meep': 'moop'}
- new_credentials = self.credentials.with_claims(
- additional_claims=new_claims)
+ new_claims = {"meep": "moop"}
+ new_credentials = self.credentials.with_claims(additional_claims=new_claims)
assert new_credentials._signer == self.credentials._signer
assert new_credentials._issuer == self.credentials._issuer
@@ -430,7 +454,7 @@
assert new_credentials._additional_claims == new_claims
def test_sign_bytes(self):
- to_sign = b'123'
+ to_sign = b"123"
signature = self.credentials.sign_bytes(to_sign)
assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)
@@ -438,12 +462,11 @@
assert isinstance(self.credentials.signer, crypt.RSASigner)
def test_signer_email(self):
- assert (self.credentials.signer_email ==
- SERVICE_ACCOUNT_INFO['client_email'])
+ assert self.credentials.signer_email == SERVICE_ACCOUNT_INFO["client_email"]
def _verify_token(self, token):
payload = jwt.decode(token, PUBLIC_CERT_BYTES)
- assert payload['iss'] == self.SERVICE_ACCOUNT_EMAIL
+ assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL
return payload
def test_refresh(self):
@@ -454,25 +477,27 @@
headers = {}
self.credentials.before_request(
- None, 'GET', 'http://example.com?a=1#3', headers)
+ None, "GET", "http://example.com?a=1#3", headers
+ )
- _, token = headers['authorization'].split(' ')
+ _, token = headers["authorization"].split(" ")
payload = self._verify_token(token)
- assert payload['aud'] == 'http://example.com'
+ assert payload["aud"] == "http://example.com"
# Making another request should re-use the same token.
- self.credentials.before_request(
- None, 'GET', 'http://example.com?b=2', headers)
+ self.credentials.before_request(None, "GET", "http://example.com?b=2", headers)
- _, new_token = headers['authorization'].split(' ')
+ _, new_token = headers["authorization"].split(" ")
assert new_token == token
def test_expired_token(self):
- self.credentials._cache['audience'] = (
- mock.sentinel.token, datetime.datetime.min)
+ self.credentials._cache["audience"] = (
+ mock.sentinel.token,
+ datetime.datetime.min,
+ )
- token = self.credentials._get_jwt_for_audience('audience')
+ token = self.credentials._get_jwt_for_audience("audience")
assert token != mock.sentinel.token
diff --git a/tests/transport/compliance.py b/tests/transport/compliance.py
index 50c6d7c..dc7c58b 100644
--- a/tests/transport/compliance.py
+++ b/tests/transport/compliance.py
@@ -22,12 +22,11 @@
from google.auth import exceptions
# .invalid will never resolve, see https://tools.ietf.org/html/rfc2606
-NXDOMAIN = 'test.invalid'
+NXDOMAIN = "test.invalid"
class RequestResponseTests(object):
-
- @pytest.fixture(scope='module')
+ @pytest.fixture(scope="module")
def server(self):
"""Provides a test HTTP server.
@@ -40,20 +39,21 @@
# pylint: disable=unused-variable
# (pylint thinks the flask routes are unusued.)
- @app.route('/basic')
+ @app.route("/basic")
def index():
- header_value = flask.request.headers.get('x-test-header', 'value')
- headers = {'X-Test-Header': header_value}
- return 'Basic Content', http_client.OK, headers
+ header_value = flask.request.headers.get("x-test-header", "value")
+ headers = {"X-Test-Header": header_value}
+ return "Basic Content", http_client.OK, headers
- @app.route('/server_error')
+ @app.route("/server_error")
def server_error():
- return 'Error', http_client.INTERNAL_SERVER_ERROR
+ return "Error", http_client.INTERNAL_SERVER_ERROR
- @app.route('/wait')
+ @app.route("/wait")
def wait():
time.sleep(3)
- return 'Waited'
+ return "Waited"
+
# pylint: enable=unused-variable
server = WSGIServer(application=app.wsgi_app)
@@ -63,44 +63,46 @@
def test_request_basic(self, server):
request = self.make_request()
- response = request(url=server.url + '/basic', method='GET')
+ response = request(url=server.url + "/basic", method="GET")
assert response.status == http_client.OK
- assert response.headers['x-test-header'] == 'value'
- assert response.data == b'Basic Content'
+ assert response.headers["x-test-header"] == "value"
+ assert response.data == b"Basic Content"
def test_request_with_timeout_success(self, server):
request = self.make_request()
- response = request(url=server.url + '/basic', method='GET', timeout=2)
+ response = request(url=server.url + "/basic", method="GET", timeout=2)
assert response.status == http_client.OK
- assert response.headers['x-test-header'] == 'value'
- assert response.data == b'Basic Content'
+ assert response.headers["x-test-header"] == "value"
+ assert response.data == b"Basic Content"
def test_request_with_timeout_failure(self, server):
request = self.make_request()
with pytest.raises(exceptions.TransportError):
- request(url=server.url + '/wait', method='GET', timeout=1)
+ request(url=server.url + "/wait", method="GET", timeout=1)
def test_request_headers(self, server):
request = self.make_request()
response = request(
- url=server.url + '/basic', method='GET', headers={
- 'x-test-header': 'hello world'})
+ url=server.url + "/basic",
+ method="GET",
+ headers={"x-test-header": "hello world"},
+ )
assert response.status == http_client.OK
- assert response.headers['x-test-header'] == 'hello world'
- assert response.data == b'Basic Content'
+ assert response.headers["x-test-header"] == "hello world"
+ assert response.data == b"Basic Content"
def test_request_error(self, server):
request = self.make_request()
- response = request(url=server.url + '/server_error', method='GET')
+ response = request(url=server.url + "/server_error", method="GET")
assert response.status == http_client.INTERNAL_SERVER_ERROR
- assert response.data == b'Error'
+ assert response.data == b"Error"
def test_connection_error(self):
request = self.make_request()
with pytest.raises(exceptions.TransportError):
- request(url='http://{}'.format(NXDOMAIN), method='GET')
+ request(url="http://{}".format(NXDOMAIN), method="GET")
diff --git a/tests/transport/test__http_client.py b/tests/transport/test__http_client.py
index 6b69088..9e7f108 100644
--- a/tests/transport/test__http_client.py
+++ b/tests/transport/test__http_client.py
@@ -26,6 +26,6 @@
def test_non_http(self):
request = self.make_request()
with pytest.raises(exceptions.TransportError) as excinfo:
- request(url='https://{}'.format(compliance.NXDOMAIN), method='GET')
+ request(url="https://{}".format(compliance.NXDOMAIN), method="GET")
- assert excinfo.match('https')
+ assert excinfo.match("https")
diff --git a/tests/transport/test_grpc.py b/tests/transport/test_grpc.py
index c98dcff..810d038 100644
--- a/tests/transport/test_grpc.py
+++ b/tests/transport/test_grpc.py
@@ -25,22 +25,23 @@
# pylint: disable=ungrouped-imports
import grpc
import google.auth.transport.grpc
+
HAS_GRPC = True
except ImportError: # pragma: NO COVER
HAS_GRPC = False
-pytestmark = pytest.mark.skipif(not HAS_GRPC, reason='gRPC is unavailable.')
+pytestmark = pytest.mark.skipif(not HAS_GRPC, reason="gRPC is unavailable.")
class CredentialsStub(credentials.Credentials):
- def __init__(self, token='token'):
+ def __init__(self, token="token"):
super(CredentialsStub, self).__init__()
self.token = token
self.expiry = None
def refresh(self, request):
- self.token += '1'
+ self.token += "1"
class TestAuthMetadataPlugin(object):
@@ -48,8 +49,7 @@
credentials = CredentialsStub()
request = mock.create_autospec(transport.Request)
- plugin = google.auth.transport.grpc.AuthMetadataPlugin(
- credentials, request)
+ plugin = google.auth.transport.grpc.AuthMetadataPlugin(credentials, request)
context = mock.create_autospec(grpc.AuthMetadataContext, instance=True)
context.method_name = mock.sentinel.method_name
@@ -59,15 +59,15 @@
plugin(context, callback)
callback.assert_called_once_with(
- [(u'authorization', u'Bearer {}'.format(credentials.token))], None)
+ [(u"authorization", u"Bearer {}".format(credentials.token))], None
+ )
def test_call_refresh(self):
credentials = CredentialsStub()
credentials.expiry = datetime.datetime.min + _helpers.CLOCK_SKEW
request = mock.create_autospec(transport.Request)
- plugin = google.auth.transport.grpc.AuthMetadataPlugin(
- credentials, request)
+ plugin = google.auth.transport.grpc.AuthMetadataPlugin(credentials, request)
context = mock.create_autospec(grpc.AuthMetadataContext, instance=True)
context.method_name = mock.sentinel.method_name
@@ -76,29 +76,33 @@
plugin(context, callback)
- assert credentials.token == 'token1'
+ assert credentials.token == "token1"
callback.assert_called_once_with(
- [(u'authorization', u'Bearer {}'.format(credentials.token))], None)
+ [(u"authorization", u"Bearer {}".format(credentials.token))], None
+ )
-@mock.patch('grpc.composite_channel_credentials', autospec=True)
-@mock.patch('grpc.metadata_call_credentials', autospec=True)
-@mock.patch('grpc.ssl_channel_credentials', autospec=True)
-@mock.patch('grpc.secure_channel', autospec=True)
+@mock.patch("grpc.composite_channel_credentials", autospec=True)
+@mock.patch("grpc.metadata_call_credentials", autospec=True)
+@mock.patch("grpc.ssl_channel_credentials", autospec=True)
+@mock.patch("grpc.secure_channel", autospec=True)
def test_secure_authorized_channel(
- secure_channel, ssl_channel_credentials, metadata_call_credentials,
- composite_channel_credentials):
+ secure_channel,
+ ssl_channel_credentials,
+ metadata_call_credentials,
+ composite_channel_credentials,
+):
credentials = CredentialsStub()
request = mock.create_autospec(transport.Request)
- target = 'example.com:80'
+ target = "example.com:80"
channel = google.auth.transport.grpc.secure_authorized_channel(
- credentials, request, target, options=mock.sentinel.options)
+ credentials, request, target, options=mock.sentinel.options
+ )
# Check the auth plugin construction.
auth_plugin = metadata_call_credentials.call_args[0][0]
- assert isinstance(
- auth_plugin, google.auth.transport.grpc.AuthMetadataPlugin)
+ assert isinstance(auth_plugin, google.auth.transport.grpc.AuthMetadataPlugin)
assert auth_plugin._credentials == credentials
assert auth_plugin._request == request
@@ -107,35 +111,41 @@
# Check the composite credentials call.
composite_channel_credentials.assert_called_once_with(
- ssl_channel_credentials.return_value,
- metadata_call_credentials.return_value)
+ ssl_channel_credentials.return_value, metadata_call_credentials.return_value
+ )
# Check the channel call.
secure_channel.assert_called_once_with(
- target, composite_channel_credentials.return_value,
- options=mock.sentinel.options)
+ target,
+ composite_channel_credentials.return_value,
+ options=mock.sentinel.options,
+ )
assert channel == secure_channel.return_value
-@mock.patch('grpc.composite_channel_credentials', autospec=True)
-@mock.patch('grpc.metadata_call_credentials', autospec=True)
-@mock.patch('grpc.ssl_channel_credentials', autospec=True)
-@mock.patch('grpc.secure_channel', autospec=True)
+@mock.patch("grpc.composite_channel_credentials", autospec=True)
+@mock.patch("grpc.metadata_call_credentials", autospec=True)
+@mock.patch("grpc.ssl_channel_credentials", autospec=True)
+@mock.patch("grpc.secure_channel", autospec=True)
def test_secure_authorized_channel_explicit_ssl(
- secure_channel, ssl_channel_credentials, metadata_call_credentials,
- composite_channel_credentials):
+ secure_channel,
+ ssl_channel_credentials,
+ metadata_call_credentials,
+ composite_channel_credentials,
+):
credentials = mock.Mock()
request = mock.Mock()
- target = 'example.com:80'
+ target = "example.com:80"
ssl_credentials = mock.Mock()
google.auth.transport.grpc.secure_authorized_channel(
- credentials, request, target, ssl_credentials=ssl_credentials)
+ credentials, request, target, ssl_credentials=ssl_credentials
+ )
# Check the ssl channel call.
assert not ssl_channel_credentials.called
# Check the composite credentials call.
composite_channel_credentials.assert_called_once_with(
- ssl_credentials,
- metadata_call_credentials.return_value)
+ ssl_credentials, metadata_call_credentials.return_value
+ )
diff --git a/tests/transport/test_requests.py b/tests/transport/test_requests.py
index 311992a..0e165ac 100644
--- a/tests/transport/test_requests.py
+++ b/tests/transport/test_requests.py
@@ -29,24 +29,24 @@
def test_timeout(self):
http = mock.create_autospec(requests.Session, instance=True)
request = google.auth.transport.requests.Request(http)
- request(url='http://example.com', method='GET', timeout=5)
+ request(url="http://example.com", method="GET", timeout=5)
- assert http.request.call_args[1]['timeout'] == 5
+ assert http.request.call_args[1]["timeout"] == 5
class CredentialsStub(google.auth.credentials.Credentials):
- def __init__(self, token='token'):
+ def __init__(self, token="token"):
super(CredentialsStub, self).__init__()
self.token = token
def apply(self, headers, token=None):
- headers['authorization'] = self.token
+ headers["authorization"] = self.token
def before_request(self, request, method, url, headers):
self.apply(headers)
def refresh(self, request):
- self.token += '1'
+ self.token += "1"
class AdapterStub(requests.adapters.BaseAdapter):
@@ -77,11 +77,12 @@
class TestAuthorizedHttp(object):
- TEST_URL = 'http://example.com/'
+ TEST_URL = "http://example.com/"
def test_constructor(self):
authed_session = google.auth.transport.requests.AuthorizedSession(
- mock.sentinel.credentials)
+ mock.sentinel.credentials
+ )
assert authed_session.credentials == mock.sentinel.credentials
@@ -90,7 +91,8 @@
auth_request = google.auth.transport.requests.Request(http)
authed_session = google.auth.transport.requests.AuthorizedSession(
- mock.sentinel.credentials, auth_request=auth_request)
+ mock.sentinel.credentials, auth_request=auth_request
+ )
assert authed_session._auth_request == auth_request
@@ -99,32 +101,30 @@
response = make_response()
adapter = AdapterStub([response])
- authed_session = google.auth.transport.requests.AuthorizedSession(
- credentials)
+ authed_session = google.auth.transport.requests.AuthorizedSession(credentials)
authed_session.mount(self.TEST_URL, adapter)
- result = authed_session.request('GET', self.TEST_URL)
+ result = authed_session.request("GET", self.TEST_URL)
assert response == result
assert credentials.before_request.called
assert not credentials.refresh.called
assert len(adapter.requests) == 1
assert adapter.requests[0].url == self.TEST_URL
- assert adapter.requests[0].headers['authorization'] == 'token'
+ assert adapter.requests[0].headers["authorization"] == "token"
def test_request_refresh(self):
credentials = mock.Mock(wraps=CredentialsStub())
final_response = make_response(status=http_client.OK)
# First request will 401, second request will succeed.
- adapter = AdapterStub([
- make_response(status=http_client.UNAUTHORIZED),
- final_response])
+ adapter = AdapterStub(
+ [make_response(status=http_client.UNAUTHORIZED), final_response]
+ )
- authed_session = google.auth.transport.requests.AuthorizedSession(
- credentials)
+ authed_session = google.auth.transport.requests.AuthorizedSession(credentials)
authed_session.mount(self.TEST_URL, adapter)
- result = authed_session.request('GET', self.TEST_URL)
+ result = authed_session.request("GET", self.TEST_URL)
assert result == final_response
assert credentials.before_request.call_count == 2
@@ -132,7 +132,7 @@
assert len(adapter.requests) == 2
assert adapter.requests[0].url == self.TEST_URL
- assert adapter.requests[0].headers['authorization'] == 'token'
+ assert adapter.requests[0].headers["authorization"] == "token"
assert adapter.requests[1].url == self.TEST_URL
- assert adapter.requests[1].headers['authorization'] == 'token1'
+ assert adapter.requests[1].headers["authorization"] == "token1"
diff --git a/tests/transport/test_urllib3.py b/tests/transport/test_urllib3.py
index a119b74..1d7ce5a 100644
--- a/tests/transport/test_urllib3.py
+++ b/tests/transport/test_urllib3.py
@@ -29,35 +29,35 @@
def test_timeout(self):
http = mock.create_autospec(urllib3.PoolManager)
request = google.auth.transport.urllib3.Request(http)
- request(url='http://example.com', method='GET', timeout=5)
+ request(url="http://example.com", method="GET", timeout=5)
- assert http.request.call_args[1]['timeout'] == 5
+ assert http.request.call_args[1]["timeout"] == 5
def test__make_default_http_with_certifi():
http = google.auth.transport.urllib3._make_default_http()
- assert 'cert_reqs' in http.connection_pool_kw
+ assert "cert_reqs" in http.connection_pool_kw
-@mock.patch.object(google.auth.transport.urllib3, 'certifi', new=None)
+@mock.patch.object(google.auth.transport.urllib3, "certifi", new=None)
def test__make_default_http_without_certifi():
http = google.auth.transport.urllib3._make_default_http()
- assert 'cert_reqs' not in http.connection_pool_kw
+ assert "cert_reqs" not in http.connection_pool_kw
class CredentialsStub(google.auth.credentials.Credentials):
- def __init__(self, token='token'):
+ def __init__(self, token="token"):
super(CredentialsStub, self).__init__()
self.token = token
def apply(self, headers, token=None):
- headers['authorization'] = self.token
+ headers["authorization"] = self.token
def before_request(self, request, method, url, headers):
self.apply(headers)
def refresh(self, request):
- self.token += '1'
+ self.token += "1"
class HttpStub(object):
@@ -78,11 +78,12 @@
class TestAuthorizedHttp(object):
- TEST_URL = 'http://example.com'
+ TEST_URL = "http://example.com"
def test_authed_http_defaults(self):
authed_http = google.auth.transport.urllib3.AuthorizedHttp(
- mock.sentinel.credentials)
+ mock.sentinel.credentials
+ )
assert authed_http.credentials == mock.sentinel.credentials
assert isinstance(authed_http.http, urllib3.PoolManager)
@@ -93,40 +94,41 @@
http = HttpStub([response])
authed_http = google.auth.transport.urllib3.AuthorizedHttp(
- credentials, http=http)
+ credentials, http=http
+ )
- result = authed_http.urlopen('GET', self.TEST_URL)
+ result = authed_http.urlopen("GET", self.TEST_URL)
assert result == response
assert credentials.before_request.called
assert not credentials.refresh.called
assert http.requests == [
- ('GET', self.TEST_URL, None, {'authorization': 'token'}, {})]
+ ("GET", self.TEST_URL, None, {"authorization": "token"}, {})
+ ]
def test_urlopen_refresh(self):
credentials = mock.Mock(wraps=CredentialsStub())
final_response = ResponseStub(status=http_client.OK)
# First request will 401, second request will succeed.
- http = HttpStub([
- ResponseStub(status=http_client.UNAUTHORIZED),
- final_response])
+ http = HttpStub([ResponseStub(status=http_client.UNAUTHORIZED), final_response])
authed_http = google.auth.transport.urllib3.AuthorizedHttp(
- credentials, http=http)
+ credentials, http=http
+ )
- authed_http = authed_http.urlopen('GET', 'http://example.com')
+ authed_http = authed_http.urlopen("GET", "http://example.com")
assert authed_http == final_response
assert credentials.before_request.call_count == 2
assert credentials.refresh.called
assert http.requests == [
- ('GET', self.TEST_URL, None, {'authorization': 'token'}, {}),
- ('GET', self.TEST_URL, None, {'authorization': 'token1'}, {})]
+ ("GET", self.TEST_URL, None, {"authorization": "token"}, {}),
+ ("GET", self.TEST_URL, None, {"authorization": "token1"}, {}),
+ ]
def test_proxies(self):
http = mock.create_autospec(urllib3.PoolManager)
- authed_http = google.auth.transport.urllib3.AuthorizedHttp(
- None, http=http)
+ authed_http = google.auth.transport.urllib3.AuthorizedHttp(None, http=http)
with authed_http:
pass