fix ldap delete_user group member cleanup

When an LDAP user is deleted, keystone was removing it from groups that
matched the group_filter conf setting, but not from other groups. This
change fixes it to remove the user from all groups.

Closes-Bug: #1590584
Change-Id: Icca09d2782b4adf9519a24d1713adcb8b3e2a27c
This commit is contained in:
Matthew Edmonds 2016-06-08 17:46:15 -04:00
parent 53b186306c
commit 907ee2d15e
2 changed files with 42 additions and 5 deletions

View File

@ -22,7 +22,7 @@ import six
from keystone.common import driver_hints
from keystone import exception
from keystone.i18n import _
from keystone.i18n import _, _LW
from keystone.identity.backends import base
from keystone.identity.backends.ldap import common as common_ldap
from keystone.identity.backends.ldap import models
@ -124,7 +124,15 @@ class Identity(base.IdentityDriverV8):
user_dn = user['dn']
groups = self.group.list_user_groups(user_dn)
for group in groups:
self.group.remove_user(user_dn, group['id'], user_id)
group_ref = self.group.get(group['id'], '*') # unfiltered
group_dn = group_ref['dn']
try:
super(GroupApi, self.group).remove_member(user_dn, group_dn)
except ldap.NO_SUCH_ATTRIBUTE:
LOG.warning(
_LW('User %(user)s was not removed from group %(group)s '
'because the relationship was not found'),
{'user': user_id, 'group': group['id']})
if hasattr(user, 'tenant_id'):
self.project.remove_user(user.tenant_id, user_dn)
@ -374,9 +382,8 @@ class GroupApi(common_ldap.BaseLdap):
def list_user_groups(self, user_dn):
"""Return a list of groups for which the user is a member."""
user_dn_esc = ldap.filter.escape_filter_chars(user_dn)
query = '(%s=%s)%s' % (self.member_attribute,
user_dn_esc,
self.ldap_filter or '')
query = '(%s=%s)' % (self.member_attribute,
user_dn_esc)
return self.get_all(query)
def list_user_groups_filtered(self, user_dn, hints):

View File

@ -2060,6 +2060,36 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity):
self.identity_api.get_user,
user['id'])
def test_delete_user_group_cleanup(self):
domain = self._get_domain_fixture()
# setup: create user
user_dict = self.new_user_ref(domain_id=domain['id'])
user = self.identity_api.create_user(user_dict)
# setup: add user to 3 groups
group_names = []
numgroups = 3
for _ in range(numgroups):
group_dict = unit.new_group_ref(domain_id=domain['id'])
group = self.identity_api.create_group(group_dict)
group_names.append(group['name'])
self.identity_api.add_user_to_group(user['id'], group['id'])
# configure a group filter
driver = self.identity_api._select_identity_driver(domain['id'])
driver.group.ldap_filter = ('(|(ou=%s)(ou=%s))' %
tuple(group_names[:2]))
# confirm that user is a member of all 3 groups
group_api = self.identity_api.driver.group
user_dn_esc = self.identity_api.driver.user.get(user['id'])['dn']
groups = group_api.get_all('(%s=%s)' %
(group_api.member_attribute, user_dn_esc))
self.assertEqual(numgroups, len(groups))
# confirm that deleting user removes from all groups
self.identity_api.delete_user(user['id'])
groups = group_api.get_all('(%s=%s)' %
(group_api.member_attribute, user_dn_esc))
self.assertEqual(0, len(groups))
def test_user_auth_emulated(self):
driver = self.identity_api._select_identity_driver(
CONF.identity.default_domain_id)