| OLD | NEW |
| 1 # Copyright 2014 The LUCI Authors. All rights reserved. | 1 # Copyright 2014 The LUCI Authors. All rights reserved. |
| 2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
| 3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
| 4 | 4 |
| 5 """High level tasks execution scheduling API. | 5 """High level tasks execution scheduling API. |
| 6 | 6 |
| 7 This is the interface closest to the HTTP handlers. | 7 This is the interface closest to the HTTP handlers. |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 import datetime | 10 import datetime |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 """Raises AuthorizationError if some requested dimensions are forbidden. | 389 """Raises AuthorizationError if some requested dimensions are forbidden. |
| 390 | 390 |
| 391 Uses 'dimension_acls' field from the settings. See proto/config.proto. | 391 Uses 'dimension_acls' field from the settings. See proto/config.proto. |
| 392 """ | 392 """ |
| 393 dim_acls = config.settings().dimension_acls | 393 dim_acls = config.settings().dimension_acls |
| 394 if not dim_acls or not dim_acls.entry: | 394 if not dim_acls or not dim_acls.entry: |
| 395 return # not configured, this is fine | 395 return # not configured, this is fine |
| 396 | 396 |
| 397 ident = request.authenticated | 397 ident = request.authenticated |
| 398 dims = request.properties.dimensions | 398 dims = request.properties.dimensions |
| 399 assert 'id' in dims or 'pool' in dims, dims # see _validate_dimensions | |
| 400 assert ident is not None # see task_request.init_new_request | 399 assert ident is not None # see task_request.init_new_request |
| 401 | 400 |
| 402 # Forbid targeting individual bots for non-admins, but allow using 'id' if | |
| 403 # 'pool' is used as well (so whoever can posts tasks to 'pool', can target an | |
| 404 # individual bot in that pool). | |
| 405 if 'id' in dims and 'pool' not in dims: | |
| 406 if not acl.is_admin(): | |
| 407 raise auth.AuthorizationError( | |
| 408 'Only Swarming administrators can post tasks with "id" dimension ' | |
| 409 'without specifying a "pool" dimension.') | |
| 410 | |
| 411 for k, v in sorted(dims.iteritems()): | 401 for k, v in sorted(dims.iteritems()): |
| 412 if not _can_use_dimension(dim_acls, ident, k, v): | 402 if not _can_use_dimension(dim_acls, ident, k, v): |
| 413 raise auth.AuthorizationError( | 403 raise auth.AuthorizationError( |
| 414 'User %s is not allowed to schedule tasks with dimension "%s:%s"' % | 404 'User %s is not allowed to schedule tasks with dimension "%s:%s"' % |
| 415 (ident.to_bytes(), k, v)) | 405 (ident.to_bytes(), k, v)) |
| 416 | 406 |
| 417 | 407 |
| 418 def _can_use_dimension(dim_acls, ident, k, v): | 408 def _can_use_dimension(dim_acls, ident, k, v): |
| 419 """Returns True if 'dimension_acls' allow the given dimension to be used. | 409 """Returns True if 'dimension_acls' allow the given dimension to be used. |
| 420 | 410 |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 ## Task queue tasks. | 975 ## Task queue tasks. |
| 986 | 976 |
| 987 | 977 |
| 988 def task_handle_pubsub_task(payload): | 978 def task_handle_pubsub_task(payload): |
| 989 """Handles task enqueued by _maybe_pubsub_notify_via_tq.""" | 979 """Handles task enqueued by _maybe_pubsub_notify_via_tq.""" |
| 990 # Do not catch errors to trigger task queue task retry. Errors should not | 980 # Do not catch errors to trigger task queue task retry. Errors should not |
| 991 # happen in normal case. | 981 # happen in normal case. |
| 992 _pubsub_notify( | 982 _pubsub_notify( |
| 993 payload['task_id'], payload['topic'], | 983 payload['task_id'], payload['topic'], |
| 994 payload['auth_token'], payload['userdata']) | 984 payload['auth_token'], payload['userdata']) |
| OLD | NEW |