blob: 92f2796f45b5694fe8de9db5e2bfba185827fa10 [file] [log] [blame]
Jon Wayne Parrott85c2c6d2017-01-05 12:34:49 -08001# Copyright 2016 Google Inc. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Helpers for authentication using oauth2client or google-auth."""
16
Jon Wayne Parrottd3a5cf42017-06-19 17:55:04 -070017import httplib2
18
Jon Wayne Parrott85c2c6d2017-01-05 12:34:49 -080019try:
20 import google.auth
Wilson Lian09527302017-01-11 14:38:18 -080021 import google.auth.credentials
Jon Wayne Parrott85c2c6d2017-01-05 12:34:49 -080022 import google_auth_httplib2
23 HAS_GOOGLE_AUTH = True
24except ImportError: # pragma: NO COVER
25 HAS_GOOGLE_AUTH = False
26
27try:
28 import oauth2client
29 import oauth2client.client
30 HAS_OAUTH2CLIENT = True
31except ImportError: # pragma: NO COVER
32 HAS_OAUTH2CLIENT = False
33
34
35def default_credentials():
36 """Returns Application Default Credentials."""
37 if HAS_GOOGLE_AUTH:
38 credentials, _ = google.auth.default()
39 return credentials
40 elif HAS_OAUTH2CLIENT:
41 return oauth2client.client.GoogleCredentials.get_application_default()
42 else:
43 raise EnvironmentError(
44 'No authentication library is available. Please install either '
45 'google-auth or oauth2client.')
46
47
48def with_scopes(credentials, scopes):
49 """Scopes the credentials if necessary.
50
51 Args:
52 credentials (Union[
53 google.auth.credentials.Credentials,
54 oauth2client.client.Credentials]): The credentials to scope.
55 scopes (Sequence[str]): The list of scopes.
56
57 Returns:
58 Union[google.auth.credentials.Credentials,
59 oauth2client.client.Credentials]: The scoped credentials.
60 """
61 if HAS_GOOGLE_AUTH and isinstance(
62 credentials, google.auth.credentials.Credentials):
63 return google.auth.credentials.with_scopes_if_required(
64 credentials, scopes)
65 else:
66 try:
67 if credentials.create_scoped_required():
68 return credentials.create_scoped(scopes)
69 else:
70 return credentials
71 except AttributeError:
72 return credentials
73
74
75def authorized_http(credentials):
76 """Returns an http client that is authorized with the given credentials.
77
78 Args:
79 credentials (Union[
80 google.auth.credentials.Credentials,
81 oauth2client.client.Credentials]): The credentials to use.
82
83 Returns:
84 Union[httplib2.Http, google_auth_httplib2.AuthorizedHttp]: An
85 authorized http client.
86 """
Jon Wayne Parrottd3a5cf42017-06-19 17:55:04 -070087 from googleapiclient.http import build_http
88
Jon Wayne Parrott85c2c6d2017-01-05 12:34:49 -080089 if HAS_GOOGLE_AUTH and isinstance(
90 credentials, google.auth.credentials.Credentials):
Igor Maravić22435292017-01-19 22:28:22 +010091 return google_auth_httplib2.AuthorizedHttp(credentials,
92 http=build_http())
Jon Wayne Parrott85c2c6d2017-01-05 12:34:49 -080093 else:
Igor Maravić22435292017-01-19 22:28:22 +010094 return credentials.authorize(build_http())
Jon Wayne Parrottd3a5cf42017-06-19 17:55:04 -070095
96
97def refresh_credentials(credentials):
98 # Refresh must use a new http instance, as the one associated with the
99 # credentials could be a AuthorizedHttp or an oauth2client-decorated
100 # Http instance which would cause a weird recursive loop of refreshing
101 # and likely tear a hole in spacetime.
102 refresh_http = httplib2.Http()
103 if HAS_GOOGLE_AUTH and isinstance(
104 credentials, google.auth.credentials.Credentials):
105 request = google_auth_httplib2.Request(refresh_http)
106 return credentials.refresh(request)
107 else:
108 return credentials.refresh(refresh_http)
109
110
111def apply_credentials(credentials, headers):
112 # oauth2client and google-auth have the same interface for this.
113 return credentials.apply(headers)
114
115
116def is_valid(credentials):
117 if HAS_GOOGLE_AUTH and isinstance(
118 credentials, google.auth.credentials.Credentials):
119 return credentials.valid
120 else:
121 return not credentials.access_token_expired
122
123
124def get_credentials_from_http(http):
125 if http is None:
126 return None
127 elif hasattr(http.request, 'credentials'):
128 return http.request.credentials
Jon Wayne Parrott3fb2a382017-08-02 13:04:30 -0700129 elif (hasattr(http, 'credentials')
130 and not isinstance(http.credentials, httplib2.Credentials)):
Jon Wayne Parrottd3a5cf42017-06-19 17:55:04 -0700131 return http.credentials
132 else:
133 return None