Skip to content

Commit

Permalink
Return correct link for effective group roles in GET /role_assignments
Browse files Browse the repository at this point in the history
The assignment link returned for roles that are included by virtue of
group membership should refer to the group assignment that led to this
role, rather than a direct user assignment.

Fixes bug 1201374

Change-Id: Ic649e7eb4633e258264f27280d938a08af380921
  • Loading branch information
henrynash committed Jul 17, 2013
1 parent 2667c77 commit 2af9ce3
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 24 deletions.
17 changes: 4 additions & 13 deletions keystone/identity/controllers.py
Expand Up @@ -950,23 +950,14 @@ def _build_user_assignment_equivalent_of_group(
"""Create a user assignment equivalent to the group one.
The template has had the 'group' entity removed, so
substitute a 'user' one, modify the 'assignment' link
to match, and add a 'membership' link.
substitute a 'user' one. The 'assignment' link stays as it is,
referring to the group assignment that led to this role.
A 'membership' link is added that refers to this particular
user's membership of this group.
"""
user_entry = copy.deepcopy(template)
user_entry['user'] = {'id': user['id']}
scope = user_entry.get('scope')
if 'domain' in scope:
target_link = (
'/domains/%s' % scope['domain']['id'])
else:
target_link = (
'/projects/%s' % scope['project']['id'])
user_entry['links']['assignment'] = (
self.base_url('%s/users/%s/roles/%s' %
(target_link, user['id'],
user_entry['role']['id'])))
user_entry['links']['membership'] = (
self.base_url('/groups/%s/users/%s' %
(group_id, user['id'])))
Expand Down
28 changes: 17 additions & 11 deletions tests/test_v3_identity.py
Expand Up @@ -827,14 +827,17 @@ def test_get_effective_role_assignments(self):
self.assertValidRoleAssignmentListResponse(r)
self.assertEqual(len(r.result.get('role_assignments')),
existing_assignments + 2)
ud_url, ud_entity = _build_role_assignment_url_and_entity(
unused, ud_entity = _build_role_assignment_url_and_entity(
domain_id=self.domain_id, user_id=self.user1['id'],
role_id=self.role_id)
self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url)
gd_url, unused = _build_role_assignment_url_and_entity(
domain_id=self.domain_id, group_id=self.group['id'],
role_id=self.role_id)
self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=gd_url)
ud_url, ud_entity = _build_role_assignment_url_and_entity(
domain_id=self.domain_id, user_id=self.user2['id'],
role_id=self.role_id)
self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url)
self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=gd_url)

def test_check_effective_values_for_role_assignments(self):
"""Call ``GET /role_assignments?effective=value``.
Expand Down Expand Up @@ -1049,16 +1052,22 @@ def test_filtered_role_assignments(self):
self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url)
self.assertRoleAssignmentInListResponse(r, ud_entity, link_url=ud_url)
# ...and the two via group membership...
up1_url, up1_entity = _build_role_assignment_url_and_entity(
unused, up1_entity = _build_role_assignment_url_and_entity(
project_id=self.project1['id'], user_id=self.user1['id'],
role_id=self.role1['id'])
ud1_url, ud1_entity = _build_role_assignment_url_and_entity(
unused, ud1_entity = _build_role_assignment_url_and_entity(
domain_id=self.domain_id, user_id=self.user1['id'],
role_id=self.role1['id'])
gp1_url, unused = _build_role_assignment_url_and_entity(
project_id=self.project1['id'], group_id=self.group1['id'],
role_id=self.role1['id'])
gd1_url, unused = _build_role_assignment_url_and_entity(
domain_id=self.domain_id, group_id=self.group1['id'],
role_id=self.role1['id'])
self.assertRoleAssignmentInListResponse(r, up1_entity,
link_url=up1_url)
link_url=gp1_url)
self.assertRoleAssignmentInListResponse(r, ud1_entity,
link_url=ud1_url)
link_url=gd1_url)

# ...and for the grand-daddy of them all, simulate the request
# that would generate the list of effective roles in a project
Expand All @@ -1073,12 +1082,9 @@ def test_filtered_role_assignments(self):
self.assertValidRoleAssignmentListResponse(r)
self.assertEqual(len(r.result.get('role_assignments')), 2)
# Should have one direct role and one from group membership...
up1_url, up1_entity = _build_role_assignment_url_and_entity(
project_id=self.project1['id'], user_id=self.user1['id'],
role_id=self.role1['id'])
self.assertRoleAssignmentInListResponse(r, up_entity, link_url=up_url)
self.assertRoleAssignmentInListResponse(r, up1_entity,
link_url=up1_url)
link_url=gp1_url)


class IdentityIneritanceTestCase(test_v3.RestfulTestCase):
Expand Down

0 comments on commit 2af9ce3

Please sign in to comment.