| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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') |
| OLD | NEW |