Removed duplication with list_user_ids_for_project

Keystone list_user_ids_for_project has the possibility of returning
duplicate users if the user has more than one role in the project.
list_user_ids_for_project queries the assignment table which has
one entry for every role the user has but will now remove
duplicate combinations of target_id and actor_id. This impacts
V2 calls for tenants.list_users(<tenant_id>) and
users.list(tenant_id=<tenant_id>).

Change-Id: I9a1e5b944c2c627138851976e81d405f54fae1c9
Closes-Bug: #1308218
(cherry picked from commit d6cb7043cb)
This commit is contained in:
Christina Darretta 2014-04-18 11:36:31 -04:00 committed by Kieran Spear
parent 1716748df1
commit 0bd819c469
2 changed files with 33 additions and 0 deletions

View File

@ -70,6 +70,7 @@ class Assignment(assignment.Driver):
query = session.query(RoleAssignment.actor_id)
query = query.filter_by(type=AssignmentType.USER_PROJECT)
query = query.filter_by(target_id=tenant_id)
query = query.distinct('actor_id', 'target_id')
assignments = query.all()
return [assignment.actor_id for assignment in assignments]

View File

@ -185,6 +185,38 @@ class IdentityTests(object):
self.assertIn(self.user_two['id'], user_ids)
self.assertIn(self.user_badguy['id'], user_ids)
def test_list_user_ids_for_project_no_duplicates(self):
# Create user
user_ref = {
'id': uuid.uuid4().hex,
'name': uuid.uuid4().hex,
'domain_id': DEFAULT_DOMAIN_ID,
'password': uuid.uuid4().hex,
'enabled': True}
self.identity_api.create_user(user_ref['id'], user_ref)
# Create project
project_ref = {
'id': uuid.uuid4().hex,
'name': uuid.uuid4().hex,
'domain_id': DEFAULT_DOMAIN_ID}
self.assignment_api.create_project(
project_ref['id'], project_ref)
# Create 2 roles and give user each role in project
for i in range(2):
role_ref = {
'id': uuid.uuid4().hex,
'name': uuid.uuid4().hex}
self.assignment_api.create_role(role_ref['id'], role_ref)
self.assignment_api.add_role_to_user_and_project(
user_id=user_ref['id'],
tenant_id=project_ref['id'],
role_id=role_ref['id'])
# Get the list of user_ids in project
user_ids = self.assignment_api.list_user_ids_for_project(
project_ref['id'])
# Ensure the user is only returned once
self.assertEqual(1, len(user_ids))
def test_get_project_user_ids_404(self):
self.assertRaises(exception.ProjectNotFound,
self.assignment_api.list_user_ids_for_project,