diff --git a/keystone/assignment/core.py b/keystone/assignment/core.py index 508e181b55..f0058fb821 100644 --- a/keystone/assignment/core.py +++ b/keystone/assignment/core.py @@ -1222,9 +1222,13 @@ class RoleManager(manager.Manager): # TODO(ayoung): Add notification def create_implied_role(self, prior_role_id, implied_role_id): implied_role = self.driver.get_role(implied_role_id) - self.driver.get_role(prior_role_id) + prior_role = self.driver.get_role(prior_role_id) if implied_role['name'] in CONF.assignment.prohibited_implied_role: raise exception.InvalidImpliedRole(role_id=implied_role_id) + if prior_role['domain_id'] is None and implied_role['domain_id']: + msg = _('Global role cannot imply a domain-specific role') + raise exception.InvalidImpliedRole(msg, + role_id=implied_role_id) response = self.driver.create_implied_role( prior_role_id, implied_role_id) COMPUTED_ASSIGNMENTS_REGION.invalidate() diff --git a/keystone/tests/unit/test_v3_assignment.py b/keystone/tests/unit/test_v3_assignment.py index 30b54061a8..6b4a56a5a4 100644 --- a/keystone/tests/unit/test_v3_assignment.py +++ b/keystone/tests/unit/test_v3_assignment.py @@ -2748,6 +2748,21 @@ class ImpliedRolesTests(test_v3.RestfulTestCase, test_v3.AssignmentTestMixin, self.assertIn(role, token['roles']) self.assertNotIn(self.role_list[0], token['roles']) + def test_global_role_cannot_imply_domain_specific_role(self): + domain = unit.new_domain_ref() + self.resource_api.create_domain(domain['id'], domain) + + domain_role_ref = unit.new_role_ref(domain_id=domain['id']) + domain_role = self.role_api.create_role(domain_role_ref['id'], + domain_role_ref) + global_role_ref = unit.new_role_ref() + global_role = self.role_api.create_role(global_role_ref['id'], + global_role_ref) + + self.put('/roles/%s/implies/%s' % (global_role['id'], + domain_role['id']), + expected_status=http_client.FORBIDDEN) + class DomainSpecificRoleTests(test_v3.RestfulTestCase, unit.TestCase): def setUp(self):