blob: 07e76082885df1e076f1445682691a2265d0e1d9 [file] [log] [blame]
Joe Gregorio562b7312011-09-15 09:06:38 -04001#!/usr/bin/python2.4
2#
3# Copyright 2010 Google Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17
18"""Oauth2client.file tests
19
20Unit tests for oauth2client.file
21"""
22
23__author__ = 'jcgregorio@google.com (Joe Gregorio)'
24
Joe Gregoriod2ee4d82011-09-15 14:32:45 -040025import copy
Joe Beda17311fb2011-09-20 14:43:08 -070026import datetime
27import httplib2
Joe Gregorio562b7312011-09-15 09:06:38 -040028import os
29import pickle
Joe Gregorio9b8bec62012-01-17 11:35:32 -050030import stat
Joe Beda17311fb2011-09-20 14:43:08 -070031import tempfile
Joe Gregorio562b7312011-09-15 09:06:38 -040032import unittest
Joe Gregorio562b7312011-09-15 09:06:38 -040033
Joe Gregoriod2ee4d82011-09-15 14:32:45 -040034from apiclient.http import HttpMockSequence
Joe Gregorio0fd18532012-08-24 15:54:40 -040035from oauth2client import file
36from oauth2client import locked_file
Joe Gregorio549230c2012-01-11 10:38:05 -050037from oauth2client import multistore_file
Joe Gregorioe2233cd2013-01-24 15:46:23 -050038from oauth2client import util
Joe Gregorio549230c2012-01-11 10:38:05 -050039from oauth2client.anyjson import simplejson
Joe Gregorio562b7312011-09-15 09:06:38 -040040from oauth2client.client import AccessTokenCredentials
41from oauth2client.client import AssertionCredentials
Joe Gregorio549230c2012-01-11 10:38:05 -050042from oauth2client.client import OAuth2Credentials
Joe Gregorio562b7312011-09-15 09:06:38 -040043
44
Joe Beda17311fb2011-09-20 14:43:08 -070045FILENAME = tempfile.mktemp('oauth2client_test.data')
Joe Gregorio562b7312011-09-15 09:06:38 -040046
47
48class OAuth2ClientFileTests(unittest.TestCase):
49
50 def tearDown(self):
51 try:
52 os.unlink(FILENAME)
53 except OSError:
54 pass
55
56 def setUp(self):
57 try:
58 os.unlink(FILENAME)
59 except OSError:
60 pass
61
Joe Gregorioe2233cd2013-01-24 15:46:23 -050062 def create_test_credentials(self):
63 access_token = 'foo'
64 client_secret = 'cOuDdkfjxxnv+'
65 refresh_token = '1/0/a.df219fjls0'
66 token_expiry = datetime.datetime.utcnow()
67 token_uri = 'https://www.google.com/accounts/o8/oauth2/token'
68 user_agent = 'refresh_checker/1.0'
69 client_id = 'some_client_id'
70
71 credentials = OAuth2Credentials(
72 access_token, client_id, client_secret,
73 refresh_token, token_expiry, token_uri,
74 user_agent)
75 return credentials
76
Joe Gregorio562b7312011-09-15 09:06:38 -040077 def test_non_existent_file_storage(self):
Joe Gregorio0fd18532012-08-24 15:54:40 -040078 s = file.Storage(FILENAME)
Joe Gregorio562b7312011-09-15 09:06:38 -040079 credentials = s.get()
80 self.assertEquals(None, credentials)
81
Joe Gregorio0fd18532012-08-24 15:54:40 -040082 def test_no_sym_link_credentials(self):
83 if hasattr(os, 'symlink'):
84 SYMFILENAME = FILENAME + '.sym'
85 os.symlink(FILENAME, SYMFILENAME)
86 s = file.Storage(SYMFILENAME)
87 try:
88 s.get()
89 self.fail('Should have raised an exception.')
90 except file.CredentialsFileSymbolicLinkError:
91 pass
92 finally:
93 os.unlink(SYMFILENAME)
94
Joe Gregorio562b7312011-09-15 09:06:38 -040095 def test_pickle_and_json_interop(self):
96 # Write a file with a pickled OAuth2Credentials.
Joe Gregorioe2233cd2013-01-24 15:46:23 -050097 credentials = self.create_test_credentials()
Joe Gregorio562b7312011-09-15 09:06:38 -040098
99 f = open(FILENAME, 'w')
100 pickle.dump(credentials, f)
101 f.close()
102
Joe Gregorioec555842011-10-27 11:10:39 -0400103 # Storage should be not be able to read that object, as the capability to
104 # read and write credentials as pickled objects has been removed.
Joe Gregorio0fd18532012-08-24 15:54:40 -0400105 s = file.Storage(FILENAME)
Joe Gregorioec555842011-10-27 11:10:39 -0400106 read_credentials = s.get()
107 self.assertEquals(None, read_credentials)
Joe Gregorio562b7312011-09-15 09:06:38 -0400108
109 # Now write it back out and confirm it has been rewritten as JSON
110 s.put(credentials)
Joe Gregorio0fd18532012-08-24 15:54:40 -0400111 f = open(FILENAME)
Joe Gregorio562b7312011-09-15 09:06:38 -0400112 data = simplejson.load(f)
113 f.close()
114
115 self.assertEquals(data['access_token'], 'foo')
116 self.assertEquals(data['_class'], 'OAuth2Credentials')
Joe Beda17311fb2011-09-20 14:43:08 -0700117 self.assertEquals(data['_module'], OAuth2Credentials.__module__)
Joe Gregorio562b7312011-09-15 09:06:38 -0400118
Joe Gregoriod2ee4d82011-09-15 14:32:45 -0400119 def test_token_refresh(self):
Joe Gregorioe2233cd2013-01-24 15:46:23 -0500120 credentials = self.create_test_credentials()
Joe Gregoriod2ee4d82011-09-15 14:32:45 -0400121
Joe Gregorio0fd18532012-08-24 15:54:40 -0400122 s = file.Storage(FILENAME)
Joe Gregoriod2ee4d82011-09-15 14:32:45 -0400123 s.put(credentials)
124 credentials = s.get()
125 new_cred = copy.copy(credentials)
126 new_cred.access_token = 'bar'
127 s.put(new_cred)
128
129 credentials._refresh(lambda x: x)
130 self.assertEquals(credentials.access_token, 'bar')
131
Joe Gregorioec75dc12012-02-06 13:40:42 -0500132 def test_credentials_delete(self):
Joe Gregorioe2233cd2013-01-24 15:46:23 -0500133 credentials = self.create_test_credentials()
Joe Gregorioec75dc12012-02-06 13:40:42 -0500134
Joe Gregorio0fd18532012-08-24 15:54:40 -0400135 s = file.Storage(FILENAME)
Joe Gregorioec75dc12012-02-06 13:40:42 -0500136 s.put(credentials)
137 credentials = s.get()
138 self.assertNotEquals(None, credentials)
139 s.delete()
140 credentials = s.get()
141 self.assertEquals(None, credentials)
Joe Gregoriod2ee4d82011-09-15 14:32:45 -0400142
Joe Gregorio562b7312011-09-15 09:06:38 -0400143 def test_access_token_credentials(self):
144 access_token = 'foo'
145 user_agent = 'refresh_checker/1.0'
146
147 credentials = AccessTokenCredentials(access_token, user_agent)
148
Joe Gregorio0fd18532012-08-24 15:54:40 -0400149 s = file.Storage(FILENAME)
Joe Gregorio562b7312011-09-15 09:06:38 -0400150 credentials = s.put(credentials)
151 credentials = s.get()
152
153 self.assertNotEquals(None, credentials)
154 self.assertEquals('foo', credentials.access_token)
Joe Gregorio9b8bec62012-01-17 11:35:32 -0500155 mode = os.stat(FILENAME).st_mode
156
157 if os.name == 'posix':
158 self.assertEquals('0600', oct(stat.S_IMODE(os.stat(FILENAME).st_mode)))
159
160 def test_read_only_file_fail_lock(self):
Joe Gregorioe2233cd2013-01-24 15:46:23 -0500161 credentials = self.create_test_credentials()
Joe Gregorio9b8bec62012-01-17 11:35:32 -0500162
163 open(FILENAME, 'a+b').close()
164 os.chmod(FILENAME, 0400)
165
166 store = multistore_file.get_credential_storage(
167 FILENAME,
168 credentials.client_id,
169 credentials.user_agent,
170 ['some-scope', 'some-other-scope'])
171
172 store.put(credentials)
173 if os.name == 'posix':
174 self.assertTrue(store._multistore._read_only)
175 os.chmod(FILENAME, 0600)
176
Joe Gregorio0fd18532012-08-24 15:54:40 -0400177 def test_multistore_no_symbolic_link_files(self):
178 if hasattr(os, 'symlink'):
179 SYMFILENAME = FILENAME + 'sym'
180 os.symlink(FILENAME, SYMFILENAME)
181 store = multistore_file.get_credential_storage(
182 SYMFILENAME,
183 'some_client_id',
184 'user-agent/1.0',
185 ['some-scope', 'some-other-scope'])
186 try:
187 store.get()
188 self.fail('Should have raised an exception.')
189 except locked_file.CredentialsFileSymbolicLinkError:
190 pass
191 finally:
192 os.unlink(SYMFILENAME)
Joe Gregorio562b7312011-09-15 09:06:38 -0400193
194 def test_multistore_non_existent_file(self):
195 store = multistore_file.get_credential_storage(
196 FILENAME,
197 'some_client_id',
198 'user-agent/1.0',
Joe Gregoriof2f8a5a2011-10-14 15:11:29 -0400199 ['some-scope', 'some-other-scope'])
Joe Gregorio562b7312011-09-15 09:06:38 -0400200
201 credentials = store.get()
202 self.assertEquals(None, credentials)
203
204 def test_multistore_file(self):
Joe Gregorioe2233cd2013-01-24 15:46:23 -0500205 credentials = self.create_test_credentials()
Joe Gregorio562b7312011-09-15 09:06:38 -0400206
207 store = multistore_file.get_credential_storage(
208 FILENAME,
209 credentials.client_id,
210 credentials.user_agent,
Joe Gregoriof2f8a5a2011-10-14 15:11:29 -0400211 ['some-scope', 'some-other-scope'])
Joe Gregorio562b7312011-09-15 09:06:38 -0400212
213 store.put(credentials)
214 credentials = store.get()
215
216 self.assertNotEquals(None, credentials)
217 self.assertEquals('foo', credentials.access_token)
218
Joe Gregorioec75dc12012-02-06 13:40:42 -0500219 store.delete()
220 credentials = store.get()
221
222 self.assertEquals(None, credentials)
223
Joe Gregorio9b8bec62012-01-17 11:35:32 -0500224 if os.name == 'posix':
225 self.assertEquals('0600', oct(stat.S_IMODE(os.stat(FILENAME).st_mode)))
226
Joe Gregorioe2233cd2013-01-24 15:46:23 -0500227 def test_multistore_file_custom_key(self):
228 credentials = self.create_test_credentials()
229
230 custom_key = {'myapp': 'testing', 'clientid': 'some client'}
231 store = multistore_file.get_credential_storage_custom_key(
232 FILENAME, custom_key)
233
234 store.put(credentials)
235 stored_credentials = store.get()
236
237 self.assertNotEquals(None, stored_credentials)
238 self.assertEqual(credentials.access_token, stored_credentials.access_token)
239
240 store.delete()
241 stored_credentials = store.get()
242
243 self.assertEquals(None, stored_credentials)
244
245 def test_multistore_file_custom_string_key(self):
246 credentials = self.create_test_credentials()
247
248 # store with string key
249 store = multistore_file.get_credential_storage_custom_string_key(
250 FILENAME, 'mykey')
251
252 store.put(credentials)
253 stored_credentials = store.get()
254
255 self.assertNotEquals(None, stored_credentials)
256 self.assertEqual(credentials.access_token, stored_credentials.access_token)
257
258 # try retrieving with a dictionary
259 store_dict = multistore_file.get_credential_storage_custom_string_key(
260 FILENAME, {'key': 'mykey'})
261 stored_credentials = store.get()
262 self.assertNotEquals(None, stored_credentials)
263 self.assertEqual(credentials.access_token, stored_credentials.access_token)
264
265 store.delete()
266 stored_credentials = store.get()
267
268 self.assertEquals(None, stored_credentials)
269
270 def test_multistore_file_backwards_compatibility(self):
271 credentials = self.create_test_credentials()
272 scopes = ['scope1', 'scope2']
273
274 # store the credentials using the legacy key method
275 store = multistore_file.get_credential_storage(
276 FILENAME, 'client_id', 'user_agent', scopes)
277 store.put(credentials)
278
279 # retrieve the credentials using a custom key that matches the legacy key
280 key = {'clientId': 'client_id', 'userAgent': 'user_agent',
281 'scope': util.scopes_to_string(scopes)}
282 store = multistore_file.get_credential_storage_custom_key(FILENAME, key)
283 stored_credentials = store.get()
284
285 self.assertEqual(credentials.access_token, stored_credentials.access_token)
286
Joe Gregorio562b7312011-09-15 09:06:38 -0400287if __name__ == '__main__':
288 unittest.main()