Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: appengine/chromium_build_logs/third_party/oauth2client/clientsecrets.py

Issue 1260293009: make version of ts_mon compatible with appengine (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: clean up code Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (C) 2011 Google Inc. 1 # Copyright 2014 Google Inc. All rights reserved.
2 # 2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); 3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with 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 5 # You may obtain a copy of the License at
6 # 6 #
7 # http://www.apache.org/licenses/LICENSE-2.0 7 # http://www.apache.org/licenses/LICENSE-2.0
8 # 8 #
9 # Unless required by applicable law or agreed to in writing, software 9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, 10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and 12 # See the License for the specific language governing permissions and
13 # limitations under the License. 13 # limitations under the License.
14 14
15 """Utilities for reading OAuth 2.0 client secret files. 15 """Utilities for reading OAuth 2.0 client secret files.
16 16
17 A client_secrets.json file contains all the information needed to interact with 17 A client_secrets.json file contains all the information needed to interact with
18 an OAuth 2.0 protected service. 18 an OAuth 2.0 protected service.
19 """ 19 """
20 20
21 __author__ = 'jcgregorio@google.com (Joe Gregorio)' 21 __author__ = 'jcgregorio@google.com (Joe Gregorio)'
22 22
23 import json
24 import six
23 25
24 from anyjson import simplejson
25 26
26 # Properties that make a client_secrets.json file valid. 27 # Properties that make a client_secrets.json file valid.
27 TYPE_WEB = 'web' 28 TYPE_WEB = 'web'
28 TYPE_INSTALLED = 'installed' 29 TYPE_INSTALLED = 'installed'
29 30
30 VALID_CLIENT = { 31 VALID_CLIENT = {
31 TYPE_WEB: { 32 TYPE_WEB: {
32 'required': [ 33 'required': [
33 'client_id', 34 'client_id',
34 'client_secret', 35 'client_secret',
35 'redirect_uris', 36 'redirect_uris',
36 'auth_uri', 37 'auth_uri',
37 'token_uri'], 38 'token_uri',
39 ],
38 'string': [ 40 'string': [
39 'client_id', 41 'client_id',
40 'client_secret' 42 'client_secret',
41 ] 43 ],
42 }, 44 },
43 TYPE_INSTALLED: { 45 TYPE_INSTALLED: {
44 'required': [ 46 'required': [
45 'client_id', 47 'client_id',
46 'client_secret', 48 'client_secret',
47 'redirect_uris', 49 'redirect_uris',
48 'auth_uri', 50 'auth_uri',
49 'token_uri'], 51 'token_uri',
52 ],
50 'string': [ 53 'string': [
51 'client_id', 54 'client_id',
52 'client_secret' 55 'client_secret',
53 ] 56 ],
54 } 57 },
55 } 58 }
59
56 60
57 class Error(Exception): 61 class Error(Exception):
58 """Base error for this module.""" 62 """Base error for this module."""
59 pass 63 pass
60 64
61 65
62 class InvalidClientSecretsError(Error): 66 class InvalidClientSecretsError(Error):
63 """Format of ClientSecrets file is invalid.""" 67 """Format of ClientSecrets file is invalid."""
64 pass 68 pass
65 69
66 70
67 def _validate_clientsecrets(obj): 71 def _validate_clientsecrets(obj):
68 if obj is None or len(obj) != 1: 72 _INVALID_FILE_FORMAT_MSG = (
69 raise InvalidClientSecretsError('Invalid file format.') 73 'Invalid file format. See '
70 client_type = obj.keys()[0] 74 'https://developers.google.com/api-client-library/'
71 if client_type not in VALID_CLIENT.keys(): 75 'python/guide/aaa_client_secrets')
72 raise InvalidClientSecretsError('Unknown client type: %s.' % client_type) 76
77 if obj is None:
78 raise InvalidClientSecretsError(_INVALID_FILE_FORMAT_MSG)
79 if len(obj) != 1:
80 raise InvalidClientSecretsError(
81 _INVALID_FILE_FORMAT_MSG + ' '
82 'Expected a JSON object with a single property for a "web" or '
83 '"installed" application')
84 client_type = tuple(obj)[0]
85 if client_type not in VALID_CLIENT:
86 raise InvalidClientSecretsError('Unknown client type: %s.' % (client_type,))
73 client_info = obj[client_type] 87 client_info = obj[client_type]
74 for prop_name in VALID_CLIENT[client_type]['required']: 88 for prop_name in VALID_CLIENT[client_type]['required']:
75 if prop_name not in client_info: 89 if prop_name not in client_info:
76 raise InvalidClientSecretsError( 90 raise InvalidClientSecretsError(
77 'Missing property "%s" in a client type of "%s".' % (prop_name, 91 'Missing property "%s" in a client type of "%s".' % (prop_name,
78 client_type)) 92 client_type))
79 for prop_name in VALID_CLIENT[client_type]['string']: 93 for prop_name in VALID_CLIENT[client_type]['string']:
80 if client_info[prop_name].startswith('[['): 94 if client_info[prop_name].startswith('[['):
81 raise InvalidClientSecretsError( 95 raise InvalidClientSecretsError(
82 'Property "%s" is not configured.' % prop_name) 96 'Property "%s" is not configured.' % prop_name)
83 return client_type, client_info 97 return client_type, client_info
84 98
85 99
86 def load(fp): 100 def load(fp):
87 obj = simplejson.load(fp) 101 obj = json.load(fp)
88 return _validate_clientsecrets(obj) 102 return _validate_clientsecrets(obj)
89 103
90 104
91 def loads(s): 105 def loads(s):
92 obj = simplejson.loads(s) 106 obj = json.loads(s)
93 return _validate_clientsecrets(obj) 107 return _validate_clientsecrets(obj)
94 108
95 109
96 def loadfile(filename): 110 def _loadfile(filename):
97 try: 111 try:
98 fp = file(filename, 'r') 112 with open(filename, 'r') as fp:
99 try: 113 obj = json.load(fp)
100 obj = simplejson.load(fp)
101 finally:
102 fp.close()
103 except IOError: 114 except IOError:
104 raise InvalidClientSecretsError('File not found: "%s"' % filename) 115 raise InvalidClientSecretsError('File not found: "%s"' % filename)
105 return _validate_clientsecrets(obj) 116 return _validate_clientsecrets(obj)
117
118
119 def loadfile(filename, cache=None):
120 """Loading of client_secrets JSON file, optionally backed by a cache.
121
122 Typical cache storage would be App Engine memcache service,
123 but you can pass in any other cache client that implements
124 these methods:
125
126 * ``get(key, namespace=ns)``
127 * ``set(key, value, namespace=ns)``
128
129 Usage::
130
131 # without caching
132 client_type, client_info = loadfile('secrets.json')
133 # using App Engine memcache service
134 from google.appengine.api import memcache
135 client_type, client_info = loadfile('secrets.json', cache=memcache)
136
137 Args:
138 filename: string, Path to a client_secrets.json file on a filesystem.
139 cache: An optional cache service client that implements get() and set()
140 methods. If not specified, the file is always being loaded from
141 a filesystem.
142
143 Raises:
144 InvalidClientSecretsError: In case of a validation error or some
145 I/O failure. Can happen only on cache miss.
146
147 Returns:
148 (client_type, client_info) tuple, as _loadfile() normally would.
149 JSON contents is validated only during first load. Cache hits are not
150 validated.
151 """
152 _SECRET_NAMESPACE = 'oauth2client:secrets#ns'
153
154 if not cache:
155 return _loadfile(filename)
156
157 obj = cache.get(filename, namespace=_SECRET_NAMESPACE)
158 if obj is None:
159 client_type, client_info = _loadfile(filename)
160 obj = {client_type: client_info}
161 cache.set(filename, obj, namespace=_SECRET_NAMESPACE)
162
163 return next(six.iteritems(obj))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698