blob: dd7d5af444a7b5c58b1f1bfc01b32953efc6c80f [file] [log] [blame]
nayna-patel755d8142013-07-16 06:45:34 +00001# Copyright 2013 OpenStack Foundation
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
Trevor McCaslandc44eadc2019-01-17 11:27:48 -060015import testtools
nayna-patel755d8142013-07-16 06:45:34 +000016
17from tempest.api.identity import base
Trevor McCaslandc44eadc2019-01-17 11:27:48 -060018from tempest import config
Ken'ichi Ohmichi7bd25752017-03-10 10:45:39 -080019from tempest.lib.common.utils import data_utils
Rodrigo Duarteca3b39d2017-01-26 18:10:31 -030020from tempest.lib.common.utils import test_utils
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -080021from tempest.lib import decorators
Rodrigo Duarteca3b39d2017-01-26 18:10:31 -030022from tempest.lib import exceptions as lib_exc
nayna-patel755d8142013-07-16 06:45:34 +000023
Trevor McCaslandc44eadc2019-01-17 11:27:48 -060024CONF = config.CONF
25
nayna-patel755d8142013-07-16 06:45:34 +000026
Matthew Treinishdb2c5972014-01-31 22:18:59 +000027class RolesV3TestJSON(base.BaseIdentityV3AdminTest):
zhufla7635d72020-04-29 14:36:41 +080028 """Test roles"""
29
Trevor McCasland7ea7e0a2019-01-17 11:35:39 -060030 # NOTE: force_tenant_isolation is true in the base class by default but
31 # overridden to false here to allow test execution for clouds using the
32 # pre-provisioned credentials provider.
33 force_tenant_isolation = False
nayna-patel755d8142013-07-16 06:45:34 +000034
35 @classmethod
Andrea Frittoli7688e742014-09-15 12:38:22 +010036 def resource_setup(cls):
37 super(RolesV3TestJSON, cls).resource_setup()
Castulo J. Martinez19b81b22016-07-15 08:58:25 -070038 cls.roles = list()
nayna-patelc905c182014-04-21 14:00:32 +000039 for _ in range(3):
Ken'ichi Ohmichi96508472015-03-23 01:43:42 +000040 role_name = data_utils.rand_name(name='role')
Arx Cruz24bcb882016-02-10 15:20:16 +010041 role = cls.roles_client.create_role(name=role_name)['role']
Trevor McCaslanddbfd7c22017-11-28 14:32:23 -060042 cls.addClassResourceCleanup(cls.roles_client.delete_role,
43 role['id'])
Castulo J. Martinez19b81b22016-07-15 08:58:25 -070044 cls.roles.append(role)
Ken'ichi Ohmichi96508472015-03-23 01:43:42 +000045 u_name = data_utils.rand_name('user')
nayna-patel755d8142013-07-16 06:45:34 +000046 u_desc = '%s description' % u_name
47 u_email = '%s@testmail.tm' % u_name
Zack Feldsteind8c5f7a2015-12-14 10:44:07 -060048 cls.u_password = data_utils.rand_password()
zhufl2b33c1a2017-04-24 17:33:48 +080049 cls.domain = cls.create_domain()
Yaroslav Lobankov47a93ab2016-02-07 16:32:49 -060050 cls.project = cls.projects_client.create_project(
Ken'ichi Ohmichi96508472015-03-23 01:43:42 +000051 data_utils.rand_name('project'),
52 description=data_utils.rand_name('project-desc'),
John Warren56317e02015-08-12 20:48:32 +000053 domain_id=cls.domain['id'])['project']
Trevor McCaslanddbfd7c22017-11-28 14:32:23 -060054 cls.addClassResourceCleanup(cls.projects_client.delete_project,
55 cls.project['id'])
Yaroslav Lobankov997a1452015-11-19 17:11:37 +030056 cls.group_body = cls.groups_client.create_group(
Yaroslav Lobankov45025c02015-11-19 17:55:15 +030057 name=data_utils.rand_name('Group'), project_id=cls.project['id'],
John Warren56317e02015-08-12 20:48:32 +000058 domain_id=cls.domain['id'])['group']
Trevor McCaslanddbfd7c22017-11-28 14:32:23 -060059 cls.addClassResourceCleanup(cls.groups_client.delete_group,
60 cls.group_body['id'])
Arx Cruz24bcb882016-02-10 15:20:16 +010061 cls.role = cls.roles_client.create_role(
piyush110786afaaf262015-12-11 18:54:05 +053062 name=data_utils.rand_name('Role'))['role']
Trevor McCaslanddbfd7c22017-11-28 14:32:23 -060063 cls.addClassResourceCleanup(cls.roles_client.delete_role,
64 cls.role['id'])
Trevor McCaslandc44eadc2019-01-17 11:27:48 -060065 if not CONF.identity_feature_enabled.immutable_user_source:
66 cls.user_body = cls.users_client.create_user(
67 name=u_name,
68 description=u_desc,
69 email=u_email,
70 password=cls.u_password,
71 domain_id=cls.domain['id'],
72 project_id=cls.project['id']
73 )['user']
74 cls.addClassResourceCleanup(cls.users_client.delete_user,
75 cls.user_body['id'])
nayna-patel755d8142013-07-16 06:45:34 +000076
Jordan Pittier3b46d272017-04-12 16:17:28 +020077 @decorators.attr(type='smoke')
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -080078 @decorators.idempotent_id('18afc6c0-46cf-4911-824e-9989cc056c3a')
Arx Cruz24bcb882016-02-10 15:20:16 +010079 def test_role_create_update_show_list(self):
zhufla7635d72020-04-29 14:36:41 +080080 """Test creating, updating, showing and listing a role"""
Ken'ichi Ohmichi96508472015-03-23 01:43:42 +000081 r_name = data_utils.rand_name('Role')
Arx Cruz24bcb882016-02-10 15:20:16 +010082 role = self.roles_client.create_role(name=r_name)['role']
83 self.addCleanup(self.roles_client.delete_role, role['id'])
nayna-patel755d8142013-07-16 06:45:34 +000084 self.assertIn('name', role)
85 self.assertEqual(role['name'], r_name)
86
Ken'ichi Ohmichi96508472015-03-23 01:43:42 +000087 new_name = data_utils.rand_name('NewRole')
Arx Cruz24bcb882016-02-10 15:20:16 +010088 updated_role = self.roles_client.update_role(role['id'],
89 name=new_name)['role']
nayna-patel755d8142013-07-16 06:45:34 +000090 self.assertIn('name', updated_role)
91 self.assertIn('id', updated_role)
92 self.assertIn('links', updated_role)
93 self.assertNotEqual(r_name, updated_role['name'])
94
Arx Cruz24bcb882016-02-10 15:20:16 +010095 new_role = self.roles_client.show_role(role['id'])['role']
nayna-patel755d8142013-07-16 06:45:34 +000096 self.assertEqual(new_name, new_role['name'])
97 self.assertEqual(updated_role['id'], new_role['id'])
98
Arx Cruz24bcb882016-02-10 15:20:16 +010099 roles = self.roles_client.list_roles()['roles']
wanglianmina3e84ea2014-03-26 17:30:33 +0800100 self.assertIn(role['id'], [r['id'] for r in roles])
101
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -0800102 @decorators.idempotent_id('c6b80012-fe4a-498b-9ce8-eb391c05169f')
Trevor McCaslandc44eadc2019-01-17 11:27:48 -0600103 @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
104 'Skipped because environment has an immutable user '
105 'source and solely provides read-only access to users.')
nayna-patel755d8142013-07-16 06:45:34 +0000106 def test_grant_list_revoke_role_to_user_on_project(self):
zhufla7635d72020-04-29 14:36:41 +0800107 """Test granting, listing, revoking role to user on project"""
ghanshyam2e6fb562016-09-06 11:14:31 +0900108 self.roles_client.create_user_role_on_project(self.project['id'],
Arx Cruz24bcb882016-02-10 15:20:16 +0100109 self.user_body['id'],
110 self.role['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000111
Arx Cruz24bcb882016-02-10 15:20:16 +0100112 roles = self.roles_client.list_user_roles_on_project(
John Warren56317e02015-08-12 20:48:32 +0000113 self.project['id'], self.user_body['id'])['roles']
nayna-patel755d8142013-07-16 06:45:34 +0000114
zhufl628642b2017-08-01 14:39:34 +0800115 self.assertEqual(1, len(roles))
116 self.assertEqual(self.role['id'], roles[0]['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000117
Arx Cruz24bcb882016-02-10 15:20:16 +0100118 self.roles_client.check_user_role_existence_on_project(
Maho Koshiyab6fa2e42015-12-07 16:52:53 +0900119 self.project['id'], self.user_body['id'], self.role['id'])
120
Arx Cruz24bcb882016-02-10 15:20:16 +0100121 self.roles_client.delete_role_from_user_on_project(
nayna-patel755d8142013-07-16 06:45:34 +0000122 self.project['id'], self.user_body['id'], self.role['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000123
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -0800124 @decorators.idempotent_id('6c9a2940-3625-43a3-ac02-5dcec62ef3bd')
Trevor McCaslandc44eadc2019-01-17 11:27:48 -0600125 @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
126 'Skipped because environment has an immutable user '
127 'source and solely provides read-only access to users.')
nayna-patel755d8142013-07-16 06:45:34 +0000128 def test_grant_list_revoke_role_to_user_on_domain(self):
zhufla7635d72020-04-29 14:36:41 +0800129 """Test granting, listing, revoking role to user on domain"""
ghanshyam2e6fb562016-09-06 11:14:31 +0900130 self.roles_client.create_user_role_on_domain(
nayna-patel755d8142013-07-16 06:45:34 +0000131 self.domain['id'], self.user_body['id'], self.role['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000132
Arx Cruz24bcb882016-02-10 15:20:16 +0100133 roles = self.roles_client.list_user_roles_on_domain(
John Warren56317e02015-08-12 20:48:32 +0000134 self.domain['id'], self.user_body['id'])['roles']
nayna-patel755d8142013-07-16 06:45:34 +0000135
zhufl628642b2017-08-01 14:39:34 +0800136 self.assertEqual(1, len(roles))
137 self.assertEqual(self.role['id'], roles[0]['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000138
Arx Cruz24bcb882016-02-10 15:20:16 +0100139 self.roles_client.check_user_role_existence_on_domain(
Maho Koshiyab6fa2e42015-12-07 16:52:53 +0900140 self.domain['id'], self.user_body['id'], self.role['id'])
141
Arx Cruz24bcb882016-02-10 15:20:16 +0100142 self.roles_client.delete_role_from_user_on_domain(
nayna-patel755d8142013-07-16 06:45:34 +0000143 self.domain['id'], self.user_body['id'], self.role['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000144
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -0800145 @decorators.idempotent_id('cbf11737-1904-4690-9613-97bcbb3df1c4')
Trevor McCaslandc44eadc2019-01-17 11:27:48 -0600146 @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
147 'Skipped because environment has an immutable user '
148 'source and solely provides read-only access to users.')
nayna-patel755d8142013-07-16 06:45:34 +0000149 def test_grant_list_revoke_role_to_group_on_project(self):
zhufla7635d72020-04-29 14:36:41 +0800150 """Test granting, listing, revoking role to group on project"""
wanglianmind599cc52014-03-17 17:03:56 +0800151 # Grant role to group on project
ghanshyam2e6fb562016-09-06 11:14:31 +0900152 self.roles_client.create_group_role_on_project(
nayna-patel755d8142013-07-16 06:45:34 +0000153 self.project['id'], self.group_body['id'], self.role['id'])
wanglianmind599cc52014-03-17 17:03:56 +0800154 # List group roles on project
Arx Cruz24bcb882016-02-10 15:20:16 +0100155 roles = self.roles_client.list_group_roles_on_project(
John Warren56317e02015-08-12 20:48:32 +0000156 self.project['id'], self.group_body['id'])['roles']
nayna-patel755d8142013-07-16 06:45:34 +0000157
zhufl628642b2017-08-01 14:39:34 +0800158 self.assertEqual(1, len(roles))
159 self.assertEqual(self.role['id'], roles[0]['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000160
wanglianmind599cc52014-03-17 17:03:56 +0800161 # Add user to group, and insure user has role on project
Yaroslav Lobankov997a1452015-11-19 17:11:37 +0300162 self.groups_client.add_group_user(self.group_body['id'],
163 self.user_body['id'])
164 self.addCleanup(self.groups_client.delete_group_user,
wanglianmind599cc52014-03-17 17:03:56 +0800165 self.group_body['id'], self.user_body['id'])
Jamie Lennox97504612015-02-26 16:47:06 +1100166 body = self.token.auth(user_id=self.user_body['id'],
Jamie Lennoxe5a95d42015-02-11 07:19:57 +0000167 password=self.u_password,
Jamie Lennox97504612015-02-26 16:47:06 +1100168 user_domain_name=self.domain['name'],
169 project_name=self.project['name'],
170 project_domain_name=self.domain['name'])
wanglianmind599cc52014-03-17 17:03:56 +0800171 roles = body['token']['roles']
wanglianmind599cc52014-03-17 17:03:56 +0800172 self.assertEqual(len(roles), 1)
173 self.assertEqual(roles[0]['id'], self.role['id'])
Maho Koshiyab6fa2e42015-12-07 16:52:53 +0900174
Arx Cruz24bcb882016-02-10 15:20:16 +0100175 self.roles_client.check_role_from_group_on_project_existence(
Maho Koshiyab6fa2e42015-12-07 16:52:53 +0900176 self.project['id'], self.group_body['id'], self.role['id'])
177
wanglianmind599cc52014-03-17 17:03:56 +0800178 # Revoke role to group on project
Arx Cruz24bcb882016-02-10 15:20:16 +0100179 self.roles_client.delete_role_from_group_on_project(
nayna-patel755d8142013-07-16 06:45:34 +0000180 self.project['id'], self.group_body['id'], self.role['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000181
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -0800182 @decorators.idempotent_id('4bf8a70b-e785-413a-ad53-9f91ce02faa7')
nayna-patel755d8142013-07-16 06:45:34 +0000183 def test_grant_list_revoke_role_to_group_on_domain(self):
zhufla7635d72020-04-29 14:36:41 +0800184 """Test granting, listing, revoking role to group on domain"""
ghanshyam2e6fb562016-09-06 11:14:31 +0900185 self.roles_client.create_group_role_on_domain(
nayna-patel755d8142013-07-16 06:45:34 +0000186 self.domain['id'], self.group_body['id'], self.role['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000187
Arx Cruz24bcb882016-02-10 15:20:16 +0100188 roles = self.roles_client.list_group_roles_on_domain(
John Warren56317e02015-08-12 20:48:32 +0000189 self.domain['id'], self.group_body['id'])['roles']
nayna-patel755d8142013-07-16 06:45:34 +0000190
zhufl628642b2017-08-01 14:39:34 +0800191 self.assertEqual(1, len(roles))
192 self.assertEqual(self.role['id'], roles[0]['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000193
Arx Cruz24bcb882016-02-10 15:20:16 +0100194 self.roles_client.check_role_from_group_on_domain_existence(
Maho Koshiyab6fa2e42015-12-07 16:52:53 +0900195 self.domain['id'], self.group_body['id'], self.role['id'])
196
Arx Cruz24bcb882016-02-10 15:20:16 +0100197 self.roles_client.delete_role_from_group_on_domain(
nayna-patel755d8142013-07-16 06:45:34 +0000198 self.domain['id'], self.group_body['id'], self.role['id'])
nayna-patel755d8142013-07-16 06:45:34 +0000199
Ken'ichi Ohmichieeabdd22017-01-27 17:46:00 -0800200 @decorators.idempotent_id('f5654bcc-08c4-4f71-88fe-05d64e06de94')
nayna-patelc905c182014-04-21 14:00:32 +0000201 def test_list_roles(self):
zhufla7635d72020-04-29 14:36:41 +0800202 """Test listing roles"""
nayna-patelc905c182014-04-21 14:00:32 +0000203 # Return a list of all roles
Arx Cruz24bcb882016-02-10 15:20:16 +0100204 body = self.roles_client.list_roles()['roles']
Castulo J. Martinez19b81b22016-07-15 08:58:25 -0700205 found = [role for role in body if role in self.roles]
206 self.assertEqual(len(found), len(self.roles))
Rodrigo Duarteca3b39d2017-01-26 18:10:31 -0300207
208 def _create_implied_role(self, prior_role_id, implies_role_id,
209 ignore_not_found=False):
210 self.roles_client.create_role_inference_rule(
211 prior_role_id, implies_role_id)
212 if ignore_not_found:
213 self.addCleanup(
214 test_utils.call_and_ignore_notfound_exc,
215 self.roles_client.delete_role_inference_rule,
216 prior_role_id,
217 implies_role_id)
218 else:
219 self.addCleanup(
220 self.roles_client.delete_role_inference_rule,
221 prior_role_id,
222 implies_role_id)
223
224 @decorators.idempotent_id('c90c316c-d706-4728-bcba-eb1912081b69')
jeremy.zhangef5d4e92017-05-04 19:19:27 +0800225 def test_implied_roles_create_check_show_delete(self):
zhufla7635d72020-04-29 14:36:41 +0800226 """Test creating, checking, showing and deleting implied roles"""
Rodrigo Duarteca3b39d2017-01-26 18:10:31 -0300227 prior_role_id = self.roles[0]['id']
228 implies_role_id = self.roles[1]['id']
229
230 # Create an inference rule from prior_role to implies_role
231 self._create_implied_role(prior_role_id, implies_role_id,
232 ignore_not_found=True)
233
234 # Check if the inference rule exists
jeremy.zhangef5d4e92017-05-04 19:19:27 +0800235 self.roles_client.check_role_inference_rule(
Rodrigo Duarteca3b39d2017-01-26 18:10:31 -0300236 prior_role_id, implies_role_id)
237
jeremy.zhangef5d4e92017-05-04 19:19:27 +0800238 # Show the inference rule and check its elements
239 resp_body = self.roles_client.show_role_inference_rule(
240 prior_role_id, implies_role_id)
241 self.assertIn('role_inference', resp_body)
242 role_inference = resp_body['role_inference']
243 for key1 in ['prior_role', 'implies']:
244 self.assertIn(key1, role_inference)
245 for key2 in ['id', 'links', 'name']:
246 self.assertIn(key2, role_inference[key1])
247
Rodrigo Duarteca3b39d2017-01-26 18:10:31 -0300248 # Delete the inference rule
249 self.roles_client.delete_role_inference_rule(
250 prior_role_id, implies_role_id)
251 # Check if the inference rule no longer exists
252 self.assertRaises(
253 lib_exc.NotFound,
254 self.roles_client.show_role_inference_rule,
255 prior_role_id,
256 implies_role_id)
257
258 @decorators.idempotent_id('dc6f5959-b74d-4e30-a9e5-a8255494ff00')
259 def test_roles_hierarchy(self):
zhufla7635d72020-04-29 14:36:41 +0800260 """Test creating implied role and listing role inferences rules"""
Rodrigo Duarteca3b39d2017-01-26 18:10:31 -0300261 # Create inference rule from "roles[0]" to "role[1]"
262 self._create_implied_role(
263 self.roles[0]['id'], self.roles[1]['id'])
264
265 # Create inference rule from "roles[0]" to "role[2]"
266 self._create_implied_role(
267 self.roles[0]['id'], self.roles[2]['id'])
268
269 # Create inference rule from "roles[2]" to "role"
270 self._create_implied_role(
271 self.roles[2]['id'], self.role['id'])
272
273 # Listing inferences rules from "roles[2]" should only return "role"
274 rules = self.roles_client.list_role_inferences_rules(
275 self.roles[2]['id'])['role_inference']
276 self.assertEqual(1, len(rules['implies']))
277 self.assertEqual(self.role['id'], rules['implies'][0]['id'])
278
279 # Listing inferences rules from "roles[0]" should return "roles[1]" and
280 # "roles[2]" (only direct rules are listed)
281 rules = self.roles_client.list_role_inferences_rules(
282 self.roles[0]['id'])['role_inference']
283 implies_ids = [role['id'] for role in rules['implies']]
284 self.assertEqual(2, len(implies_ids))
285 self.assertIn(self.roles[1]['id'], implies_ids)
286 self.assertIn(self.roles[2]['id'], implies_ids)
287
288 @decorators.idempotent_id('c8828027-df48-4021-95df-b65b92c7429e')
Trevor McCaslandc44eadc2019-01-17 11:27:48 -0600289 @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
290 'Skipped because environment has an immutable user '
291 'source and solely provides read-only access to users.')
Rodrigo Duarteca3b39d2017-01-26 18:10:31 -0300292 def test_assignments_for_implied_roles_create_delete(self):
zhufla7635d72020-04-29 14:36:41 +0800293 """Test assignments when implied roles are created and deleted"""
Rodrigo Duarteca3b39d2017-01-26 18:10:31 -0300294 # Create a grant using "roles[0]"
295 self.roles_client.create_user_role_on_project(
296 self.project['id'], self.user_body['id'], self.roles[0]['id'])
297 self.addCleanup(
298 self.roles_client.delete_role_from_user_on_project,
299 self.project['id'], self.user_body['id'], self.roles[0]['id'])
300
301 # Create an inference rule from "roles[0]" to "roles[1]"
302 self._create_implied_role(self.roles[0]['id'], self.roles[1]['id'],
303 ignore_not_found=True)
304
305 # In the effective list of role assignments, both prior role and
306 # implied role should be present. This means that a user can
307 # authenticate using both roles (both roles will be present
308 # in the token).
309 params = {'scope.project.id': self.project['id'],
310 'user.id': self.user_body['id']}
311 role_assignments = self.role_assignments.list_role_assignments(
312 effective=True, **params)['role_assignments']
313 self.assertEqual(2, len(role_assignments))
314
315 roles_ids = [assignment['role']['id']
316 for assignment in role_assignments]
317 self.assertIn(self.roles[0]['id'], roles_ids)
318 self.assertIn(self.roles[1]['id'], roles_ids)
319
320 # After deleting the implied role, only the assignment with "roles[0]"
321 # should be present.
322 self.roles_client.delete_role_inference_rule(
323 self.roles[0]['id'], self.roles[1]['id'])
324
325 role_assignments = self.role_assignments.list_role_assignments(
326 effective=True, **params)['role_assignments']
327 self.assertEqual(1, len(role_assignments))
328
329 roles_ids = [assignment['role']['id']
330 for assignment in role_assignments]
331 self.assertIn(self.roles[0]['id'], roles_ids)
Rodrigo Duarte34a65122017-01-27 11:28:26 -0300332
333 @decorators.idempotent_id('d92a41d2-5501-497a-84bb-6e294330e8f8')
334 def test_domain_roles_create_delete(self):
zhufla7635d72020-04-29 14:36:41 +0800335 """Test creating, listing and deleting domain roles"""
Rodrigo Duarte34a65122017-01-27 11:28:26 -0300336 domain_role = self.roles_client.create_role(
337 name=data_utils.rand_name('domain_role'),
338 domain_id=self.domain['id'])['role']
339 self.addCleanup(
340 test_utils.call_and_ignore_notfound_exc,
341 self.roles_client.delete_role,
342 domain_role['id'])
343
344 domain_roles = self.roles_client.list_roles(
345 domain_id=self.domain['id'])['roles']
346 self.assertEqual(1, len(domain_roles))
347 self.assertIn(domain_role, domain_roles)
348
349 self.roles_client.delete_role(domain_role['id'])
350 domain_roles = self.roles_client.list_roles(
351 domain_id=self.domain['id'])['roles']
352 self.assertEmpty(domain_roles)
353
354 @decorators.idempotent_id('eb1e1c24-1bc4-4d47-9748-e127a1852c82')
355 def test_implied_domain_roles(self):
zhufla7635d72020-04-29 14:36:41 +0800356 """Test creating implied roles when roles are in domains"""
Rodrigo Duarte34a65122017-01-27 11:28:26 -0300357 # Create two roles in the same domain
358 domain_role1 = self.setup_test_role(domain_id=self.domain['id'])
359 domain_role2 = self.setup_test_role(domain_id=self.domain['id'])
360
361 # Check if we can create an inference rule from roles in the same
362 # domain
363 self._create_implied_role(domain_role1['id'], domain_role2['id'])
364
365 # Create another role in a different domain
366 domain2 = self.setup_test_domain()
367 domain_role3 = self.setup_test_role(domain_id=domain2['id'])
368
369 # Check if we can create cross domain implied roles
370 self._create_implied_role(domain_role1['id'], domain_role3['id'])
371
372 # Finally, we also should be able to create an implied from a
373 # domain role to a global one
374 self._create_implied_role(domain_role1['id'], self.role['id'])
375
ghanshyamefb12be2017-12-10 04:18:38 +0300376 # The contrary is not true: we can't create an inference rule
377 # from a global role to a domain role
378 self.assertRaises(
379 lib_exc.Forbidden,
380 self.roles_client.create_role_inference_rule,
381 self.role['id'],
382 domain_role1['id'])
Rodrigo Duarte Sousa592148c2017-01-31 15:26:16 -0300383
Rodrigo Duarte34a65122017-01-27 11:28:26 -0300384 @decorators.idempotent_id('3859df7e-5b78-4e4d-b10e-214c8953842a')
Trevor McCaslandc44eadc2019-01-17 11:27:48 -0600385 @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
386 'Skipped because environment has an immutable user '
387 'source and solely provides read-only access to users.')
Rodrigo Duarte34a65122017-01-27 11:28:26 -0300388 def test_assignments_for_domain_roles(self):
zhufla7635d72020-04-29 14:36:41 +0800389 """Test assignments for domain roles"""
Rodrigo Duarte34a65122017-01-27 11:28:26 -0300390 domain_role = self.setup_test_role(domain_id=self.domain['id'])
391
392 # Create a grant using "domain_role"
393 self.roles_client.create_user_role_on_project(
394 self.project['id'], self.user_body['id'], domain_role['id'])
395 self.addCleanup(
396 self.roles_client.delete_role_from_user_on_project,
397 self.project['id'], self.user_body['id'], domain_role['id'])
398
399 # NOTE(rodrigods): Regular roles would appear in the effective
400 # list of role assignments (meaning the role would be returned in
401 # a token) as a result from the grant above. This is not the case
402 # for domain roles, they should not appear in the effective role
403 # assignments list.
404 params = {'scope.project.id': self.project['id'],
405 'user.id': self.user_body['id']}
406 role_assignments = self.role_assignments.list_role_assignments(
407 effective=True, **params)['role_assignments']
408 self.assertEmpty(role_assignments)
Felipe Monteirofe96c262017-03-31 05:25:26 +0100409
410 @decorators.idempotent_id('3748c316-c18f-4b08-997b-c60567bc6235')
411 def test_list_all_implied_roles(self):
zhufla7635d72020-04-29 14:36:41 +0800412 """Test listing all implied roles"""
Felipe Monteirofe96c262017-03-31 05:25:26 +0100413 # Create inference rule from "roles[0]" to "roles[1]"
414 self._create_implied_role(
415 self.roles[0]['id'], self.roles[1]['id'])
416
417 # Create inference rule from "roles[0]" to "roles[2]"
418 self._create_implied_role(
419 self.roles[0]['id'], self.roles[2]['id'])
420
421 # Create inference rule from "roles[2]" to "role"
422 self._create_implied_role(
423 self.roles[2]['id'], self.role['id'])
424
425 rules = self.roles_client.list_all_role_inference_rules()[
426 'role_inferences']
Juan Antonio Osorio Robles7d2b6362018-06-11 10:23:21 +0300427
428 # NOTE(jaosorior): With the work related to the define-default-roles
429 # blueprint, we now have 'admin', 'member' and 'reader' by default. So
430 # we filter every other implied role to only take into account the ones
431 # relates to this test.
432 relevant_roles = (self.roles[0]['id'], self.roles[1]['id'],
433 self.roles[2]['id'], self.role['id'])
434
435 def is_implied_role_relevant(rule):
436 return any(r for r in rule['implies'] if r['id'] in relevant_roles)
437
438 relevant_rules = filter(is_implied_role_relevant, rules)
Felipe Monteirofe96c262017-03-31 05:25:26 +0100439 # Sort the rules by the number of inferences, since there should be 1
440 # inference between "roles[2]" and "role" and 2 inferences for
441 # "roles[0]": between "roles[1]" and "roles[2]".
Juan Antonio Osorio Robles7d2b6362018-06-11 10:23:21 +0300442 sorted_rules = sorted(relevant_rules, key=lambda r: len(r['implies']))
Felipe Monteirofe96c262017-03-31 05:25:26 +0100443
Felipe Monteirofe96c262017-03-31 05:25:26 +0100444 self.assertEqual(2, len(sorted_rules))
445 # Check that only 1 inference rule exists between "roles[2]" and "role"
446 self.assertEqual(1, len(sorted_rules[0]['implies']))
447 # Check that 2 inference rules exist for "roles[0]": one between
448 # "roles[1]" and one between "roles[2]".
449 self.assertEqual(2, len(sorted_rules[1]['implies']))
450
451 # Check that "roles[2]" is the "prior_role" and that "role" is the
452 # "implies" role.
453 self.assertEqual(self.roles[2]['id'],
454 sorted_rules[0]['prior_role']['id'])
455 self.assertEqual(self.role['id'],
456 sorted_rules[0]['implies'][0]['id'])
457
458 # Check that "roles[0]" is the "prior_role" and that "roles[1]" and
459 # "roles[2]" are the "implies" roles.
460 self.assertEqual(self.roles[0]['id'],
461 sorted_rules[1]['prior_role']['id'])
462
463 implies_ids = [r['id'] for r in sorted_rules[1]['implies']]
464 self.assertIn(self.roles[1]['id'], implies_ids)
465 self.assertIn(self.roles[2]['id'], implies_ids)