This repository was archived by the owner on Jan 18, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 427
Adding dictionary storage for #319. #380
Merged
nathanielmanistaatgoogle
merged 1 commit into
googleapis:master
from
theacodes:add-dictionary-storage
Jan 11, 2016
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| oauth2client.contrib.dictionary_storage module | ||
| ============================================== | ||
|
|
||
| .. automodule:: oauth2client.contrib.dictionary_storage | ||
| :members: | ||
| :undoc-members: | ||
| :show-inheritance: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Copyright 2016 Google Inc. All rights reserved. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| """Dictionary storage for OAuth2 Credentials.""" | ||
|
|
||
| from oauth2client.client import OAuth2Credentials | ||
| from oauth2client.client import Storage | ||
|
|
||
|
|
||
| class DictionaryStorage(Storage): | ||
| """Store and retrieve credentials to and from a dictionary-like object. | ||
|
|
||
| Args: | ||
| dictionary: A dictionary or dictionary-like object. | ||
| key: A string or other hashable. The credentials will be stored in | ||
| ``dictionary[key]``. | ||
| lock: An optional threading.Lock-like object. The lock will be | ||
| acquired before anything is written or read from the | ||
| dictionary. | ||
| """ | ||
|
|
||
| def __init__(self, dictionary, key, lock=None): | ||
| """Construct a DictionaryStorage instance.""" | ||
| super(DictionaryStorage, self).__init__(lock=lock) | ||
| self._dictionary = dictionary | ||
| self._key = key | ||
|
|
||
| def locked_get(self): | ||
| """Retrieve the credentials from the dictionary, if they exist. | ||
|
|
||
| Returns: A :class:`oauth2client.client.OAuth2Credentials` instance. | ||
| """ | ||
| serialized = self._dictionary.get(self._key) | ||
|
|
||
| if serialized is None: | ||
| return None | ||
|
|
||
| credentials = OAuth2Credentials.from_json(serialized) | ||
| credentials.set_store(self) | ||
|
|
||
| return credentials | ||
|
|
||
| def locked_put(self, credentials): | ||
| """Save the credentials to the dictionary. | ||
|
|
||
| Args: | ||
| credentials: A :class:`oauth2client.client.OAuth2Credentials` | ||
| instance. | ||
| """ | ||
| serialized = credentials.to_json() | ||
| self._dictionary[self._key] = serialized | ||
|
|
||
| def locked_delete(self): | ||
| """Remove the credentials from the dictionary, if they exist.""" | ||
| self._dictionary.pop(self._key, None) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # Copyright 2016 Google Inc. All rights reserved. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| """Unit tests for oauth2client.contrib.dictionary_storage""" | ||
|
|
||
| import unittest2 | ||
|
|
||
| from oauth2client import GOOGLE_TOKEN_URI | ||
| from oauth2client.client import OAuth2Credentials | ||
| from oauth2client.contrib.dictionary_storage import DictionaryStorage | ||
|
|
||
|
|
||
| def _generate_credentials(scopes=None): | ||
| return OAuth2Credentials( | ||
| 'access_tokenz', | ||
| 'client_idz', | ||
| 'client_secretz', | ||
| 'refresh_tokenz', | ||
| '3600', | ||
| GOOGLE_TOKEN_URI, | ||
| 'Test', | ||
| id_token={ | ||
| 'sub': '123', | ||
| 'email': 'user@example.com' | ||
| }, | ||
| scopes=scopes) | ||
|
|
||
|
|
||
| class DictionaryStorageTests(unittest2.TestCase): | ||
|
|
||
| def test_constructor_defaults(self): | ||
| dictionary = {} | ||
| key = 'test-key' | ||
| storage = DictionaryStorage(dictionary, key) | ||
|
|
||
| self.assertEqual(dictionary, storage._dictionary) | ||
| self.assertEqual(key, storage._key) | ||
| self.assertIsNone(storage._lock) | ||
|
|
||
| def test_constructor_explicit(self): | ||
| dictionary = {} | ||
| key = 'test-key' | ||
| storage = DictionaryStorage(dictionary, key) | ||
|
|
||
| lock = object() | ||
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
Sorry, something went wrong. |
||
| storage = DictionaryStorage(dictionary, key, lock=lock) | ||
| self.assertEqual(storage._lock, lock) | ||
|
|
||
| def test_get(self): | ||
| credentials = _generate_credentials() | ||
| dictionary = {} | ||
| key = 'credentials' | ||
| storage = DictionaryStorage(dictionary, key) | ||
|
|
||
| self.assertIsNone(storage.get()) | ||
|
|
||
| dictionary[key] = credentials.to_json() | ||
| returned = storage.get() | ||
|
|
||
| self.assertIsNotNone(returned) | ||
| self.assertEqual(returned.access_token, credentials.access_token) | ||
| self.assertEqual(returned.id_token, credentials.id_token) | ||
| self.assertEqual(returned.refresh_token, credentials.refresh_token) | ||
| self.assertEqual(returned.client_id, credentials.client_id) | ||
This comment was marked as spam.
Sorry, something went wrong. |
||
|
|
||
| def test_put(self): | ||
| credentials = _generate_credentials() | ||
| dictionary = {} | ||
| key = 'credentials' | ||
| storage = DictionaryStorage(dictionary, key) | ||
|
|
||
| storage.put(credentials) | ||
| returned = storage.get() | ||
|
|
||
| self.assertIn(key, dictionary) | ||
| self.assertIsNotNone(returned) | ||
| self.assertEqual(returned.access_token, credentials.access_token) | ||
| self.assertEqual(returned.id_token, credentials.id_token) | ||
| self.assertEqual(returned.refresh_token, credentials.refresh_token) | ||
| self.assertEqual(returned.client_id, credentials.client_id) | ||
This comment was marked as spam.
Sorry, something went wrong. |
||
|
|
||
| def test_delete(self): | ||
| credentials = _generate_credentials() | ||
| dictionary = {} | ||
| key = 'credentials' | ||
| storage = DictionaryStorage(dictionary, key) | ||
|
|
||
| storage.put(credentials) | ||
|
|
||
| self.assertIn(key, dictionary) | ||
|
|
||
| storage.delete() | ||
|
|
||
| self.assertNotIn(key, dictionary) | ||
| self.assertIsNone(storage.get()) | ||
|
|
||
|
|
||
| if __name__ == '__main__': # pragma: NO COVER | ||
| unittest2.main() | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This comment was marked as spam.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This comment was marked as spam.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This comment was marked as spam.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.