Merge "Modify rules for domain specific role assignments"

This commit is contained in:
Jenkins 2016-02-17 10:00:25 +00:00 committed by Gerrit Code Review
commit 695ea9a857
3 changed files with 132 additions and 8 deletions

View File

@ -101,13 +101,20 @@
"identity:list_role_inference_rules": "rule:cloud_admin",
"identity:check_implied_role": "rule:cloud_admin",
"domain_admin_for_grants": "rule:admin_required and (domain_id:%(domain_id)s or domain_id:%(target.project.domain_id)s)",
"project_admin_for_grants": "rule:admin_required and project_id:%(project_id)s",
"identity:check_grant": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants",
"identity:list_grants": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants",
"identity:list_grants": "rule:cloud_admin or rule:domain_admin_for_list_grants or rule:project_admin_for_list_grants",
"identity:create_grant": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants",
"identity:revoke_grant": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants",
"domain_admin_for_grants": "rule:domain_admin_for_global_role_grants or rule:domain_admin_for_domain_role_grants",
"domain_admin_for_global_role_grants": "rule:admin_required and None:%(target.role.domain_id)s and rule:domain_admin_grant_match",
"domain_admin_for_domain_role_grants": "rule:admin_required and domain_id:%(target.role.domain_id)s and rule:domain_admin_grant_match",
"domain_admin_grant_match": "domain_id:%(domain_id)s or domain_id:%(target.project.domain_id)s",
"project_admin_for_grants": "rule:project_admin_for_global_role_grants or rule:project_admin_for_domain_role_grants",
"project_admin_for_global_role_grants": "rule:admin_required and None:%(target.role.domain_id)s and project_id:%(project_id)s",
"project_admin_for_domain_role_grants": "rule:admin_required and project_domain_id:%(target.role.domain_id)s and project_id:%(project_id)s",
"domain_admin_for_list_grants": "rule:admin_required and rule:domain_admin_grant_match",
"project_admin_for_list_grants": "rule:admin_required and project_id:%(project_id)s",
"admin_on_domain_filter" : "rule:admin_required and domain_id:%(scope.domain.id)s",
"admin_on_project_filter" : "rule:admin_required and project_id:%(scope.project.id)s",
"admin_on_domain_of_project_filter" : "rule:admin_required and domain_id:%(target.project.domain_id)s",

View File

@ -735,9 +735,10 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
self.post('/domains', auth=self.auth, body={'domain': domain_ref},
expected_status=status_created)
def _test_grants(self, target, entity_id, expected=None):
def _test_grants(self, target, entity_id, role_domain_id=None,
list_status_OK=False, expected=None):
status_OK, status_created, status_no_data = self._stati(expected)
a_role = unit.new_role_ref()
a_role = unit.new_role_ref(domain_id=role_domain_id)
self.role_api.create_role(a_role['id'], a_role)
collection_url = (
@ -753,8 +754,11 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
expected_status=status_no_data)
self.head(member_url, auth=self.auth,
expected_status=status_no_data)
self.get(collection_url, auth=self.auth,
expected_status=status_OK)
if list_status_OK:
self.get(collection_url, auth=self.auth)
else:
self.get(collection_url, auth=self.auth,
expected_status=status_OK)
self.delete(member_url, auth=self.auth,
expected_status=status_no_data)
@ -983,6 +987,52 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
self._test_grants('domains', self.domainA['id'])
def test_domain_grants_by_cloud_admin_for_domain_specific_role(self):
# Test domain grants with a cloud admin. This user should be
# able to manage domain roles on any domain.
self.auth = self.build_authentication_request(
user_id=self.cloud_admin_user['id'],
password=self.cloud_admin_user['password'],
project_id=self.admin_project['id'])
self._test_grants('domains', self.domainA['id'],
role_domain_id=self.domainB['id'])
def test_domain_grants_by_non_admin_for_domain_specific_role(self):
# A non-admin shouldn't be able to do anything
self.auth = self.build_authentication_request(
user_id=self.just_a_user['id'],
password=self.just_a_user['password'],
domain_id=self.domainA['id'])
self._test_grants('domains', self.domainA['id'],
role_domain_id=self.domainA['id'],
expected=exception.ForbiddenAction.code)
self._test_grants('domains', self.domainA['id'],
role_domain_id=self.domainB['id'],
expected=exception.ForbiddenAction.code)
def test_domain_grants_by_domain_admin_for_domain_specific_role(self):
# Authenticate with a user that does have the domain admin role,
# should not be able to assign a domain_specific role from another
# domain
self.auth = self.build_authentication_request(
user_id=self.domain_admin_user['id'],
password=self.domain_admin_user['password'],
domain_id=self.domainA['id'])
self._test_grants('domains', self.domainA['id'],
role_domain_id=self.domainB['id'],
# List status will always be OK, since we are not
# granting/checking/deleting assignments
list_status_OK=True,
expected=exception.ForbiddenAction.code)
# They should be able to assign a domain specific role from the same
# domain
self._test_grants('domains', self.domainA['id'],
role_domain_id=self.domainA['id'])
def test_project_grants(self):
self.auth = self.build_authentication_request(
user_id=self.just_a_user['id'],
@ -1011,6 +1061,62 @@ class IdentityTestv3CloudPolicySample(test_v3.RestfulTestCase,
self._test_grants('projects', self.project['id'])
def test_project_grants_by_non_admin_for_domain_specific_role(self):
# A non-admin shouldn't be able to do anything
self.auth = self.build_authentication_request(
user_id=self.just_a_user['id'],
password=self.just_a_user['password'],
project_id=self.project['id'])
self._test_grants('projects', self.project['id'],
role_domain_id=self.domainA['id'],
expected=exception.ForbiddenAction.code)
self._test_grants('projects', self.project['id'],
role_domain_id=self.domainB['id'],
expected=exception.ForbiddenAction.code)
def test_project_grants_by_project_admin_for_domain_specific_role(self):
# Authenticate with a user that does have the project admin role,
# should not be able to assign a domain_specific role from another
# domain
self.auth = self.build_authentication_request(
user_id=self.project_admin_user['id'],
password=self.project_admin_user['password'],
project_id=self.project['id'])
self._test_grants('projects', self.project['id'],
role_domain_id=self.domainB['id'],
# List status will always be OK, since we are not
# granting/checking/deleting assignments
list_status_OK=True,
expected=exception.ForbiddenAction.code)
# They should be able to assign a domain specific role from the same
# domain
self._test_grants('projects', self.project['id'],
role_domain_id=self.domainA['id'])
def test_project_grants_by_domain_admin_for_domain_specific_role(self):
# Authenticate with a user that does have the domain admin role,
# should not be able to assign a domain_specific role from another
# domain
self.auth = self.build_authentication_request(
user_id=self.domain_admin_user['id'],
password=self.domain_admin_user['password'],
domain_id=self.domainA['id'])
self._test_grants('projects', self.project['id'],
role_domain_id=self.domainB['id'],
# List status will always be OK, since we are not
# granting/checking/deleting assignments
list_status_OK=True,
expected=exception.ForbiddenAction.code)
# They should be able to assign a domain specific role from the same
# domain
self._test_grants('projects', self.project['id'],
role_domain_id=self.domainA['id'])
def test_cloud_admin_list_assignments_of_domain(self):
self.auth = self.build_authentication_request(
user_id=self.cloud_admin_user['id'],

View File

@ -0,0 +1,11 @@
---
features:
- >
[`blueprint domain-specific-roles <https://blueprints.launchpad.net/keystone/+spec/domain-specific-roles>`_]
Roles can now be optionally defined as domain specific. Domain specific
roles are not references in policy files, rather they can be used to allow
a domain to build their own private inference rules with implies roles. A
domain specific role can be assigned to a domain or project within its
domain, and any subset of global roles it implies will appear in a token
scoped to the respective domain or project. The domain specific role
itself, however, will not appear in the token.