You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
5.6 KiB

# Copyright 2016 Google Inc. All Rights Reserved.
#
# 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.
"""Helpers for authentication using oauth2client or google-auth."""
import httplib2
try:
import google.auth
import google.auth.credentials
HAS_GOOGLE_AUTH = True
except ImportError: # pragma: NO COVER
HAS_GOOGLE_AUTH = False
try:
import google_auth_httplib2
except ImportError: # pragma: NO COVER
google_auth_httplib2 = None
try:
import oauth2client
import oauth2client.client
HAS_OAUTH2CLIENT = True
except ImportError: # pragma: NO COVER
HAS_OAUTH2CLIENT = False
def credentials_from_file(filename, scopes=None, quota_project_id=None):
"""Returns credentials loaded from a file."""
if HAS_GOOGLE_AUTH:
credentials, _ = google.auth.load_credentials_from_file(
filename, scopes=scopes, quota_project_id=quota_project_id
)
return credentials
else:
raise EnvironmentError(
"client_options.credentials_file is only supported in google-auth."
)
def default_credentials(scopes=None, quota_project_id=None):
"""Returns Application Default Credentials."""
if HAS_GOOGLE_AUTH:
credentials, _ = google.auth.default(
scopes=scopes, quota_project_id=quota_project_id
)
return credentials
elif HAS_OAUTH2CLIENT:
if scopes is not None or quota_project_id is not None:
raise EnvironmentError(
"client_options.scopes and client_options.quota_project_id are not supported in oauth2client."
"Please install google-auth."
)
return oauth2client.client.GoogleCredentials.get_application_default()
else:
raise EnvironmentError(
"No authentication library is available. Please install either "
"google-auth or oauth2client."
)
def with_scopes(credentials, scopes):
"""Scopes the credentials if necessary.
Args:
credentials (Union[
google.auth.credentials.Credentials,
oauth2client.client.Credentials]): The credentials to scope.
scopes (Sequence[str]): The list of scopes.
Returns:
Union[google.auth.credentials.Credentials,
oauth2client.client.Credentials]: The scoped credentials.
"""
if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
return google.auth.credentials.with_scopes_if_required(credentials, scopes)
else:
try:
if credentials.create_scoped_required():
return credentials.create_scoped(scopes)
else:
return credentials
except AttributeError:
return credentials
def authorized_http(credentials):
"""Returns an http client that is authorized with the given credentials.
Args:
credentials (Union[
google.auth.credentials.Credentials,
oauth2client.client.Credentials]): The credentials to use.
Returns:
Union[httplib2.Http, google_auth_httplib2.AuthorizedHttp]: An
authorized http client.
"""
from googleapiclient.http import build_http
if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
if google_auth_httplib2 is None:
raise ValueError(
"Credentials from google.auth specified, but "
"google-api-python-client is unable to use these credentials "
"unless google-auth-httplib2 is installed. Please install "
"google-auth-httplib2."
)
return google_auth_httplib2.AuthorizedHttp(credentials, http=build_http())
else:
return credentials.authorize(build_http())
def refresh_credentials(credentials):
# Refresh must use a new http instance, as the one associated with the
# credentials could be a AuthorizedHttp or an oauth2client-decorated
# Http instance which would cause a weird recursive loop of refreshing
# and likely tear a hole in spacetime.
refresh_http = httplib2.Http()
if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
request = google_auth_httplib2.Request(refresh_http)
return credentials.refresh(request)
else:
return credentials.refresh(refresh_http)
def apply_credentials(credentials, headers):
# oauth2client and google-auth have the same interface for this.
if not is_valid(credentials):
refresh_credentials(credentials)
return credentials.apply(headers)
def is_valid(credentials):
if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
return credentials.valid
else:
return (
credentials.access_token is not None
and not credentials.access_token_expired
)
def get_credentials_from_http(http):
if http is None:
return None
elif hasattr(http.request, "credentials"):
return http.request.credentials
elif hasattr(http, "credentials") and not isinstance(
http.credentials, httplib2.Credentials
):
return http.credentials
else:
return None