Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: client/third_party/google/oauth2/_client.py

Issue 2953253003: Replace custom blob gRPC API with ByteStream (Closed)
Patch Set: Import ndb directly to test code Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 Google Inc.
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 """OAuth 2.0 client.
16
17 This is a client for interacting with an OAuth 2.0 authorization server's
18 token endpoint.
19
20 For more information about the token endpoint, see
21 `Section 3.1 of rfc6749`_
22
23 .. _Section 3.1 of rfc6749: https://tools.ietf.org/html/rfc6749#section-3.2
24 """
25
26 import datetime
27 import json
28
29 from six.moves import http_client
30 from six.moves import urllib
31
32 from google.auth import _helpers
33 from google.auth import exceptions
34
35 _URLENCODED_CONTENT_TYPE = 'application/x-www-form-urlencoded'
36 _JWT_GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
37 _REFRESH_GRANT_TYPE = 'refresh_token'
38
39
40 def _handle_error_response(response_body):
41 """"Translates an error response into an exception.
42
43 Args:
44 response_body (str): The decoded response data.
45
46 Raises:
47 google.auth.exceptions.RefreshError
48 """
49 try:
50 error_data = json.loads(response_body)
51 error_details = '{}: {}'.format(
52 error_data['error'],
53 error_data.get('error_description'))
54 # If no details could be extracted, use the response data.
55 except (KeyError, ValueError):
56 error_details = response_body
57
58 raise exceptions.RefreshError(
59 error_details, response_body)
60
61
62 def _parse_expiry(response_data):
63 """Parses the expiry field from a response into a datetime.
64
65 Args:
66 response_data (Mapping): The JSON-parsed response data.
67
68 Returns:
69 Optional[datetime]: The expiration or ``None`` if no expiration was
70 specified.
71 """
72 expires_in = response_data.get('expires_in', None)
73
74 if expires_in is not None:
75 return _helpers.utcnow() + datetime.timedelta(
76 seconds=expires_in)
77 else:
78 return None
79
80
81 def _token_endpoint_request(request, token_uri, body):
82 """Makes a request to the OAuth 2.0 authorization server's token endpoint.
83
84 Args:
85 request (google.auth.transport.Request): A callable used to make
86 HTTP requests.
87 token_uri (str): The OAuth 2.0 authorizations server's token endpoint
88 URI.
89 body (Mapping[str, str]): The parameters to send in the request body.
90
91 Returns:
92 Mapping[str, str]: The JSON-decoded response data.
93
94 Raises:
95 google.auth.exceptions.RefreshError: If the token endpoint returned
96 an error.
97 """
98 body = urllib.parse.urlencode(body)
99 headers = {
100 'content-type': _URLENCODED_CONTENT_TYPE,
101 }
102
103 response = request(
104 method='POST', url=token_uri, headers=headers, body=body)
105
106 response_body = response.data.decode('utf-8')
107
108 if response.status != http_client.OK:
109 _handle_error_response(response_body)
110
111 response_data = json.loads(response_body)
112
113 return response_data
114
115
116 def jwt_grant(request, token_uri, assertion):
117 """Implements the JWT Profile for OAuth 2.0 Authorization Grants.
118
119 For more details, see `rfc7523 section 4`_.
120
121 Args:
122 request (google.auth.transport.Request): A callable used to make
123 HTTP requests.
124 token_uri (str): The OAuth 2.0 authorizations server's token endpoint
125 URI.
126 assertion (str): The OAuth 2.0 assertion.
127
128 Returns:
129 Tuple[str, Optional[datetime], Mapping[str, str]]: The access token,
130 expiration, and additional data returned by the token endpoint.
131
132 Raises:
133 google.auth.exceptions.RefreshError: If the token endpoint returned
134 an error.
135
136 .. _rfc7523 section 4: https://tools.ietf.org/html/rfc7523#section-4
137 """
138 body = {
139 'assertion': assertion,
140 'grant_type': _JWT_GRANT_TYPE,
141 }
142
143 response_data = _token_endpoint_request(request, token_uri, body)
144
145 try:
146 access_token = response_data['access_token']
147 except KeyError:
148 raise exceptions.RefreshError(
149 'No access token in response.', response_data)
150
151 expiry = _parse_expiry(response_data)
152
153 return access_token, expiry, response_data
154
155
156 def refresh_grant(request, token_uri, refresh_token, client_id, client_secret):
157 """Implements the OAuth 2.0 refresh token grant.
158
159 For more details, see `rfc678 section 6`_.
160
161 Args:
162 request (google.auth.transport.Request): A callable used to make
163 HTTP requests.
164 token_uri (str): The OAuth 2.0 authorizations server's token endpoint
165 URI.
166 refresh_token (str): The refresh token to use to get a new access
167 token.
168 client_id (str): The OAuth 2.0 application's client ID.
169 client_secret (str): The Oauth 2.0 appliaction's client secret.
170
171 Returns:
172 Tuple[str, Optional[str], Optional[datetime], Mapping[str, str]]: The
173 access token, new refresh token, expiration, and additional data
174 returned by the token endpoint.
175
176 Raises:
177 google.auth.exceptions.RefreshError: If the token endpoint returned
178 an error.
179
180 .. _rfc6748 section 6: https://tools.ietf.org/html/rfc6749#section-6
181 """
182 body = {
183 'grant_type': _REFRESH_GRANT_TYPE,
184 'client_id': client_id,
185 'client_secret': client_secret,
186 'refresh_token': refresh_token,
187 }
188
189 response_data = _token_endpoint_request(request, token_uri, body)
190
191 try:
192 access_token = response_data['access_token']
193 except KeyError:
194 raise exceptions.RefreshError(
195 'No access token in response.', response_data)
196
197 refresh_token = response_data.get('refresh_token', refresh_token)
198 expiry = _parse_expiry(response_data)
199
200 return access_token, refresh_token, expiry, response_data
OLDNEW
« no previous file with comments | « client/third_party/google/oauth2/__init__.py ('k') | client/third_party/google/oauth2/credentials.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698