Automatically reauthenticate to Rietveld
Added automatic detection of OAuth2 token expiracy. Token is
automatically renewed when necessary.
BUG=363825
Review URL: https://codereview.chromium.org/243323003
git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@264871 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/rietveld.py b/rietveld.py
index 97dae6d..d78c017 100644
--- a/rietveld.py
+++ b/rietveld.py
@@ -481,14 +481,14 @@
"OAuth2 support requires it.")
logging.error("Installing pyopenssl will probably solve this issue.")
raise RuntimeError('No OpenSSL support')
- creds = oa2client.SignedJwtAssertionCredentials(
+ self.creds = oa2client.SignedJwtAssertionCredentials(
client_email,
client_private_key,
'https://www.googleapis.com/auth/userinfo.email',
private_key_password=private_key_password,
user_agent=user_agent)
- self._http = creds.authorize(httplib2.Http(timeout=timeout))
+ self._http = self.creds.authorize(httplib2.Http(timeout=timeout))
def Send(self,
request_path,
@@ -525,17 +525,30 @@
if kwargs:
url += "?" + urllib.urlencode(kwargs)
- ret = self._http.request(url,
- method=method,
- body=payload,
- headers=headers)
+ # This weird loop is there to detect when the OAuth2 token has expired.
+ # This is specific to appengine *and* rietveld. It relies on the
+ # assumption that a 302 is triggered only by an expired OAuth2 token. This
+ # prevents any usage of redirections in pages accessed this way.
- if (method == 'GET'
- and not ret[0]['content-location'].startswith(self.host)):
- upload.logging.warning('Redirection to host %s detected: '
- 'login may have failed/expired.'
- % urlparse.urlparse(
- ret[0]['content-location']).netloc)
+ # This variable is used to make sure the following loop runs only twice.
+ redirect_caught = False
+ while True:
+ try:
+ ret = self._http.request(url,
+ method=method,
+ body=payload,
+ headers=headers,
+ redirections=0)
+ except httplib2.RedirectLimit:
+ if redirect_caught or method != 'GET':
+ logging.error('Redirection detected after logging in. Giving up.')
+ raise
+ redirect_caught = True
+ logging.debug('Redirection detected. Trying to log in again...')
+ self.creds.access_token = None
+ continue
+ break
+
return ret[1]
finally: