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.""" |
| 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 def can_config_view(): |
|
Vadim Sh.
2017/07/21 22:01:20
nit: please make it "can_<verb>_<subject>". Will b
M-A Ruel
2017/07/24 15:42:51
I did ponder between "can_<object>_<mutation>" and
| |
| 49 # TODO(vadimsh): Get rid of this. Swarming jobs will use service accounts | 65 """Can view the configuration data.""" |
| 50 # associated with the job when calling Swarming, not the machine ID itself. | 66 return _is_admin() |
| 51 return is_bot() or is_user() | |
| 52 | 67 |
| 53 | 68 |
| 54 def is_bot_or_privileged_user(): | 69 def can_config_edit(): |
| 55 # TODO(vadimsh): Get rid of this. Swarming jobs will use service accounts | 70 """Can edit the configuration data. |
| 56 # associated with the job when calling Swarming, not the machine ID itself. | 71 |
| 57 return is_bot() or is_privileged_user() | 72 Only super users can edit the configuration data. |
| 73 """ | |
| 74 return _is_admin() | |
| 58 | 75 |
| 59 | 76 |
| 60 def is_bot_or_admin(): | 77 def can_bot_view(): |
| 61 """Returns True if current user can execute user-side and bot-side calls.""" | 78 """Can view bot. |
| 62 # TODO(vadimsh): Get rid of this. Swarming jobs will use service accounts | 79 |
| 63 # associated with the job when calling Swarming, not the machine ID itself. | 80 Bots can view other bots. This may change in the future. |
| 64 return is_bot() or is_admin() | 81 """ |
| 82 return is_ip_whitelisted_machine() or _is_user() or _is_view_all_bots() | |
| 83 | |
| 84 | |
| 85 def can_bot_create(): | |
| 86 """Can create (bootstrap) a bot.""" | |
| 87 return _is_admin() or _is_bootstrapper() | |
| 88 | |
| 89 | |
| 90 def can_bot_edit(): | |
| 91 """Can terminate, delete a bot. | |
| 92 | |
| 93 Bots can terminate other bots. This may change in the future. | |
| 94 """ | |
| 95 return is_ip_whitelisted_machine() or _is_privileged_user() | |
| 96 | |
| 97 | |
| 98 def can_task_view(): | |
| 99 """Can view tasks. | |
| 100 | |
| 101 It is possible that the user can only see a subset of the tasks. | |
| 102 """ | |
| 103 return is_ip_whitelisted_machine() or _is_view_all_tasks() or _is_user() | |
| 104 | |
| 105 | |
| 106 def can_task_create(): | |
| 107 """Can create a task. | |
| 108 | |
| 109 Swarming is reentrant, a bot can create a new task as part of a task. This may | |
| 110 change in the future. | |
| 111 """ | |
| 112 return is_ip_whitelisted_machine() or _is_user() | |
| 113 | |
| 114 | |
| 115 def can_task_edit(): | |
| 116 """Can 'edit' tasks, like cancelling. | |
| 117 | |
| 118 Since bots can create tasks, they can also cancel them. This may change in the | |
| 119 future. | |
| 120 """ | |
| 121 return is_ip_whitelisted_machine() or _is_user() | |
| 122 | |
| 123 | |
| 124 def can_tasks_edit(): | |
| 125 """Can 'edit' a batch of tasks, like cancelling.""" | |
| 126 return _is_privileged_user() | |
| 127 | |
| 128 | |
| 129 def can_id_task_view(identity): | |
|
Vadim Sh.
2017/07/21 22:01:20
I think this should be merged with 'can_task_view'
| |
| 130 """Can this user view a task.""" | |
| 131 return _is_privileged_user() or auth.get_current_identity() == identity | |
| 132 | |
| 133 | |
| 134 def can_id_task_edit(identity): | |
| 135 """Can 'edit' tasks, like cancelling. | |
| 136 | |
| 137 Since bots can create tasks, they can also cancel them. This may change in the | |
| 138 future. | |
| 139 """ | |
| 140 return ( | |
| 141 is_ip_whitelisted_machine() or _is_privileged_user() or | |
| 142 auth.get_current_identity() == identity) | |
| 65 | 143 |
| 66 | 144 |
| 67 def can_schedule_high_priority_tasks(): | 145 def can_schedule_high_priority_tasks(): |
| 68 """Returns True if the current user can schedule high priority tasks.""" | 146 """Returns True if the current user can schedule high priority tasks.""" |
| 69 return is_bot() or is_privileged_user() | 147 return is_ip_whitelisted_machine() or _is_privileged_user() |
| 70 | 148 |
| 71 | 149 |
| 72 def get_user_type(): | 150 def get_user_type(): |
|
Vadim Sh.
2017/07/21 22:01:20
We should get rid of this, it doesn't work well in
M-A Ruel
2017/07/24 15:42:51
Done.
| |
| 73 """Returns a string describing the current access control for the user.""" | 151 """Returns a string describing the current access control for the user.""" |
| 74 if is_admin(): | 152 if _is_admin(): |
| 75 return 'admin' | 153 return 'admin' |
| 76 if is_privileged_user(): | 154 if _is_privileged_user(): |
| 77 return 'privileged user' | 155 return 'privileged user' |
| 78 if is_user(): | 156 if _is_user(): |
| 79 return 'user' | 157 return 'user' |
| 158 if _is_view_all_bots(): | |
| 159 return 'bots_viewer' | |
| 160 if _is_view_all_tasks(): | |
| 161 return 'tasks_viewer' | |
| 80 | 162 |
| 81 | 163 |
| 82 def bootstrap_dev_server_acls(): | 164 def bootstrap_dev_server_acls(): |
| 83 """Adds localhost to IP whitelist and Swarming groups.""" | 165 """Adds localhost to IP whitelist and Swarming groups.""" |
| 84 assert utils.is_local_dev_server() | 166 assert utils.is_local_dev_server() |
| 85 if auth.is_replica(): | 167 if auth.is_replica(): |
| 86 return | 168 return |
| 87 | 169 |
| 88 bots = auth.bootstrap_loopback_ips() | 170 bots = auth.bootstrap_loopback_ips() |
| 89 | 171 |
| 90 auth_settings = config.settings().auth | 172 auth_settings = config.settings().auth |
| 91 admins_group = auth_settings.admins_group | 173 admins_group = auth_settings.admins_group |
| 92 users_group = auth_settings.users_group | 174 users_group = auth_settings.users_group |
| 93 bot_bootstrap_group = auth_settings.bot_bootstrap_group | 175 bot_bootstrap_group = auth_settings.bot_bootstrap_group |
| 94 | 176 |
| 95 auth.bootstrap_group(users_group, bots, 'Swarming users') | 177 auth.bootstrap_group(users_group, bots, 'Swarming users') |
| 96 auth.bootstrap_group(bot_bootstrap_group, bots, 'Bot bootstrap') | 178 auth.bootstrap_group(bot_bootstrap_group, bots, 'Bot bootstrap') |
| 97 | 179 |
| 98 # Add a swarming admin. smoke-test@example.com is used in | 180 # Add a swarming admin. smoke-test@example.com is used in |
| 99 # server_smoke_test.py | 181 # server_smoke_test.py |
| 100 admin = auth.Identity(auth.IDENTITY_USER, 'smoke-test@example.com') | 182 admin = auth.Identity(auth.IDENTITY_USER, 'smoke-test@example.com') |
| 101 auth.bootstrap_group(admins_group, [admin], 'Swarming administrators') | 183 auth.bootstrap_group(admins_group, [admin], 'Swarming administrators') |
| 102 | 184 |
| 103 # Add an instance admin (for easier manual testing when running dev server). | 185 # Add an instance admin (for easier manual testing when running dev server). |
| 104 auth.bootstrap_group( | 186 auth.bootstrap_group( |
| 105 auth.ADMIN_GROUP, | 187 auth.ADMIN_GROUP, |
| 106 [auth.Identity(auth.IDENTITY_USER, 'test@example.com')], | 188 [auth.Identity(auth.IDENTITY_USER, 'test@example.com')], |
| 107 'Users that can manage groups') | 189 'Users that can manage groups') |
| OLD | NEW |