OLD | NEW |
1 # coding: utf-8 | 1 # coding: utf-8 |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 """Defines class Rietveld to easily access a rietveld instance. | 5 """Defines class Rietveld to easily access a rietveld instance. |
6 | 6 |
7 Security implications: | 7 Security implications: |
8 | 8 |
9 The following hypothesis are made: | 9 The following hypothesis are made: |
10 - Rietveld enforces: | 10 - Rietveld enforces: |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 | 474 |
475 self.host = self.host.rstrip('/') | 475 self.host = self.host.rstrip('/') |
476 | 476 |
477 self.extra_headers = extra_headers or {} | 477 self.extra_headers = extra_headers or {} |
478 | 478 |
479 if not oa2client.HAS_OPENSSL: | 479 if not oa2client.HAS_OPENSSL: |
480 logging.error("No support for OpenSSL has been found, " | 480 logging.error("No support for OpenSSL has been found, " |
481 "OAuth2 support requires it.") | 481 "OAuth2 support requires it.") |
482 logging.error("Installing pyopenssl will probably solve this issue.") | 482 logging.error("Installing pyopenssl will probably solve this issue.") |
483 raise RuntimeError('No OpenSSL support') | 483 raise RuntimeError('No OpenSSL support') |
484 creds = oa2client.SignedJwtAssertionCredentials( | 484 self.creds = oa2client.SignedJwtAssertionCredentials( |
485 client_email, | 485 client_email, |
486 client_private_key, | 486 client_private_key, |
487 'https://www.googleapis.com/auth/userinfo.email', | 487 'https://www.googleapis.com/auth/userinfo.email', |
488 private_key_password=private_key_password, | 488 private_key_password=private_key_password, |
489 user_agent=user_agent) | 489 user_agent=user_agent) |
490 | 490 |
491 self._http = creds.authorize(httplib2.Http(timeout=timeout)) | 491 self._http = self.creds.authorize(httplib2.Http(timeout=timeout)) |
492 | 492 |
493 def Send(self, | 493 def Send(self, |
494 request_path, | 494 request_path, |
495 payload=None, | 495 payload=None, |
496 content_type='application/octet-stream', | 496 content_type='application/octet-stream', |
497 timeout=None, | 497 timeout=None, |
498 extra_headers=None, | 498 extra_headers=None, |
499 **kwargs): | 499 **kwargs): |
500 """Send a POST or GET request to the server. | 500 """Send a POST or GET request to the server. |
501 | 501 |
(...skipping 16 matching lines...) Expand all Loading... |
518 | 518 |
519 prev_timeout = self._http.timeout | 519 prev_timeout = self._http.timeout |
520 try: | 520 try: |
521 if timeout: | 521 if timeout: |
522 self._http.timeout = timeout | 522 self._http.timeout = timeout |
523 # TODO(pgervais) implement some kind of retry mechanism (see upload.py). | 523 # TODO(pgervais) implement some kind of retry mechanism (see upload.py). |
524 url = self.host + request_path | 524 url = self.host + request_path |
525 if kwargs: | 525 if kwargs: |
526 url += "?" + urllib.urlencode(kwargs) | 526 url += "?" + urllib.urlencode(kwargs) |
527 | 527 |
528 ret = self._http.request(url, | 528 # This weird loop is there to detect when the OAuth2 token has expired. |
529 method=method, | 529 # This is specific to appengine *and* rietveld. It relies on the |
530 body=payload, | 530 # assumption that a 302 is triggered only by an expired OAuth2 token. This |
531 headers=headers) | 531 # prevents any usage of redirections in pages accessed this way. |
532 | 532 |
533 if (method == 'GET' | 533 # This variable is used to make sure the following loop runs only twice. |
534 and not ret[0]['content-location'].startswith(self.host)): | 534 redirect_caught = False |
535 upload.logging.warning('Redirection to host %s detected: ' | 535 while True: |
536 'login may have failed/expired.' | 536 try: |
537 % urlparse.urlparse( | 537 ret = self._http.request(url, |
538 ret[0]['content-location']).netloc) | 538 method=method, |
| 539 body=payload, |
| 540 headers=headers, |
| 541 redirections=0) |
| 542 except httplib2.RedirectLimit: |
| 543 if redirect_caught or method != 'GET': |
| 544 logging.error('Redirection detected after logging in. Giving up.') |
| 545 raise |
| 546 redirect_caught = True |
| 547 logging.debug('Redirection detected. Trying to log in again...') |
| 548 self.creds.access_token = None |
| 549 continue |
| 550 break |
| 551 |
539 return ret[1] | 552 return ret[1] |
540 | 553 |
541 finally: | 554 finally: |
542 self._http.timeout = prev_timeout | 555 self._http.timeout = prev_timeout |
543 | 556 |
544 | 557 |
545 class JwtOAuth2Rietveld(Rietveld): | 558 class JwtOAuth2Rietveld(Rietveld): |
546 """Access to Rietveld using OAuth authentication. | 559 """Access to Rietveld using OAuth authentication. |
547 | 560 |
548 This class is supposed to be used only by bots, since this kind of | 561 This class is supposed to be used only by bots, since this kind of |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 def trigger_try_jobs( # pylint:disable=R0201 | 717 def trigger_try_jobs( # pylint:disable=R0201 |
705 self, issue, patchset, reason, clobber, revision, builders_and_tests, | 718 self, issue, patchset, reason, clobber, revision, builders_and_tests, |
706 master=None): | 719 master=None): |
707 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' % | 720 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' % |
708 (builders_and_tests, issue)) | 721 (builders_and_tests, issue)) |
709 | 722 |
710 def trigger_distributed_try_jobs( # pylint:disable=R0201 | 723 def trigger_distributed_try_jobs( # pylint:disable=R0201 |
711 self, issue, patchset, reason, clobber, revision, masters): | 724 self, issue, patchset, reason, clobber, revision, masters): |
712 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' % | 725 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' % |
713 (masters, issue)) | 726 (masters, issue)) |
OLD | NEW |