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

Side by Side Diff: appengine/config_service/api.py

Issue 1224913002: luci-config: fine-grained acls (Closed) Base URL: git@github.com:luci/luci-py.git@master
Patch Set: mentioned in doc that trusted services also have access Created 5 years, 5 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 2015 The Swarming Authors. All rights reserved. 1 # Copyright 2015 The Swarming Authors. All rights reserved.
2 # Use of this source code is governed by the Apache v2.0 license that can be 2 # Use of this source code is governed by the Apache v2.0 license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import logging 5 import logging
6 6
7 from protorpc import messages 7 from protorpc import messages
8 from protorpc import message_types 8 from protorpc import message_types
9 from protorpc import remote 9 from protorpc import remote
10 import endpoints 10 import endpoints
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 content = messages.BytesField(4) 48 content = messages.BytesField(4)
49 configs = messages.MessageField(ConfigEntry, 1, repeated=True) 49 configs = messages.MessageField(ConfigEntry, 1, repeated=True)
50 50
51 51
52 @auth.endpoints_api(name='config', version='v1', title='Configuration Service') 52 @auth.endpoints_api(name='config', version='v1', title='Configuration Service')
53 class ConfigApi(remote.Service): 53 class ConfigApi(remote.Service):
54 """API to access configurations.""" 54 """API to access configurations."""
55 55
56 def can_read_config_set(self, config_set): 56 def can_read_config_set(self, config_set):
57 try: 57 try:
58 return acl.can_read_config_set( 58 return acl.can_read_config_set(config_set)
59 config_set, headers=self.request_state.headers)
60 except ValueError: 59 except ValueError:
61 raise endpoints.BadRequestException('Invalid config set: %s' % config_set) 60 raise endpoints.BadRequestException('Invalid config set: %s' % config_set)
62 61
63 ############################################################################## 62 ##############################################################################
64 # endpoint: get_mapping 63 # endpoint: get_mapping
65 64
66 class GetMappingResponseMessage(messages.Message): 65 class GetMappingResponseMessage(messages.Message):
67 class Mapping(messages.Message): 66 class Mapping(messages.Message):
68 config_set = messages.StringField(1, required=True) 67 config_set = messages.StringField(1, required=True)
69 location = messages.StringField(2) 68 location = messages.StringField(2)
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 @auth.endpoints_method( 177 @auth.endpoints_method(
179 message_types.VoidMessage, 178 message_types.VoidMessage,
180 GetProjectsResponseMessage, 179 GetProjectsResponseMessage,
181 http_method='GET', 180 http_method='GET',
182 path='projects') 181 path='projects')
183 def get_projects(self, request): # pylint: disable=W0613 182 def get_projects(self, request): # pylint: disable=W0613
184 """Gets list of registered projects. 183 """Gets list of registered projects.
185 184
186 The project list is stored in services/luci-config:projects.cfg. 185 The project list is stored in services/luci-config:projects.cfg.
187 """ 186 """
188 if not acl.can_read_project_list(): 187 return self.GetProjectsResponseMessage(
189 raise endpoints.ForbiddenException() 188 projects=[p for p in get_projects() if acl.has_project_access(p.id)],
190 return self.GetProjectsResponseMessage(projects=get_projects()) 189 )
191 190
192 ############################################################################## 191 ##############################################################################
193 # endpoint: get_refs 192 # endpoint: get_refs
194 193
195 class GetRefsResponseMessage(messages.Message): 194 class GetRefsResponseMessage(messages.Message):
196 class Ref(messages.Message): 195 class Ref(messages.Message):
197 name = messages.StringField(1) 196 name = messages.StringField(1)
198 refs = messages.MessageField(Ref, 1, repeated=True) 197 refs = messages.MessageField(Ref, 1, repeated=True)
199 198
200 @auth.endpoints_method( 199 @auth.endpoints_method(
201 endpoints.ResourceContainer( 200 endpoints.ResourceContainer(
202 message_types.VoidMessage, 201 message_types.VoidMessage,
203 project_id=messages.StringField(1, required=True), 202 project_id=messages.StringField(1, required=True),
204 ), 203 ),
205 GetRefsResponseMessage, 204 GetRefsResponseMessage,
206 http_method='GET', 205 http_method='GET',
207 path='projects/{project_id}/refs') 206 path='projects/{project_id}/refs')
208 def get_refs(self, request): 207 def get_refs(self, request):
209 """Gets list of refs of a project.""" 208 """Gets list of refs of a project."""
210 if not acl.can_read_project_config(request.project_id): 209 if not acl.has_project_access(request.project_id):
211 raise endpoints.NotFoundException() 210 raise endpoints.NotFoundException()
212 ref_names = get_ref_names(request.project_id) 211 ref_names = get_ref_names(request.project_id)
213 if ref_names is None: 212 if ref_names is None:
214 # Project not found 213 # Project not found
215 raise endpoints.NotFoundException() 214 raise endpoints.NotFoundException()
216 res = self.GetRefsResponseMessage() 215 res = self.GetRefsResponseMessage()
217 res.refs = [res.Ref(name=ref) for ref in ref_names] 216 res.refs = [res.Ref(name=ref) for ref in ref_names]
218 return res 217 return res
219 218
220 ############################################################################## 219 ##############################################################################
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 # Project does not exist 296 # Project does not exist
298 return None 297 return None
299 return [ref.name for ref in refs] 298 return [ref.name for ref in refs]
300 299
301 300
302 def get_config_multi(config_sets, path, hashes_only): 301 def get_config_multi(config_sets, path, hashes_only):
303 """Returns configs at |path| in all config sets. 302 """Returns configs at |path| in all config sets.
304 303
305 Returns empty config list if requester does not have project access. 304 Returns empty config list if requester does not have project access.
306 """ 305 """
307 if not acl.has_project_access():
308 raise endpoints.ForbiddenException()
309
310 res = GetConfigMultiResponseMessage() 306 res = GetConfigMultiResponseMessage()
307 config_sets = filter(acl.can_read_config_set, config_sets)
311 configs = storage.get_latest_multi_async( 308 configs = storage.get_latest_multi_async(
312 config_sets, path, hashes_only).get_result() 309 config_sets, path, hashes_only).get_result()
313 for config in configs: 310 for config in configs:
314 if not hashes_only and config.get('content') is None: 311 if not hashes_only and config.get('content') is None:
315 logging.error( 312 logging.error(
316 'Blob %s referenced from %s:%s:%s was not found', 313 'Blob %s referenced from %s:%s:%s was not found',
317 config['content_hash'], 314 config['content_hash'],
318 config['config_set'], 315 config['config_set'],
319 config['revision'], 316 config['revision'],
320 path) 317 path)
321 continue 318 continue
322 res.configs.append(res.ConfigEntry( 319 res.configs.append(res.ConfigEntry(
323 config_set=config['config_set'], 320 config_set=config['config_set'],
324 revision=config['revision'], 321 revision=config['revision'],
325 content_hash=config['content_hash'], 322 content_hash=config['content_hash'],
326 content=config.get('content'), 323 content=config.get('content'),
327 )) 324 ))
328 return res 325 return res
329 326
330 327
331 def raise_config_not_found(): 328 def raise_config_not_found():
332 raise endpoints.NotFoundException('The requested config is not found') 329 raise endpoints.NotFoundException('The requested config is not found')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698