OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Google OAuth2 related functions.""" | 5 """Google OAuth2 related functions.""" |
6 | 6 |
7 import BaseHTTPServer | 7 import BaseHTTPServer |
8 import collections | 8 import collections |
9 import datetime | 9 import datetime |
10 import functools | 10 import functools |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 # Adapted from oauth2client.OAuth2Credentials.authorize. | 322 # Adapted from oauth2client.OAuth2Credentials.authorize. |
323 | 323 |
324 request_orig = http.request | 324 request_orig = http.request |
325 | 325 |
326 @functools.wraps(request_orig) | 326 @functools.wraps(request_orig) |
327 def new_request( | 327 def new_request( |
328 uri, method='GET', body=None, headers=None, | 328 uri, method='GET', body=None, headers=None, |
329 redirections=httplib2.DEFAULT_MAX_REDIRECTS, | 329 redirections=httplib2.DEFAULT_MAX_REDIRECTS, |
330 connection_type=None): | 330 connection_type=None): |
331 headers = (headers or {}).copy() | 331 headers = (headers or {}).copy() |
332 headers['Authorizaton'] = 'Bearer %s' % self.get_access_token().token | 332 headers['Authorization'] = 'Bearer %s' % self.get_access_token().token |
333 resp, content = request_orig( | 333 resp, content = request_orig( |
334 uri, method, body, headers, redirections, connection_type) | 334 uri, method, body, headers, redirections, connection_type) |
335 if resp.status in client.REFRESH_STATUS_CODES: | 335 if resp.status in client.REFRESH_STATUS_CODES: |
336 logging.info('Refreshing due to a %s', resp.status) | 336 logging.info('Refreshing due to a %s', resp.status) |
337 access_token = self.get_access_token(force_refresh=True) | 337 access_token = self.get_access_token(force_refresh=True) |
338 headers['Authorizaton'] = 'Bearer %s' % access_token.token | 338 headers['Authorization'] = 'Bearer %s' % access_token.token |
339 return request_orig( | 339 return request_orig( |
340 uri, method, body, headers, redirections, connection_type) | 340 uri, method, body, headers, redirections, connection_type) |
341 else: | 341 else: |
342 return (resp, content) | 342 return (resp, content) |
343 | 343 |
344 http.request = new_request | 344 http.request = new_request |
345 return http | 345 return http |
346 | 346 |
347 ## Private methods. | 347 ## Private methods. |
348 | 348 |
349 def _get_storage(self): | 349 def _get_storage(self): |
350 """Returns oauth2client.Storage with cached tokens.""" | 350 """Returns oauth2client.Storage with cached tokens.""" |
351 return multistore_file.get_credential_storage_custom_string_key( | 351 return multistore_file.get_credential_storage_custom_string_key( |
352 OAUTH_TOKENS_CACHE, self._token_cache_key) | 352 OAUTH_TOKENS_CACHE, self._token_cache_key) |
353 | 353 |
354 def _load_access_token(self): | 354 def _load_access_token(self): |
355 """Returns cached AccessToken if it is not expired yet.""" | 355 """Returns cached AccessToken if it is not expired yet.""" |
356 credentials = self._get_storage().get() | 356 credentials = self._get_storage().get() |
357 if not credentials or credentials.invalid: | 357 if not credentials or credentials.invalid: |
358 return None | 358 return None |
359 if not credentials.access_token or credentials.access_token_expired: | 359 if not credentials.access_token or credentials.access_token_expired: |
360 return None | 360 return None |
361 return AccessToken(credentials.access_token, credentials.token_expiry) | 361 return AccessToken(str(credentials.access_token), credentials.token_expiry) |
362 | 362 |
363 def _create_access_token(self, allow_user_interaction=False): | 363 def _create_access_token(self, allow_user_interaction=False): |
364 """Mints and caches a new access token, launching OAuth2 dance if necessary. | 364 """Mints and caches a new access token, launching OAuth2 dance if necessary. |
365 | 365 |
366 Uses cached refresh token, if present. In that case user interaction is not | 366 Uses cached refresh token, if present. In that case user interaction is not |
367 required and function will finish quietly. Otherwise it will launch 3-legged | 367 required and function will finish quietly. Otherwise it will launch 3-legged |
368 OAuth2 flow, that needs user interaction. | 368 OAuth2 flow, that needs user interaction. |
369 | 369 |
370 Args: | 370 Args: |
371 allow_user_interaction: if True, allow interaction with the user (e.g. | 371 allow_user_interaction: if True, allow interaction with the user (e.g. |
(...skipping 26 matching lines...) Expand all Loading... |
398 if not refreshed: | 398 if not refreshed: |
399 if not allow_user_interaction: | 399 if not allow_user_interaction: |
400 raise LoginRequiredError(self._token_cache_key) | 400 raise LoginRequiredError(self._token_cache_key) |
401 credentials = _run_oauth_dance(self._config) | 401 credentials = _run_oauth_dance(self._config) |
402 | 402 |
403 logging.info( | 403 logging.info( |
404 'OAuth access_token refreshed. Expires in %s.', | 404 'OAuth access_token refreshed. Expires in %s.', |
405 credentials.token_expiry - datetime.datetime.utcnow()) | 405 credentials.token_expiry - datetime.datetime.utcnow()) |
406 credentials.set_store(storage) | 406 credentials.set_store(storage) |
407 storage.put(credentials) | 407 storage.put(credentials) |
408 return AccessToken(credentials.access_token, credentials.token_expiry) | 408 return AccessToken(str(credentials.access_token), credentials.token_expiry) |
409 | 409 |
410 | 410 |
411 ## Private functions. | 411 ## Private functions. |
412 | 412 |
413 | 413 |
414 def _should_use_oauth2(): | 414 def _should_use_oauth2(): |
415 """Default value for use_oauth2 config option. | 415 """Default value for use_oauth2 config option. |
416 | 416 |
417 Used to selectively enable OAuth2 by default. | 417 Used to selectively enable OAuth2 by default. |
418 """ | 418 """ |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 self.end_headers() | 540 self.end_headers() |
541 query = self.path.split('?', 1)[-1] | 541 query = self.path.split('?', 1)[-1] |
542 query = dict(urlparse.parse_qsl(query)) | 542 query = dict(urlparse.parse_qsl(query)) |
543 self.server.query_params = query | 543 self.server.query_params = query |
544 self.wfile.write('<html><head><title>Authentication Status</title></head>') | 544 self.wfile.write('<html><head><title>Authentication Status</title></head>') |
545 self.wfile.write('<body><p>The authentication flow has completed.</p>') | 545 self.wfile.write('<body><p>The authentication flow has completed.</p>') |
546 self.wfile.write('</body></html>') | 546 self.wfile.write('</body></html>') |
547 | 547 |
548 def log_message(self, _format, *args): | 548 def log_message(self, _format, *args): |
549 """Do not log messages to stdout while running as command line program.""" | 549 """Do not log messages to stdout while running as command line program.""" |
OLD | NEW |