Skip to content
This repository was archived by the owner on Jan 18, 2025. It is now read-only.

Commit f3c20ce

Browse files
committed
Check expiration of credentials loaded from store
Today the _refresh logic lazily loads a credential from its store during _refresh, but blindly trusts its validity (no expiry check). This adds a check that the stored credential has not expired before updating from the cache, falling back on the existing uncached path.
1 parent 0a6241c commit f3c20ce

2 files changed

Lines changed: 29 additions & 5 deletions

File tree

oauth2client/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,8 @@ def _refresh(self, http_request):
756756
try:
757757
new_cred = self.store.locked_get()
758758
if (new_cred and not new_cred.invalid and
759-
new_cred.access_token != self.access_token):
759+
new_cred.access_token != self.access_token and
760+
not new_cred.access_token_expired):
760761
logger.info('Updated access_token read from Storage')
761762
self._updateFromCredential(new_cred)
762763
else:

tests/test_file.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import tempfile
3333
import unittest
3434

35+
from .http_mock import HttpMockSequence
3536
from oauth2client import GOOGLE_TOKEN_URI
3637
from oauth2client import file
3738
from oauth2client import locked_file
@@ -64,11 +65,12 @@ def setUp(self):
6465
except OSError:
6566
pass
6667

67-
def create_test_credentials(self, client_id='some_client_id'):
68+
def create_test_credentials(self, client_id='some_client_id',
69+
expiration=None):
6870
access_token = 'foo'
6971
client_secret = 'cOuDdkfjxxnv+'
7072
refresh_token = '1/0/a.df219fjls0'
71-
token_expiry = datetime.datetime.utcnow()
73+
token_expiry = datetime.datetime.utcnow() if not expiration else expiration
7274
token_uri = 'https://www.google.com/accounts/o8/oauth2/token'
7375
user_agent = 'refresh_checker/1.0'
7476

@@ -119,8 +121,29 @@ def test_pickle_and_json_interop(self):
119121
self.assertEquals(data['_class'], 'OAuth2Credentials')
120122
self.assertEquals(data['_module'], OAuth2Credentials.__module__)
121123

122-
def test_token_refresh(self):
123-
credentials = self.create_test_credentials()
124+
def test_token_refresh_store_expired(self):
125+
expiration = datetime.datetime.utcnow() - datetime.timedelta(minutes=15)
126+
credentials = self.create_test_credentials(expiration=expiration)
127+
128+
s = file.Storage(FILENAME)
129+
s.put(credentials)
130+
credentials = s.get()
131+
new_cred = copy.copy(credentials)
132+
new_cred.access_token = 'bar'
133+
s.put(new_cred)
134+
135+
access_token = '1/3w'
136+
token_response = {'access_token': access_token, 'expires_in': 3600}
137+
http = HttpMockSequence([
138+
({'status': '200'}, json.dumps(token_response).encode('utf-8')),
139+
])
140+
141+
credentials._refresh(http.request)
142+
self.assertEquals(credentials.access_token, access_token)
143+
144+
def test_token_refresh_good_store(self):
145+
expiration = datetime.datetime.utcnow() + datetime.timedelta(minutes=15)
146+
credentials = self.create_test_credentials(expiration=expiration)
124147

125148
s = file.Storage(FILENAME)
126149
s.put(credentials)

0 commit comments

Comments
 (0)