feat: new method to search for members ldap groups

New method to search for user group membership. Replaces old logic of using an ldap users attribute memberof which is not supported by all LDAP implementations

issue #13738
This commit is contained in:
Jon Lockwood 2021-07-25 11:03:47 +09:30
parent 1f0e0d23ed
commit 622800453a

View file

@ -142,6 +142,60 @@ class LDAPSettings(Document):
return ldap_attributes
def fetch_ldap_groups(self, user, conn):
fetch_ldap_groups = None
ldap_attributes = ['cn']
ldap_object_class = None
ldap_group_members_attribute = None
ldap_group_search_filter = None
if self.ldap_directory_server.lower() == 'active directory':
ldap_object_class = 'Group'
ldap_group_members_attribute = 'member'
elif self.ldap_directory_server.lower() == 'openldap':
ldap_object_class = 'GroupOfNames'
ldap_group_members_attribute = 'member'
elif self.ldap_directory_server.lower() == 'custom':
ldap_object_class = self.ldap_group_objectclass
ldap_group_members_attribute = self.ldap_group_member_attribute
else:
# NOTE: depreciate this path
# this path will be hit for everyone with preconfigured ldap settings. this must be taken into account so as not to break ldap for those users.
if self.ldap_group_field:
fetch_ldap_groups = getattr(user, self.ldap_group_field).values
if ldap_object_class is not None:
conn.search(
search_base=self.organizational_unit_for_groups,
search_filter="(&(objectClass={0})({1}={2}))".format(ldap_object_class,ldap_group_members_attribute, user),
attributes=ldap_attributes) # Build search query
if len(conn.entries) >= 1:
fetch_ldap_groups = []
for group in conn.entries:
fetch_ldap_groups.append(group['cn'].value)
return fetch_ldap_groups
def authenticate(self, username, password):
if not self.enabled:
@ -162,9 +216,8 @@ class LDAPSettings(Document):
# only try and connect as the user, once we have their fqdn entry.
self.connect_to_ldap(base_dn=user.entry_dn, password=password)
groups = None
if self.ldap_group_field:
groups = getattr(user, self.ldap_group_field).values
groups = self.fetch_ldap_groups(user, conn)
return self.create_or_update_user(self.convert_ldap_entry_to_dict(user), groups=groups)
else:
frappe.throw(_("Invalid username or password"))