Index: client/third_party/google/auth/_default.py |
diff --git a/client/third_party/google/auth/_default.py b/client/third_party/google/auth/_default.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1e91368f5fa17213a879e42ac9cf4783ca61c332 |
--- /dev/null |
+++ b/client/third_party/google/auth/_default.py |
@@ -0,0 +1,282 @@ |
+# Copyright 2015 Google Inc. |
+# |
+# Licensed under the Apache License, Version 2.0 (the "License"); |
+# you may not use this file except in compliance with the License. |
+# You may obtain a copy of the License at |
+# |
+# http://www.apache.org/licenses/LICENSE-2.0 |
+# |
+# Unless required by applicable law or agreed to in writing, software |
+# distributed under the License is distributed on an "AS IS" BASIS, |
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+# See the License for the specific language governing permissions and |
+# limitations under the License. |
+ |
+"""Application default credentials. |
+ |
+Implements application default credentials and project ID detection. |
+""" |
+ |
+import io |
+import json |
+import logging |
+import os |
+ |
+from google.auth import environment_vars |
+from google.auth import exceptions |
+import google.auth.transport._http_client |
+ |
+_LOGGER = logging.getLogger(__name__) |
+ |
+# Valid types accepted for file-based credentials. |
+_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. |
+_HELP_MESSAGE = """ |
+Could not automatically determine credentials. Please set {env} or |
+explicitly create credential and re-run the application. For more |
+information, please see |
+https://developers.google.com/accounts/docs/application-default-credentials. |
+""".format(env=environment_vars.CREDENTIALS).strip() |
+ |
+ |
+def _load_credentials_from_file(filename): |
+ """Loads credentials from a file. |
+ |
+ The credentials file must be a service account key or stored authorized |
+ user credentials. |
+ |
+ Args: |
+ filename (str): The full path to the credentials file. |
+ |
+ Returns: |
+ Tuple[google.auth.credentials.Credentials, Optional[str]]: Loaded |
+ credentials and the project ID. Authorized user credentials do not |
+ have the project ID information. |
+ |
+ Raises: |
+ google.auth.exceptions.DefaultCredentialsError: if the file is in the |
+ wrong format. |
+ """ |
+ with io.open(filename, 'r') as file_obj: |
+ try: |
+ info = json.load(file_obj) |
+ except ValueError as exc: |
+ raise exceptions.DefaultCredentialsError( |
+ 'File {} is not a valid json file.'.format(filename), exc) |
+ |
+ # 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') |
+ |
+ if credential_type == _AUTHORIZED_USER_TYPE: |
+ from google.auth import _cloud_sdk |
+ |
+ try: |
+ credentials = _cloud_sdk.load_authorized_user_credentials(info) |
+ except ValueError as exc: |
+ raise exceptions.DefaultCredentialsError( |
+ 'Failed to load authorized user credentials from {}'.format( |
+ filename), exc) |
+ # Authorized user credentials do not contain the project ID. |
+ return credentials, None |
+ |
+ elif credential_type == _SERVICE_ACCOUNT_TYPE: |
+ from google.oauth2 import service_account |
+ |
+ try: |
+ credentials = ( |
+ service_account.Credentials.from_service_account_info(info)) |
+ except ValueError as exc: |
+ raise exceptions.DefaultCredentialsError( |
+ 'Failed to load service account credentials from {}'.format( |
+ filename), exc) |
+ 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)) |
+ |
+ |
+def _get_gcloud_sdk_credentials(): |
+ """Gets the credentials and project ID from the Cloud SDK.""" |
+ from google.auth import _cloud_sdk |
+ |
+ # Check if application default credentials exist. |
+ 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) |
+ |
+ if not project_id: |
+ project_id = _cloud_sdk.get_project_id() |
+ |
+ if not project_id: |
+ _LOGGER.warning( |
+ 'No project ID could be determined from the Cloud SDK ' |
+ 'configuration. Consider running `gcloud config set project` or ' |
+ 'setting the %s environment variable', environment_vars.PROJECT) |
+ |
+ return credentials, project_id |
+ |
+ |
+def _get_explicit_environ_credentials(): |
+ """Gets credentials from the GOOGLE_APPLICATION_CREDENTIALS environment |
+ variable.""" |
+ explicit_file = os.environ.get(environment_vars.CREDENTIALS) |
+ |
+ if explicit_file is not None: |
+ credentials, project_id = _load_credentials_from_file( |
+ os.environ[environment_vars.CREDENTIALS]) |
+ |
+ if not project_id: |
+ _LOGGER.warning( |
+ 'No project ID could be determined from the credentials at %s ' |
+ 'Consider setting the %s environment variable', |
+ environment_vars.CREDENTIALS, environment_vars.PROJECT) |
+ |
+ return credentials, project_id |
+ |
+ else: |
+ return None, None |
+ |
+ |
+def _get_gae_credentials(): |
+ """Gets Google App Engine App Identity credentials and project ID.""" |
+ from google.auth import app_engine |
+ |
+ try: |
+ credentials = app_engine.Credentials() |
+ project_id = app_engine.get_project_id() |
+ return credentials, project_id |
+ except EnvironmentError: |
+ return None, None |
+ |
+ |
+def _get_gce_credentials(request=None): |
+ """Gets credentials and project ID from the GCE Metadata Service.""" |
+ # Ping requires a transport, but we want application default credentials |
+ # to require no arguments. So, we'll use the _http_client transport which |
+ # uses http.client. This is only acceptable because the metadata server |
+ # doesn't do SSL and never requires proxies. |
+ from google.auth import compute_engine |
+ from google.auth.compute_engine import _metadata |
+ |
+ if request is None: |
+ request = google.auth.transport._http_client.Request() |
+ |
+ if _metadata.ping(request=request): |
+ # Get the project ID. |
+ try: |
+ project_id = _metadata.get_project_id(request=request) |
+ except exceptions.TransportError: |
+ _LOGGER.warning( |
+ 'No project ID could be determined from the Compute Engine ' |
+ 'metadata service. Consider setting the %s environment ' |
+ 'variable.', environment_vars.PROJECT) |
+ project_id = None |
+ |
+ return compute_engine.Credentials(), project_id |
+ else: |
+ return None, None |
+ |
+ |
+def default(scopes=None, request=None): |
+ """Gets the default credentials for the current environment. |
+ |
+ `Application Default Credentials`_ provides an easy way to obtain |
+ credentials to call Google APIs for server-to-server or local applications. |
+ This function acquires credentials from the environment in the following |
+ order: |
+ |
+ 1. If the environment variable ``GOOGLE_APPLICATION_CREDENTIALS`` is set |
+ to the path of a valid service account JSON private key file, then it is |
+ loaded and returned. The project ID returned is the project ID defined |
+ in the service account file if available (some older files do not |
+ contain project ID information). |
+ 2. If the `Google Cloud SDK`_ is installed and has application default |
+ credentials set they are loaded and returned. |
+ |
+ To enable application default credentials with the Cloud SDK run:: |
+ |
+ gcloud auth application-default login |
+ |
+ If the Cloud SDK has an active project, the project ID is returned. The |
+ active project can be set using:: |
+ |
+ gcloud config set project |
+ |
+ 3. If the application is running in the `App Engine standard environment`_ |
+ then the credentials and project ID from the `App Identity Service`_ |
+ are used. |
+ 4. If the application is running in `Compute Engine`_ or the |
+ `App Engine flexible environment`_ then the credentials and project ID |
+ are obtained from the `Metadata Service`_. |
+ 5. If no credentials are found, |
+ :class:`~google.auth.exceptions.DefaultCredentialsError` will be raised. |
+ |
+ .. _Application Default Credentials: https://developers.google.com\ |
+ /identity/protocols/application-default-credentials |
+ .. _Google Cloud SDK: https://cloud.google.com/sdk |
+ .. _App Engine standard environment: https://cloud.google.com/appengine |
+ .. _App Identity Service: https://cloud.google.com/appengine/docs/python\ |
+ /appidentity/ |
+ .. _Compute Engine: https://cloud.google.com/compute |
+ .. _App Engine flexible environment: https://cloud.google.com\ |
+ /appengine/flexible |
+ .. _Metadata Service: https://cloud.google.com/compute/docs\ |
+ /storing-retrieving-metadata |
+ |
+ Example:: |
+ |
+ import google.auth |
+ |
+ credentials, project_id = google.auth.default() |
+ |
+ Args: |
+ scopes (Sequence[str]): The list of scopes for the credentials. If |
+ specified, the credentials will automatically be scoped if |
+ necessary. |
+ request (google.auth.transport.Request): An object used to make |
+ HTTP requests. This is used to detect whether the application |
+ is running on Compute Engine. If not specified, then it will |
+ use the standard library http client to make requests. |
+ |
+ Returns: |
+ Tuple[~google.auth.credentials.Credentials, Optional[str]]: |
+ the current environment's credentials and project ID. Project ID |
+ may be None, which indicates that the Project ID could not be |
+ ascertained from the environment. |
+ |
+ Raises: |
+ ~google.auth.exceptions.DefaultCredentialsError: |
+ If no credentials were found, or if the credentials found were |
+ invalid. |
+ """ |
+ 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)) |
+ |
+ checkers = ( |
+ _get_explicit_environ_credentials, |
+ _get_gcloud_sdk_credentials, |
+ _get_gae_credentials, |
+ lambda: _get_gce_credentials(request)) |
+ |
+ for checker in checkers: |
+ credentials, project_id = checker() |
+ if credentials is not None: |
+ credentials = with_scopes_if_required(credentials, scopes) |
+ return credentials, explicit_project_id or project_id |
+ |
+ raise exceptions.DefaultCredentialsError(_HELP_MESSAGE) |