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,
domain_id=None, project_id=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:
self.resource_api.get_domain(domain_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,
project_id, inherited_to_projects)
COMPUTED_ASSIGNMENTS_REGION.invalidate()

View File

@ -350,6 +350,11 @@ class InvalidImpliedRole(Forbidden):
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):
message_format = _("Could not find role assignment with role: "
"%(role_id)s, user or group: %(actor_id)s, "

View File

@ -20,6 +20,7 @@ from six.moves import range
from testtools import matchers
import keystone.conf
from keystone import exception
from keystone.tests import unit
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.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):
"""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.