Index: third_party/oauth2client/file.py |
diff --git a/third_party/oauth2client/file.py b/third_party/oauth2client/file.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1895f94eac58d0386ce59baa86295d27a8a79ec3 |
--- /dev/null |
+++ b/third_party/oauth2client/file.py |
@@ -0,0 +1,124 @@ |
+# Copyright (C) 2010 Google Inc. |
+# |
+# 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. |
+ |
+"""Utilities for OAuth. |
+ |
+Utilities for making it easier to work with OAuth 2.0 |
+credentials. |
+""" |
+ |
+__author__ = 'jcgregorio@google.com (Joe Gregorio)' |
+ |
+import os |
+import stat |
+import threading |
+ |
+from anyjson import simplejson |
+from client import Storage as BaseStorage |
+from client import Credentials |
+ |
+ |
+class CredentialsFileSymbolicLinkError(Exception): |
+ """Credentials files must not be symbolic links.""" |
+ |
+ |
+class Storage(BaseStorage): |
+ """Store and retrieve a single credential to and from a file.""" |
+ |
+ def __init__(self, filename): |
+ self._filename = filename |
+ self._lock = threading.Lock() |
+ |
+ def _validate_file(self): |
+ if os.path.islink(self._filename): |
+ raise CredentialsFileSymbolicLinkError( |
+ 'File: %s is a symbolic link.' % self._filename) |
+ |
+ def acquire_lock(self): |
+ """Acquires any lock necessary to access this Storage. |
+ |
+ This lock is not reentrant.""" |
+ self._lock.acquire() |
+ |
+ def release_lock(self): |
+ """Release the Storage lock. |
+ |
+ Trying to release a lock that isn't held will result in a |
+ RuntimeError. |
+ """ |
+ self._lock.release() |
+ |
+ def locked_get(self): |
+ """Retrieve Credential from file. |
+ |
+ Returns: |
+ oauth2client.client.Credentials |
+ |
+ Raises: |
+ CredentialsFileSymbolicLinkError if the file is a symbolic link. |
+ """ |
+ credentials = None |
+ self._validate_file() |
+ try: |
+ f = open(self._filename, 'rb') |
+ content = f.read() |
+ f.close() |
+ except IOError: |
+ return credentials |
+ |
+ try: |
+ credentials = Credentials.new_from_json(content) |
+ credentials.set_store(self) |
+ except ValueError: |
+ pass |
+ |
+ return credentials |
+ |
+ def _create_file_if_needed(self): |
+ """Create an empty file if necessary. |
+ |
+ This method will not initialize the file. Instead it implements a |
+ simple version of "touch" to ensure the file has been created. |
+ """ |
+ if not os.path.exists(self._filename): |
+ old_umask = os.umask(0177) |
+ try: |
+ open(self._filename, 'a+b').close() |
+ finally: |
+ os.umask(old_umask) |
+ |
+ def locked_put(self, credentials): |
+ """Write Credentials to file. |
+ |
+ Args: |
+ credentials: Credentials, the credentials to store. |
+ |
+ Raises: |
+ CredentialsFileSymbolicLinkError if the file is a symbolic link. |
+ """ |
+ |
+ self._create_file_if_needed() |
+ self._validate_file() |
+ f = open(self._filename, 'wb') |
+ f.write(credentials.to_json()) |
+ f.close() |
+ |
+ def locked_delete(self): |
+ """Delete Credentials file. |
+ |
+ Args: |
+ credentials: Credentials, the credentials to store. |
+ """ |
+ |
+ os.unlink(self._filename) |