googlecloud 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +4 -0
  3. data/LICENSE +674 -0
  4. data/Manifest +111 -0
  5. data/README.md +4 -3
  6. data/bin/gcutil +53 -0
  7. data/googlecloud.gemspec +4 -3
  8. data/packages/gcutil-1.7.1/CHANGELOG +197 -0
  9. data/packages/gcutil-1.7.1/LICENSE +202 -0
  10. data/packages/gcutil-1.7.1/VERSION +1 -0
  11. data/packages/gcutil-1.7.1/gcutil +53 -0
  12. data/packages/gcutil-1.7.1/lib/google_api_python_client/LICENSE +23 -0
  13. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/__init__.py +1 -0
  14. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/discovery.py +743 -0
  15. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/errors.py +123 -0
  16. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/ext/__init__.py +0 -0
  17. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/http.py +1443 -0
  18. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/mimeparse.py +172 -0
  19. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/model.py +385 -0
  20. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/schema.py +303 -0
  21. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/__init__.py +1 -0
  22. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/anyjson.py +32 -0
  23. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/appengine.py +528 -0
  24. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/client.py +1139 -0
  25. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/clientsecrets.py +105 -0
  26. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/crypt.py +244 -0
  27. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/django_orm.py +124 -0
  28. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/file.py +107 -0
  29. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/locked_file.py +343 -0
  30. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/multistore_file.py +379 -0
  31. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/tools.py +174 -0
  32. data/packages/gcutil-1.7.1/lib/google_api_python_client/uritemplate/__init__.py +147 -0
  33. data/packages/gcutil-1.7.1/lib/google_apputils/LICENSE +202 -0
  34. data/packages/gcutil-1.7.1/lib/google_apputils/google/__init__.py +3 -0
  35. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/__init__.py +3 -0
  36. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/app.py +356 -0
  37. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.py +783 -0
  38. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/basetest.py +1260 -0
  39. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/datelib.py +421 -0
  40. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/debug.py +60 -0
  41. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/file_util.py +181 -0
  42. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/resources.py +67 -0
  43. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/run_script_module.py +217 -0
  44. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/setup_command.py +159 -0
  45. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/shellutil.py +49 -0
  46. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/stopwatch.py +204 -0
  47. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/__init__.py +0 -0
  48. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper.py +140 -0
  49. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper_test.py +149 -0
  50. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth.py +130 -0
  51. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth_test.py +75 -0
  52. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds.py +128 -0
  53. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds_test.py +111 -0
  54. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base.py +1808 -0
  55. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base_test.py +1651 -0
  56. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta13.json +2851 -0
  57. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta14.json +3361 -0
  58. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds.py +342 -0
  59. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds_test.py +474 -0
  60. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds.py +344 -0
  61. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds_test.py +231 -0
  62. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/flags_cache.py +274 -0
  63. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil +89 -0
  64. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil_logging.py +69 -0
  65. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds.py +262 -0
  66. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds_test.py +172 -0
  67. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds.py +1506 -0
  68. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds_test.py +1904 -0
  69. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds.py +91 -0
  70. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds_test.py +56 -0
  71. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds.py +106 -0
  72. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds_test.py +59 -0
  73. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata.py +96 -0
  74. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_lib.py +357 -0
  75. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_test.py +84 -0
  76. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_api.py +420 -0
  77. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_metadata.py +58 -0
  78. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds.py +824 -0
  79. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds_test.py +307 -0
  80. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds.py +178 -0
  81. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds_test.py +133 -0
  82. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds.py +181 -0
  83. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds_test.py +196 -0
  84. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/path_initializer.py +38 -0
  85. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds.py +173 -0
  86. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds_test.py +111 -0
  87. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes.py +61 -0
  88. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes_test.py +50 -0
  89. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds.py +276 -0
  90. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds_test.py +260 -0
  91. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys.py +266 -0
  92. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys_test.py +128 -0
  93. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/table_formatter.py +563 -0
  94. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool.py +188 -0
  95. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool_test.py +88 -0
  96. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils.py +208 -0
  97. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils_test.py +193 -0
  98. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version.py +17 -0
  99. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker.py +246 -0
  100. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker_test.py +271 -0
  101. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds.py +151 -0
  102. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds_test.py +60 -0
  103. data/packages/gcutil-1.7.1/lib/httplib2/LICENSE +21 -0
  104. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/__init__.py +1630 -0
  105. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/cacerts.txt +714 -0
  106. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/iri2uri.py +110 -0
  107. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/socks.py +438 -0
  108. data/packages/gcutil-1.7.1/lib/iso8601/LICENSE +20 -0
  109. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/__init__.py +1 -0
  110. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/iso8601.py +102 -0
  111. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/test_iso8601.py +111 -0
  112. data/packages/gcutil-1.7.1/lib/python_gflags/AUTHORS +2 -0
  113. data/packages/gcutil-1.7.1/lib/python_gflags/LICENSE +28 -0
  114. data/packages/gcutil-1.7.1/lib/python_gflags/gflags.py +2862 -0
  115. data/packages/gcutil-1.7.1/lib/python_gflags/gflags2man.py +544 -0
  116. data/packages/gcutil-1.7.1/lib/python_gflags/gflags_validators.py +187 -0
  117. metadata +118 -5
  118. metadata.gz.sig +0 -0
@@ -0,0 +1,105 @@
1
+ # Copyright (C) 2011 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Utilities for reading OAuth 2.0 client secret files.
16
+
17
+ A client_secrets.json file contains all the information needed to interact with
18
+ an OAuth 2.0 protected service.
19
+ """
20
+
21
+
22
+
23
+
24
+ from anyjson import simplejson
25
+
26
+ # Properties that make a client_secrets.json file valid.
27
+ TYPE_WEB = 'web'
28
+ TYPE_INSTALLED = 'installed'
29
+
30
+ VALID_CLIENT = {
31
+ TYPE_WEB: {
32
+ 'required': [
33
+ 'client_id',
34
+ 'client_secret',
35
+ 'redirect_uris',
36
+ 'auth_uri',
37
+ 'token_uri'],
38
+ 'string': [
39
+ 'client_id',
40
+ 'client_secret'
41
+ ]
42
+ },
43
+ TYPE_INSTALLED: {
44
+ 'required': [
45
+ 'client_id',
46
+ 'client_secret',
47
+ 'redirect_uris',
48
+ 'auth_uri',
49
+ 'token_uri'],
50
+ 'string': [
51
+ 'client_id',
52
+ 'client_secret'
53
+ ]
54
+ }
55
+ }
56
+
57
+ class Error(Exception):
58
+ """Base error for this module."""
59
+ pass
60
+
61
+
62
+ class InvalidClientSecretsError(Error):
63
+ """Format of ClientSecrets file is invalid."""
64
+ pass
65
+
66
+
67
+ def _validate_clientsecrets(obj):
68
+ if obj is None or len(obj) != 1:
69
+ raise InvalidClientSecretsError('Invalid file format.')
70
+ client_type = obj.keys()[0]
71
+ if client_type not in VALID_CLIENT.keys():
72
+ raise InvalidClientSecretsError('Unknown client type: %s.' % client_type)
73
+ client_info = obj[client_type]
74
+ for prop_name in VALID_CLIENT[client_type]['required']:
75
+ if prop_name not in client_info:
76
+ raise InvalidClientSecretsError(
77
+ 'Missing property "%s" in a client type of "%s".' % (prop_name,
78
+ client_type))
79
+ for prop_name in VALID_CLIENT[client_type]['string']:
80
+ if client_info[prop_name].startswith('[['):
81
+ raise InvalidClientSecretsError(
82
+ 'Property "%s" is not configured.' % prop_name)
83
+ return client_type, client_info
84
+
85
+
86
+ def load(fp):
87
+ obj = simplejson.load(fp)
88
+ return _validate_clientsecrets(obj)
89
+
90
+
91
+ def loads(s):
92
+ obj = simplejson.loads(s)
93
+ return _validate_clientsecrets(obj)
94
+
95
+
96
+ def loadfile(filename):
97
+ try:
98
+ fp = file(filename, 'r')
99
+ try:
100
+ obj = simplejson.load(fp)
101
+ finally:
102
+ fp.close()
103
+ except IOError:
104
+ raise InvalidClientSecretsError('File not found: "%s"' % filename)
105
+ return _validate_clientsecrets(obj)
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/python2.4
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright (C) 2011 Google Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ import base64
19
+ import hashlib
20
+ import logging
21
+ import time
22
+
23
+ from OpenSSL import crypto
24
+ from anyjson import simplejson
25
+
26
+
27
+ CLOCK_SKEW_SECS = 300 # 5 minutes in seconds
28
+ AUTH_TOKEN_LIFETIME_SECS = 300 # 5 minutes in seconds
29
+ MAX_TOKEN_LIFETIME_SECS = 86400 # 1 day in seconds
30
+
31
+
32
+ class AppIdentityError(Exception):
33
+ pass
34
+
35
+
36
+ class Verifier(object):
37
+ """Verifies the signature on a message."""
38
+
39
+ def __init__(self, pubkey):
40
+ """Constructor.
41
+
42
+ Args:
43
+ pubkey, OpenSSL.crypto.PKey, The public key to verify with.
44
+ """
45
+ self._pubkey = pubkey
46
+
47
+ def verify(self, message, signature):
48
+ """Verifies a message against a signature.
49
+
50
+ Args:
51
+ message: string, The message to verify.
52
+ signature: string, The signature on the message.
53
+
54
+ Returns:
55
+ True if message was singed by the private key associated with the public
56
+ key that this object was constructed with.
57
+ """
58
+ try:
59
+ crypto.verify(self._pubkey, signature, message, 'sha256')
60
+ return True
61
+ except:
62
+ return False
63
+
64
+ @staticmethod
65
+ def from_string(key_pem, is_x509_cert):
66
+ """Construct a Verified instance from a string.
67
+
68
+ Args:
69
+ key_pem: string, public key in PEM format.
70
+ is_x509_cert: bool, True if key_pem is an X509 cert, otherwise it is
71
+ expected to be an RSA key in PEM format.
72
+
73
+ Returns:
74
+ Verifier instance.
75
+
76
+ Raises:
77
+ OpenSSL.crypto.Error if the key_pem can't be parsed.
78
+ """
79
+ if is_x509_cert:
80
+ pubkey = crypto.load_certificate(crypto.FILETYPE_PEM, key_pem)
81
+ else:
82
+ pubkey = crypto.load_privatekey(crypto.FILETYPE_PEM, key_pem)
83
+ return Verifier(pubkey)
84
+
85
+
86
+ class Signer(object):
87
+ """Signs messages with a private key."""
88
+
89
+ def __init__(self, pkey):
90
+ """Constructor.
91
+
92
+ Args:
93
+ pkey, OpenSSL.crypto.PKey, The private key to sign with.
94
+ """
95
+ self._key = pkey
96
+
97
+ def sign(self, message):
98
+ """Signs a message.
99
+
100
+ Args:
101
+ message: string, Message to be signed.
102
+
103
+ Returns:
104
+ string, The signature of the message for the given key.
105
+ """
106
+ return crypto.sign(self._key, message, 'sha256')
107
+
108
+ @staticmethod
109
+ def from_string(key, password='notasecret'):
110
+ """Construct a Signer instance from a string.
111
+
112
+ Args:
113
+ key: string, private key in P12 format.
114
+ password: string, password for the private key file.
115
+
116
+ Returns:
117
+ Signer instance.
118
+
119
+ Raises:
120
+ OpenSSL.crypto.Error if the key can't be parsed.
121
+ """
122
+ pkey = crypto.load_pkcs12(key, password).get_privatekey()
123
+ return Signer(pkey)
124
+
125
+
126
+ def _urlsafe_b64encode(raw_bytes):
127
+ return base64.urlsafe_b64encode(raw_bytes).rstrip('=')
128
+
129
+
130
+ def _urlsafe_b64decode(b64string):
131
+ # Guard against unicode strings, which base64 can't handle.
132
+ b64string = b64string.encode('ascii')
133
+ padded = b64string + '=' * (4 - len(b64string) % 4)
134
+ return base64.urlsafe_b64decode(padded)
135
+
136
+
137
+ def _json_encode(data):
138
+ return simplejson.dumps(data, separators = (',', ':'))
139
+
140
+
141
+ def make_signed_jwt(signer, payload):
142
+ """Make a signed JWT.
143
+
144
+ See http://self-issued.info/docs/draft-jones-json-web-token.html.
145
+
146
+ Args:
147
+ signer: crypt.Signer, Cryptographic signer.
148
+ payload: dict, Dictionary of data to convert to JSON and then sign.
149
+
150
+ Returns:
151
+ string, The JWT for the payload.
152
+ """
153
+ header = {'typ': 'JWT', 'alg': 'RS256'}
154
+
155
+ segments = [
156
+ _urlsafe_b64encode(_json_encode(header)),
157
+ _urlsafe_b64encode(_json_encode(payload)),
158
+ ]
159
+ signing_input = '.'.join(segments)
160
+
161
+ signature = signer.sign(signing_input)
162
+ segments.append(_urlsafe_b64encode(signature))
163
+
164
+ logging.debug(str(segments))
165
+
166
+ return '.'.join(segments)
167
+
168
+
169
+ def verify_signed_jwt_with_certs(jwt, certs, audience):
170
+ """Verify a JWT against public certs.
171
+
172
+ See http://self-issued.info/docs/draft-jones-json-web-token.html.
173
+
174
+ Args:
175
+ jwt: string, A JWT.
176
+ certs: dict, Dictionary where values of public keys in PEM format.
177
+ audience: string, The audience, 'aud', that this JWT should contain. If
178
+ None then the JWT's 'aud' parameter is not verified.
179
+
180
+ Returns:
181
+ dict, The deserialized JSON payload in the JWT.
182
+
183
+ Raises:
184
+ AppIdentityError if any checks are failed.
185
+ """
186
+ segments = jwt.split('.')
187
+
188
+ if (len(segments) != 3):
189
+ raise AppIdentityError(
190
+ 'Wrong number of segments in token: %s' % jwt)
191
+ signed = '%s.%s' % (segments[0], segments[1])
192
+
193
+ signature = _urlsafe_b64decode(segments[2])
194
+
195
+ # Parse token.
196
+ json_body = _urlsafe_b64decode(segments[1])
197
+ try:
198
+ parsed = simplejson.loads(json_body)
199
+ except:
200
+ raise AppIdentityError('Can\'t parse token: %s' % json_body)
201
+
202
+ # Check signature.
203
+ verified = False
204
+ for (keyname, pem) in certs.items():
205
+ verifier = Verifier.from_string(pem, True)
206
+ if (verifier.verify(signed, signature)):
207
+ verified = True
208
+ break
209
+ if not verified:
210
+ raise AppIdentityError('Invalid token signature: %s' % jwt)
211
+
212
+ # Check creation timestamp.
213
+ iat = parsed.get('iat')
214
+ if iat is None:
215
+ raise AppIdentityError('No iat field in token: %s' % json_body)
216
+ earliest = iat - CLOCK_SKEW_SECS
217
+
218
+ # Check expiration timestamp.
219
+ now = long(time.time())
220
+ exp = parsed.get('exp')
221
+ if exp is None:
222
+ raise AppIdentityError('No exp field in token: %s' % json_body)
223
+ if exp >= now + MAX_TOKEN_LIFETIME_SECS:
224
+ raise AppIdentityError(
225
+ 'exp field too far in future: %s' % json_body)
226
+ latest = exp + CLOCK_SKEW_SECS
227
+
228
+ if now < earliest:
229
+ raise AppIdentityError('Token used too early, %d < %d: %s' %
230
+ (now, earliest, json_body))
231
+ if now > latest:
232
+ raise AppIdentityError('Token used too late, %d > %d: %s' %
233
+ (now, latest, json_body))
234
+
235
+ # Check audience.
236
+ if audience is not None:
237
+ aud = parsed.get('aud')
238
+ if aud is None:
239
+ raise AppIdentityError('No aud field in token: %s' % json_body)
240
+ if aud != audience:
241
+ raise AppIdentityError('Wrong recipient, %s != %s: %s' %
242
+ (aud, audience, json_body))
243
+
244
+ return parsed
@@ -0,0 +1,124 @@
1
+ # Copyright (C) 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """OAuth 2.0 utilities for Django.
16
+
17
+ Utilities for using OAuth 2.0 in conjunction with
18
+ the Django datastore.
19
+ """
20
+
21
+
22
+
23
+ import oauth2client
24
+ import base64
25
+ import pickle
26
+
27
+ from django.db import models
28
+ from oauth2client.client import Storage as BaseStorage
29
+
30
+ class CredentialsField(models.Field):
31
+
32
+ __metaclass__ = models.SubfieldBase
33
+
34
+ def get_internal_type(self):
35
+ return "TextField"
36
+
37
+ def to_python(self, value):
38
+ if value is None:
39
+ return None
40
+ if isinstance(value, oauth2client.client.Credentials):
41
+ return value
42
+ return pickle.loads(base64.b64decode(value))
43
+
44
+ def get_db_prep_value(self, value, connection, prepared=False):
45
+ if value is None:
46
+ return None
47
+ return base64.b64encode(pickle.dumps(value))
48
+
49
+
50
+ class FlowField(models.Field):
51
+
52
+ __metaclass__ = models.SubfieldBase
53
+
54
+ def get_internal_type(self):
55
+ return "TextField"
56
+
57
+ def to_python(self, value):
58
+ if value is None:
59
+ return None
60
+ if isinstance(value, oauth2client.client.Flow):
61
+ return value
62
+ return pickle.loads(base64.b64decode(value))
63
+
64
+ def get_db_prep_value(self, value, connection, prepared=False):
65
+ if value is None:
66
+ return None
67
+ return base64.b64encode(pickle.dumps(value))
68
+
69
+
70
+ class Storage(BaseStorage):
71
+ """Store and retrieve a single credential to and from
72
+ the datastore.
73
+
74
+ This Storage helper presumes the Credentials
75
+ have been stored as a CredenialsField
76
+ on a db model class.
77
+ """
78
+
79
+ def __init__(self, model_class, key_name, key_value, property_name):
80
+ """Constructor for Storage.
81
+
82
+ Args:
83
+ model: db.Model, model class
84
+ key_name: string, key name for the entity that has the credentials
85
+ key_value: string, key value for the entity that has the credentials
86
+ property_name: string, name of the property that is an CredentialsProperty
87
+ """
88
+ self.model_class = model_class
89
+ self.key_name = key_name
90
+ self.key_value = key_value
91
+ self.property_name = property_name
92
+
93
+ def locked_get(self):
94
+ """Retrieve Credential from datastore.
95
+
96
+ Returns:
97
+ oauth2client.Credentials
98
+ """
99
+ credential = None
100
+
101
+ query = {self.key_name: self.key_value}
102
+ entities = self.model_class.objects.filter(**query)
103
+ if len(entities) > 0:
104
+ credential = getattr(entities[0], self.property_name)
105
+ if credential and hasattr(credential, 'set_store'):
106
+ credential.set_store(self)
107
+ return credential
108
+
109
+ def locked_put(self, credentials):
110
+ """Write a Credentials to the datastore.
111
+
112
+ Args:
113
+ credentials: Credentials, the credentials to store.
114
+ """
115
+ args = {self.key_name: self.key_value}
116
+ entity = self.model_class(**args)
117
+ setattr(entity, self.property_name, credentials)
118
+ entity.save()
119
+
120
+ def locked_delete(self):
121
+ """Delete Credentials from the datastore."""
122
+
123
+ query = {self.key_name: self.key_value}
124
+ entities = self.model_class.objects.filter(**query).delete()