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:
parent
f82b913db6
commit
73bdbe1f87
@ -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()
|
||||||
|
@ -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, "
|
||||||
|
@ -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."""
|
||||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user