| 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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 """Raises AuthorizationError if some requested dimensions are forbidden. | 343 """Raises AuthorizationError if some requested dimensions are forbidden. |
| 344 | 344 |
| 345 Uses 'dimension_acls' field from the settings. See proto/config.proto. | 345 Uses 'dimension_acls' field from the settings. See proto/config.proto. |
| 346 """ | 346 """ |
| 347 dim_acls = config.settings().dimension_acls | 347 dim_acls = config.settings().dimension_acls |
| 348 if not dim_acls or not dim_acls.entry: | 348 if not dim_acls or not dim_acls.entry: |
| 349 return # not configured, this is fine | 349 return # not configured, this is fine |
| 350 | 350 |
| 351 ident = request.authenticated | 351 ident = request.authenticated |
| 352 dims = request.properties.dimensions | 352 dims = request.properties.dimensions |
| 353 assert 'id' in dims or 'pool' in dims, dims # see _validate_dimensions | |
| 354 assert ident is not None # see task_request.init_new_request | 353 assert ident is not None # see task_request.init_new_request |
| 355 | 354 |
| 355 using_id = any(k == u'id' for k, _ in dims) |
| 356 using_pool = any(k == u'pool' for k, _ in dims) |
| 356 # Forbid targeting individual bots for non-admins, but allow using 'id' if | 357 # Forbid targeting individual bots for non-admins, but allow using 'id' if |
| 357 # 'pool' is used as well (so whoever can posts tasks to 'pool', can target an | 358 # 'pool' is used as well (so whoever can posts tasks to 'pool', can target an |
| 358 # individual bot in that pool). | 359 # individual bot in that pool). |
| 359 if 'id' in dims and 'pool' not in dims: | 360 if using_id and not using_pool: |
| 360 if not acl.is_admin(): | 361 if not acl.is_admin(): |
| 361 raise auth.AuthorizationError( | 362 raise auth.AuthorizationError( |
| 362 'Only Swarming administrators can post tasks with "id" dimension ' | 363 'Only Swarming administrators can post tasks with "id" dimension ' |
| 363 'without specifying a "pool" dimension.') | 364 'without specifying a "pool" dimension.') |
| 364 | 365 |
| 365 for k, v in sorted(dims.iteritems()): | 366 for k, v in dims: |
| 366 if not _can_use_dimension(dim_acls, ident, k, v): | 367 if not _can_use_dimension(dim_acls, ident, k, v): |
| 367 raise auth.AuthorizationError( | 368 raise auth.AuthorizationError( |
| 368 'User %s is not allowed to schedule tasks with dimension "%s:%s"' % | 369 'User %s is not allowed to schedule tasks with dimension "%s:%s"' % |
| 369 (ident.to_bytes(), k, v)) | 370 (ident.to_bytes(), k, v)) |
| 370 | 371 |
| 371 | 372 |
| 372 def _can_use_dimension(dim_acls, ident, k, v): | 373 def _can_use_dimension(dim_acls, ident, k, v): |
| 373 """Returns True if 'dimension_acls' allow the given dimension to be used. | 374 """Returns True if 'dimension_acls' allow the given dimension to be used. |
| 374 | 375 |
| 375 Args: | 376 Args: |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 ## Task queue tasks. | 931 ## Task queue tasks. |
| 931 | 932 |
| 932 | 933 |
| 933 def task_handle_pubsub_task(payload): | 934 def task_handle_pubsub_task(payload): |
| 934 """Handles task enqueued by _maybe_pubsub_notify_via_tq.""" | 935 """Handles task enqueued by _maybe_pubsub_notify_via_tq.""" |
| 935 # Do not catch errors to trigger task queue task retry. Errors should not | 936 # Do not catch errors to trigger task queue task retry. Errors should not |
| 936 # happen in normal case. | 937 # happen in normal case. |
| 937 _pubsub_notify( | 938 _pubsub_notify( |
| 938 payload['task_id'], payload['topic'], | 939 payload['task_id'], payload['topic'], |
| 939 payload['auth_token'], payload['userdata']) | 940 payload['auth_token'], payload['userdata']) |
| OLD | NEW |