Modify rules for domain specific role assignments

Building on the support for domain specific roles, this final
patch in the series adjusts the policy rules for grants using
domain specific roles in the v3cloudsample.

In addition, a release note is provide for the domain specifc
role functionality.

Implements: blueprint domain-specific-roles
Change-Id: I941611237ddd48cb87337bcebd61cfda52479f87
This commit is contained in:
Henry Nash 2016-01-04 20:57:46 +00:00
parent a270766eb9
commit a4e9ea5fef
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.