Chromium Code Reviews| 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 """Defines access groups.""" | 5 """Defines access groups.""" |
| 6 | 6 |
| 7 from components import auth | 7 from components import auth |
| 8 from components import utils | 8 from components import utils |
| 9 from server import config | 9 from server import config |
| 10 | 10 |
| 11 | 11 |
| 12 def is_admin(): | 12 def _is_admin(): |
| 13 admins = config.settings().auth.admins_group | 13 """The admins group is a super set of the privileged users group.""" |
|
Vadim Sh.
2017/07/24 23:07:26
This statement is false.
A group is a set of use
M-A Ruel
2017/07/25 13:46:38
Reworded
| |
| 14 return auth.is_group_member(admins) or auth.is_admin() | 14 group = config.settings().auth.admins_group |
| 15 return auth.is_group_member(group) or auth.is_admin() | |
| 15 | 16 |
| 16 | 17 |
| 17 def is_privileged_user(): | 18 def _is_privileged_user(): |
| 18 priv_users = config.settings().auth.privileged_users_group | 19 """The privileged users group is a super set of the users group.""" |
| 19 return auth.is_group_member(priv_users) or is_admin() | 20 group = config.settings().auth.privileged_users_group |
| 21 return auth.is_group_member(group) or _is_admin() | |
| 20 | 22 |
| 21 | 23 |
| 22 def is_user(): | 24 def _is_user(): |
| 23 users = config.settings().auth.users_group | 25 group = config.settings().auth.users_group |
| 24 return auth.is_group_member(users) or is_privileged_user() | 26 return auth.is_group_member(group) or _is_privileged_user() |
| 25 | 27 |
| 26 | 28 |
| 27 def is_bootstrapper(): | 29 def _is_view_all_bots(): |
| 30 group = config.settings().auth.view_all_bots_group | |
| 31 return auth.is_group_member(group) or _is_privileged_user() | |
| 32 | |
| 33 | |
| 34 def _is_view_all_tasks(): | |
| 35 group = config.settings().auth.view_all_tasks_group | |
| 36 return auth.is_group_member(group) or _is_privileged_user() | |
| 37 | |
| 38 | |
| 39 def _is_bootstrapper(): | |
| 28 """Returns True if current user have access to bot code (for bootstrap).""" | 40 """Returns True if current user have access to bot code (for bootstrap).""" |
| 29 bot_group = config.settings().auth.bot_bootstrap_group | 41 bot_group = config.settings().auth.bot_bootstrap_group |
| 30 return is_admin() or auth.is_group_member(bot_group) | 42 return _is_admin() or auth.is_group_member(bot_group) |
| 43 | |
| 44 | |
| 45 ### Capabilities | |
| 31 | 46 |
| 32 | 47 |
| 33 def is_ip_whitelisted_machine(): | 48 def is_ip_whitelisted_machine(): |
| 34 """Returns True if the call is made from IP whitelisted machine.""" | 49 """Returns True if the call is made from IP whitelisted machine.""" |
| 35 # TODO(vadimsh): Get rid of this. It's blocked on fixing /bot_code calls in | 50 # TODO(vadimsh): Get rid of this. It's blocked on fixing /bot_code calls in |
| 36 # bootstrap code everywhere to use service accounts and switching all Swarming | 51 # bootstrap code everywhere to use service accounts and switching all Swarming |
| 37 # Tasks API calls made from bots to use proper authentication. | 52 # Tasks API calls made from bots to use proper authentication. |
| 38 return auth.is_in_ip_whitelist( | 53 return auth.is_in_ip_whitelist( |
| 39 auth.bots_ip_whitelist(), auth.get_peer_ip(), False) | 54 auth.bots_ip_whitelist(), auth.get_peer_ip(), False) |
| 40 | 55 |
| 41 | 56 |
| 42 def is_bot(): | 57 def can_access(): |
| 43 # TODO(vadimsh): Get rid of this. Swarming jobs will use service accounts | 58 """Minimally authenticated user.""" |
| 44 # associated with the job when calling Swarming, not the machine IP. | 59 return ( |
| 45 return is_ip_whitelisted_machine() or is_admin() | 60 is_ip_whitelisted_machine() or _is_user() or |
| 61 _is_view_all_bots() or _is_view_all_tasks()) | |
| 46 | 62 |
| 47 | 63 |
| 48 def is_bot_or_user(): | 64 #### Config |
| 49 # TODO(vadimsh): Get rid of this. Swarming jobs will use service accounts | |
| 50 # associated with the job when calling Swarming, not the machine ID itself. | |
| 51 return is_bot() or is_user() | |
| 52 | 65 |
| 53 | 66 |
| 54 def is_bot_or_privileged_user(): | 67 def can_view_config(): |
| 55 # TODO(vadimsh): Get rid of this. Swarming jobs will use service accounts | 68 """Can view the configuration data.""" |
| 56 # associated with the job when calling Swarming, not the machine ID itself. | 69 return _is_admin() |
| 57 return is_bot() or is_privileged_user() | |
| 58 | 70 |
| 59 | 71 |
| 60 def is_bot_or_admin(): | 72 def can_edit_config(): |
| 61 """Returns True if current user can execute user-side and bot-side calls.""" | 73 """Can edit the configuration data. |
| 62 # TODO(vadimsh): Get rid of this. Swarming jobs will use service accounts | 74 |
| 63 # associated with the job when calling Swarming, not the machine ID itself. | 75 Only super users can edit the configuration data. |
| 64 return is_bot() or is_admin() | 76 """ |
| 77 return _is_admin() | |
| 78 | |
| 79 | |
| 80 #### Bot | |
| 81 | |
| 82 | |
| 83 def can_create_bot(): | |
| 84 """Can create (bootstrap) a bot.""" | |
| 85 return _is_admin() or _is_bootstrapper() | |
| 86 | |
| 87 | |
| 88 def can_edit_bot(): | |
| 89 """Can terminate, delete a bot. | |
| 90 | |
| 91 Bots can terminate other bots. This may change in the future. | |
| 92 """ | |
| 93 return is_ip_whitelisted_machine() or _is_privileged_user() | |
|
Vadim Sh.
2017/07/24 23:07:26
I think it should be _is_admin instead of _is_priv
M-A Ruel
2017/07/25 13:46:38
So that any Googler can quickly take a bot out of
| |
| 94 | |
| 95 | |
| 96 def can_view_bot(): | |
| 97 """Can view bot. | |
| 98 | |
| 99 Bots can view other bots. This may change in the future. | |
| 100 """ | |
| 101 return ( | |
| 102 is_ip_whitelisted_machine() or _is_privileged_user() or | |
| 103 _is_view_all_bots()) | |
| 104 | |
| 105 | |
| 106 #### Task | |
| 107 | |
| 108 | |
| 109 def can_create_task(): | |
| 110 """Can create a task. | |
| 111 | |
| 112 Swarming is reentrant, a bot can create a new task as part of a task. This may | |
| 113 change in the future. | |
| 114 """ | |
| 115 return is_ip_whitelisted_machine() or _is_user() | |
| 65 | 116 |
| 66 | 117 |
| 67 def can_schedule_high_priority_tasks(): | 118 def can_schedule_high_priority_tasks(): |
| 68 """Returns True if the current user can schedule high priority tasks.""" | 119 """Returns True if the current user can schedule high priority tasks.""" |
| 69 return is_bot() or is_privileged_user() | 120 # TODO(maruel): Deny priority < 100 task creation instead of silently |
| 121 # downgrading the priority. | |
| 122 return is_ip_whitelisted_machine() or _is_privileged_user() | |
| 70 | 123 |
| 71 | 124 |
| 72 def get_user_type(): | 125 def can_edit_task(task): |
| 73 """Returns a string describing the current access control for the user.""" | 126 """Can 'edit' tasks, like cancelling. |
| 74 if is_admin(): | 127 |
| 75 return 'admin' | 128 Since bots can create tasks, they can also cancel them. This may change in the |
| 76 if is_privileged_user(): | 129 future. |
| 77 return 'privileged user' | 130 """ |
| 78 if is_user(): | 131 return ( |
| 79 return 'user' | 132 is_ip_whitelisted_machine() or _is_privileged_user() or |
| 133 auth.get_current_identity() == task.authenticated) | |
| 134 | |
| 135 | |
| 136 def can_edit_all_tasks(): | |
| 137 """Can 'edit' a batch of tasks, like cancelling.""" | |
| 138 return _is_privileged_user() | |
| 139 | |
| 140 | |
| 141 def can_view_task(task): | |
| 142 """Can view a single task. | |
| 143 | |
| 144 It is possible that the user can only see a subset of the tasks. | |
|
Vadim Sh.
2017/07/24 19:16:47
this line no longer applies
M-A Ruel
2017/07/25 13:46:38
Done.
| |
| 145 """ | |
| 146 return ( | |
| 147 is_ip_whitelisted_machine() or _is_view_all_tasks() or | |
| 148 _is_privileged_user() or | |
| 149 auth.get_current_identity() == task.authenticated) | |
| 150 | |
| 151 | |
| 152 def can_view_all_tasks(): | |
| 153 """Can view all tasks.""" | |
| 154 return _is_view_all_tasks() or _is_privileged_user() | |
| 155 | |
| 156 | |
| 157 ### Other | |
| 80 | 158 |
| 81 | 159 |
| 82 def bootstrap_dev_server_acls(): | 160 def bootstrap_dev_server_acls(): |
| 83 """Adds localhost to IP whitelist and Swarming groups.""" | 161 """Adds localhost to IP whitelist and Swarming groups.""" |
| 84 assert utils.is_local_dev_server() | 162 assert utils.is_local_dev_server() |
| 85 if auth.is_replica(): | 163 if auth.is_replica(): |
| 86 return | 164 return |
| 87 | 165 |
| 88 bots = auth.bootstrap_loopback_ips() | 166 bots = auth.bootstrap_loopback_ips() |
| 89 | 167 |
| 90 auth_settings = config.settings().auth | 168 auth_settings = config.settings().auth |
| 91 admins_group = auth_settings.admins_group | 169 admins_group = auth_settings.admins_group |
| 92 users_group = auth_settings.users_group | 170 users_group = auth_settings.users_group |
| 93 bot_bootstrap_group = auth_settings.bot_bootstrap_group | 171 bot_bootstrap_group = auth_settings.bot_bootstrap_group |
| 94 | 172 |
| 95 auth.bootstrap_group(users_group, bots, 'Swarming users') | 173 auth.bootstrap_group(users_group, bots, 'Swarming users') |
| 96 auth.bootstrap_group(bot_bootstrap_group, bots, 'Bot bootstrap') | 174 auth.bootstrap_group(bot_bootstrap_group, bots, 'Bot bootstrap') |
| 97 | 175 |
| 98 # Add a swarming admin. smoke-test@example.com is used in | 176 # Add a swarming admin. smoke-test@example.com is used in |
| 99 # server_smoke_test.py | 177 # server_smoke_test.py |
| 100 admin = auth.Identity(auth.IDENTITY_USER, 'smoke-test@example.com') | 178 admin = auth.Identity(auth.IDENTITY_USER, 'smoke-test@example.com') |
| 101 auth.bootstrap_group(admins_group, [admin], 'Swarming administrators') | 179 auth.bootstrap_group(admins_group, [admin], 'Swarming administrators') |
| 102 | 180 |
| 103 # Add an instance admin (for easier manual testing when running dev server). | 181 # Add an instance admin (for easier manual testing when running dev server). |
| 104 auth.bootstrap_group( | 182 auth.bootstrap_group( |
| 105 auth.ADMIN_GROUP, | 183 auth.ADMIN_GROUP, |
| 106 [auth.Identity(auth.IDENTITY_USER, 'test@example.com')], | 184 [auth.Identity(auth.IDENTITY_USER, 'test@example.com')], |
| 107 'Users that can manage groups') | 185 'Users that can manage groups') |
| OLD | NEW |