Project domain must match role domain for assignment

When assigning a Domain specific role to a user it is OK if the user
is from a different domain, but the project's domain must match the
role's domain.

Closes-Bug: 1590587
Change-Id: I1d63415de0130794939998c3e142ebdce9ddf39d
This commit is contained in:
Sean Perry 2016-09-02 16:48:54 -07:00
parent f82b913db6
commit 73bdbe1f87
4 changed files with 62 additions and 2 deletions

View File

@ -339,11 +339,19 @@ class Manager(manager.Manager):
def create_grant(self, role_id, user_id=None, group_id=None, def create_grant(self, role_id, user_id=None, group_id=None,
domain_id=None, project_id=None, domain_id=None, project_id=None,
inherited_to_projects=False, context=None): inherited_to_projects=False, context=None):
self.role_api.get_role(role_id) role = self.role_api.get_role(role_id)
if domain_id: if domain_id:
self.resource_api.get_domain(domain_id) self.resource_api.get_domain(domain_id)
if project_id: if project_id:
self.resource_api.get_project(project_id) project = self.resource_api.get_project(project_id)
# For domain specific roles, the domain of the project must match
# the roles's
if role['domain_id'] and project['domain_id'] != role['domain_id']:
raise exception.DomainSpecificRoleMismatch(
role_id=role_id,
project_id=project_id)
self.driver.create_grant(role_id, user_id, group_id, domain_id, self.driver.create_grant(role_id, user_id, group_id, domain_id,
project_id, inherited_to_projects) project_id, inherited_to_projects)
COMPUTED_ASSIGNMENTS_REGION.invalidate() COMPUTED_ASSIGNMENTS_REGION.invalidate()

View File

@ -350,6 +350,11 @@ class InvalidImpliedRole(Forbidden):
message_format = _("%(role_id)s cannot be an implied roles") message_format = _("%(role_id)s cannot be an implied roles")
class DomainSpecificRoleMismatch(Forbidden):
message_format = _("project: %(project_id)s must be in the same domain "
" as the role: %(role_id)s being assigned.")
class RoleAssignmentNotFound(NotFound): class RoleAssignmentNotFound(NotFound):
message_format = _("Could not find role assignment with role: " message_format = _("Could not find role assignment with role: "
"%(role_id)s, user or group: %(actor_id)s, " "%(role_id)s, user or group: %(actor_id)s, "

View File

@ -20,6 +20,7 @@ from six.moves import range
from testtools import matchers from testtools import matchers
import keystone.conf import keystone.conf
from keystone import exception
from keystone.tests import unit from keystone.tests import unit
from keystone.tests.unit import test_v3 from keystone.tests.unit import test_v3
@ -2820,6 +2821,45 @@ class DomainSpecificRoleTests(test_v3.RestfulTestCase, unit.TestCase):
self.assertValidRoleListResponse(r, expected_length=1) self.assertValidRoleListResponse(r, expected_length=1)
self.assertRoleInListResponse(r, self.domainA_role2) self.assertRoleInListResponse(r, self.domainA_role2)
def test_same_domain_assignment(self):
user = unit.create_user(self.identity_api,
domain_id=self.domainA['id'])
projectA = unit.new_project_ref(domain_id=self.domainA['id'])
self.resource_api.create_project(projectA['id'], projectA)
self.assignment_api.create_grant(self.domainA_role1['id'],
user_id=user['id'],
project_id=projectA['id'])
def test_cross_domain_assignment_valid(self):
user = unit.create_user(self.identity_api,
domain_id=self.domainB['id'])
projectA = unit.new_project_ref(domain_id=self.domainA['id'])
self.resource_api.create_project(projectA['id'], projectA)
# Positive: a role on domainA can be assigned to a user from domainB
# but only for use on a project from domainA
self.assignment_api.create_grant(self.domainA_role1['id'],
user_id=user['id'],
project_id=projectA['id'])
def test_cross_domain_assignment_invalid(self):
user = unit.create_user(self.identity_api,
domain_id=self.domainB['id'])
projectB = unit.new_project_ref(domain_id=self.domainB['id'])
self.resource_api.create_project(projectB['id'], projectB)
# Negative: a role on domainA can be assigned to a user from domainB
# only for a project from domainA
self.assertRaises(exception.DomainSpecificRoleMismatch,
self.assignment_api.create_grant,
self.domainA_role1['id'],
user_id=user['id'],
project_id=projectB['id'])
class ListUserProjectsTestCase(test_v3.RestfulTestCase): class ListUserProjectsTestCase(test_v3.RestfulTestCase):
"""Test for /users/<user>/projects.""" """Test for /users/<user>/projects."""

View File

@ -0,0 +1,7 @@
---
fixes:
- >
[`bug 1590587 <https://bugs.launchpad.net/keystone/+bug/1590587>`_]
When assigning Domain Specific Roles, the domain of the role and the
domain of the project must match. This is now validated and the REST
call will return a 403 Forbidden.