Fix incorrect assumption when deleting assignments

The methods delete_user_assignments() and delete_group_assignments()
in the assignment backend remove all assignments for a user/group -
although the code fails to set the type of assignment and just uses
actor_id, making an assumption that user_id != group_id.

This patch specifies the type of assignments in the delete (i.e
USER_PROJECT/USER_DOMAIN or GROUP_PROJECT/GROUP_DOMAIN) to make sure
no assignment will be mistakenly deleted.

Change-Id: I246a61a291dd41490f49b7b26a04f93e69e61d7a
Closes-Bug: #1440135
This commit is contained in:
Clenimar Filemon 2016-02-20 12:47:24 -03:00
parent 19b058574e
commit 809e5533cc
3 changed files with 146 additions and 2 deletions

View File

@ -267,13 +267,19 @@ class Assignment(keystone_assignment.AssignmentDriverV9):
def delete_user_assignments(self, user_id):
with sql.transaction() as session:
q = session.query(RoleAssignment)
q = q.filter_by(actor_id=user_id)
q = q.filter_by(actor_id=user_id).filter(
RoleAssignment.type.in_((AssignmentType.USER_PROJECT,
AssignmentType.USER_DOMAIN))
)
q.delete(False)
def delete_group_assignments(self, group_id):
with sql.transaction() as session:
q = session.query(RoleAssignment)
q = q.filter_by(actor_id=group_id)
q = q.filter_by(actor_id=group_id).filter(
RoleAssignment.type.in_((AssignmentType.GROUP_PROJECT,
AssignmentType.GROUP_DOMAIN))
)
q.delete(False)

View File

@ -31,3 +31,9 @@ class SqlIdentityV8(test_backend_sql.SqlIdentity):
def test_delete_project_assignments_same_id_as_domain(self):
self.skipTest("V8 doesn't support project acting as a domain.")
def test_delete_user_assignments_user_same_id_as_group(self):
self.skipTest("Groups and users with the same ID are not supported.")
def test_delete_group_assignments_group_same_id_as_user(self):
self.skipTest("Groups and users with the same ID are not supported.")

View File

@ -4766,6 +4766,138 @@ class IdentityTests(AssignmentTestHelperMixin):
for assignment in domain_assignments:
self.assertThat(assignment.keys(), matchers.Contains('domain_id'))
def test_delete_user_assignments_user_same_id_as_group(self):
"""Test deleting user assignments when user_id == group_id.
In this scenario, only user assignments must be deleted (i.e.
USER_DOMAIN or USER_PROJECT).
Test plan:
* Create a user and a group with the same ID;
* Create four roles and assign them to both user and group;
* Delete all user assignments;
* Group assignments must stay intact.
"""
# Create a common ID
common_id = uuid.uuid4().hex
# Create a project
project = unit.new_project_ref(domain_id=DEFAULT_DOMAIN_ID)
project = self.resource_api.create_project(project['id'], project)
# Create a user
user = unit.new_user_ref(id=common_id,
domain_id=DEFAULT_DOMAIN_ID)
user = self.identity_api.driver.create_user(common_id, user)
self.assertEqual(common_id, user['id'])
# Create a group
group = unit.new_group_ref(id=common_id,
domain_id=DEFAULT_DOMAIN_ID)
group = self.identity_api.driver.create_group(common_id, group)
self.assertEqual(common_id, group['id'])
# Create four roles
roles = []
for _ in range(4):
role = unit.new_role_ref()
roles.append(self.role_api.create_role(role['id'], role))
# Assign roles for user
self.assignment_api.driver.create_grant(user_id=user['id'],
domain_id=DEFAULT_DOMAIN_ID,
role_id=roles[0]['id'])
self.assignment_api.driver.create_grant(user_id=user['id'],
project_id=project['id'],
role_id=roles[1]['id'])
# Assign roles for group
self.assignment_api.driver.create_grant(group_id=group['id'],
domain_id=DEFAULT_DOMAIN_ID,
role_id=roles[2]['id'])
self.assignment_api.driver.create_grant(group_id=group['id'],
project_id=project['id'],
role_id=roles[3]['id'])
# Make sure they were assigned
user_assignments = self.assignment_api.list_role_assignments(
user_id=user['id'])
self.assertThat(user_assignments, matchers.HasLength(2))
group_assignments = self.assignment_api.list_role_assignments(
group_id=group['id'])
self.assertThat(group_assignments, matchers.HasLength(2))
# Delete user assignments
self.assignment_api.delete_user_assignments(user_id=user['id'])
# Assert only user assignments were deleted
user_assignments = self.assignment_api.list_role_assignments(
user_id=user['id'])
self.assertThat(user_assignments, matchers.HasLength(0))
group_assignments = self.assignment_api.list_role_assignments(
group_id=group['id'])
self.assertThat(group_assignments, matchers.HasLength(2))
# Make sure these remaining assignments are group-related
for assignment in group_assignments:
self.assertThat(assignment.keys(), matchers.Contains('group_id'))
def test_delete_group_assignments_group_same_id_as_user(self):
"""Test deleting group assignments when group_id == user_id.
In this scenario, only group assignments must be deleted (i.e.
GROUP_DOMAIN or GROUP_PROJECT).
Test plan:
* Create a group and a user with the same ID;
* Create four roles and assign them to both group and user;
* Delete all group assignments;
* User assignments must stay intact.
"""
# Create a common ID
common_id = uuid.uuid4().hex
# Create a project
project = unit.new_project_ref(domain_id=DEFAULT_DOMAIN_ID)
project = self.resource_api.create_project(project['id'], project)
# Create a user
user = unit.new_user_ref(id=common_id,
domain_id=DEFAULT_DOMAIN_ID)
user = self.identity_api.driver.create_user(common_id, user)
self.assertEqual(common_id, user['id'])
# Create a group
group = unit.new_group_ref(id=common_id,
domain_id=DEFAULT_DOMAIN_ID)
group = self.identity_api.driver.create_group(common_id, group)
self.assertEqual(common_id, group['id'])
# Create four roles
roles = []
for _ in range(4):
role = unit.new_role_ref()
roles.append(self.role_api.create_role(role['id'], role))
# Assign roles for user
self.assignment_api.driver.create_grant(user_id=user['id'],
domain_id=DEFAULT_DOMAIN_ID,
role_id=roles[0]['id'])
self.assignment_api.driver.create_grant(user_id=user['id'],
project_id=project['id'],
role_id=roles[1]['id'])
# Assign roles for group
self.assignment_api.driver.create_grant(group_id=group['id'],
domain_id=DEFAULT_DOMAIN_ID,
role_id=roles[2]['id'])
self.assignment_api.driver.create_grant(group_id=group['id'],
project_id=project['id'],
role_id=roles[3]['id'])
# Make sure they were assigned
user_assignments = self.assignment_api.list_role_assignments(
user_id=user['id'])
self.assertThat(user_assignments, matchers.HasLength(2))
group_assignments = self.assignment_api.list_role_assignments(
group_id=group['id'])
self.assertThat(group_assignments, matchers.HasLength(2))
# Delete group assignments
self.assignment_api.delete_group_assignments(group_id=group['id'])
# Assert only group assignments were deleted
group_assignments = self.assignment_api.list_role_assignments(
group_id=group['id'])
self.assertThat(group_assignments, matchers.HasLength(0))
user_assignments = self.assignment_api.list_role_assignments(
user_id=user['id'])
self.assertThat(user_assignments, matchers.HasLength(2))
# Make sure these remaining assignments are user-related
for assignment in group_assignments:
self.assertThat(assignment.keys(), matchers.Contains('user_id'))
class TokenTests(object):
def _create_token_id(self):