def get_groups(self, use_lookup_base=False): """Return all LDAP groups below the adapted LDAPUserFolder's `groups_base` (or the `lookup_groups_base` if `use_lookup_base` is True). If defined, the `group_filter` property on the adapted LDAPUserFolder is used to further filter the results. """ # Build a filter expression that matches objectClasses for all # possible group objectClasseses encountered in the wild possible_classes = '' for oc in GROUP_MEMBER_MAP.keys(): # concatenate (objectClass=foo) pairs possible_classes += filter_format('(%s=%s)', ('objectClass', oc)) # Build the final OR expression: # (|(objectClass=aaa)(objectClass=bbb)(objectClass=ccc)) search_filter = '(|%s)' % possible_classes custom_filter = self.get_group_filter() search_filter = self._combine_filters(custom_filter, search_filter) if use_lookup_base: base_dn = getattr( self.context, 'lookup_groups_base', self.context.groups_base) else: base_dn = self.context.groups_base results = self.search(base_dn=base_dn, search_filter=search_filter) mapped_results = [] for result in results: mapped_results.append(self.apply_schema_map(result)) return mapped_results
def get_groups(self): """Return all LDAP groups below the adapted LDAPUserFolder's groups_base. If defined, the `group_filter` property on the adapted LDAPUserFolder is used to further filter the results. """ # Build a filter expression that matches objectClasses for all # possible group objectClasseses encountered in the wild possible_classes = '' for oc in GROUP_MEMBER_MAP.keys(): # concatenate (objectClass=foo) pairs possible_classes += filter_format('(%s=%s)', ('objectClass', oc)) # Build the final OR expression: # (|(objectClass=aaa)(objectClass=bbb)(objectClass=ccc)) search_filter = '(|%s)' % possible_classes custom_filter = self.get_group_filter() if custom_filter not in [None, '']: search_filter = self._combine_filters(custom_filter, search_filter) results = self.search(base_dn=self.context.groups_base, filter=search_filter) mapped_results = [] for result in results: mapped_results.append(self.apply_schema_map(result)) return mapped_results
def getGroups(self, dn='*', attr=None): """ return group records i know about """ group_list = [] if self.groups_base: no_show = ('Anonymous', 'Authenticated', 'Shared') if dn == '*': group_classes = GROUP_MEMBER_MAP.keys() filt_list = [ filter_format('(%s=%s)', ('objectClass', g)) for g in group_classes ] group_filter = '(|%s)' % ''.join(filt_list) else: member_attrs = list(Set(GROUP_MEMBER_MAP.values())) filt_list = [ filter_format('(%s=%s)', (m_attr, dn)) for m_attr in member_attrs ] group_filter = '(|%s)' % ''.join(filt_list) luf = self.getLUF() res = luf._delegate.search(self.groups_base, self.groups_scope, group_filter, attrs=['dn', 'cn']) if res['size'] > 0: resultset = res['results'] for i in range(res['size']): dn = resultset[i].get('dn') try: cn = resultset[i].get('cn')[0] except KeyError: # NDS oddity cn = luf._delegate.explode_dn(dn, 1)[0] if attr is None: group_list.append((cn, dn)) elif attr == 'cn': group_list.append(cn) elif attr == 'dn': group_list.append(dn) return group_list
def getGroups(self, dn='*', attr=None): """ return group records i know about """ group_list = [] if self.groups_base: no_show = ('Anonymous', 'Authenticated', 'Shared') if dn == '*': group_classes = GROUP_MEMBER_MAP.keys() filt_list = [ filter_format('(%s=%s)', ('objectClass', g)) for g in group_classes ] group_filter = '(|%s)' % ''.join(filt_list) else: member_attrs = list(Set(GROUP_MEMBER_MAP.values())) filt_list = [ filter_format('(%s=%s)', (m_attr, dn)) for m_attr in member_attrs ] group_filter = '(|%s)' % ''.join(filt_list) luf = self.getLUF() res = luf._delegate.search( self.groups_base , self.groups_scope , group_filter , attrs=['dn', 'cn'] ) if res['size'] > 0: resultset = res['results'] for i in range(res['size']): dn = resultset[i].get('dn') try: cn = resultset[i].get('cn')[0] except KeyError: # NDS oddity cn = luf._delegate.explode_dn(dn, 1)[0] if attr is None: group_list.append((cn, dn)) elif attr == 'cn': group_list.append(cn) elif attr == 'dn': group_list.append(dn) return group_list
def safe_call(self): acl = getToolByName(self.context, 'acl_users') ldap = acl['ldap-plugin']['acl_users'] resp = ldap._delegate.search( base=ldap.groups_base, scope=2, filter=filter_format('(cn=%s)', [self.group]), attrs=['uniqueMember']) results = resp.get('results', []) if not results: logger.warning("Couldn't find email for %s", self.context.Title()) return "" member_dns = results[0]['uniqueMember'] if member_dns[0] == '' and len(member_dns) == 1: logger.warning("Couldn't find emails for %s", self.group) return "" uids = [dn.split(',')[0].split('=')[1] for dn in member_dns] tpl = "".join("(uid=%s)" % uid for uid in uids) filter = "(|%s)" % tpl resp = ldap._delegate.search( base=ldap.users_base, scope=1, filter=filter, attrs=['uid', 'mail']) results = resp.get('results', []) mt = getToolByName(self.context, 'portal_membership') uids = [m['uid'][0] for m in results] object_sectors = self.context.sectors if len(uids) == 0: logger.warning("Couldn't find email for the group %s", self.group) return "" for uid in uids: member = mt.getMemberById(uid) user_sectors = member.getProperty('thematic_sectors', '') if user_sectors == '': continue user_sectors = user_sectors.split(',') user_has_sector = False for user_sector in user_sectors: if user_sector in object_sectors: user_has_sector = True break if user_has_sector is False: uids.remove(uid) if len(uids) == 0: logger.warning("There are no users with any of the following " + "sectors: %s", ", ".join(object_sectors)) return "" mails = [m['mail'][0] for m in results if m['uid'][0] in uids] return ", ".join(mails) or ""
def group_member_ids(self, group): if not hasattr(self, '_v_ldap_groups_cache'): cache = self._v_ldap_groups_cache = {} cache = self._v_ldap_groups_cache ldap_folder = self.getUserFolder() root_dn = self.getRootDN(ldap_folder) scope = self.getGroupScope(ldap_folder) if not cache.get(group, {}): result = self.delegate.search(root_dn, scope, filter_format('cn=%s', (group,)), ['uniqueMember']) cache[group] = result else: result = cache[group] if result['size'] > 0: group_users = [x.split(',')[0].split('=')[1] for x in result['results'][result['size']-1]['uniqueMember']] return group_users else: return []
def getUsersByRole(self, acl_folder, groups=None): """ Return all those users that are in a group """ all_dns = {} res = [] res_append = res.append member_attrs = GROUP_MEMBER_MAP.values() if groups is None: return () for group_id, group_dn in groups: dn = self.getRootDN(acl_folder) scope = self.getGroupScope(acl_folder) result = self.delegate.search(dn, scope, filter_format('(cn=%s)', (group_id,)), ['uniqueMember', 'member']) for val in result['results']: for dn in val['uniqueMember']: info = self.delegate.search(base=dn, scope=ldap.SCOPE_BASE) [ res_append(i) for i in info['results'] ] return res
def group_member_ids(self, group): ldap_folder = self.getUserFolder() root_dn = self.getRootDN(ldap_folder) scope = self.getGroupScope(ldap_folder) delegate = self.get_ldap_delegate() result = delegate.search(root_dn, scope, filter_format("cn=%s", (group,)), ["uniqueMember"]) if result["size"] > 0: group_user_members = result["results"][result["size"] - 1]["uniqueMember"] group_users = [] for member in group_user_members: if member == "": continue # we found a placeholder member for empty groups try: uid = member.split(",")[0].split("=")[1] except IndexError, e: log.exception("Can't parse the uid %r, skipping", member) else: group_users.append(uid) return group_users
def getUsersByRole(self, acl_folder, groups=None): """ Return all those users that are in a group """ #all_dns = {} res = [] res_append = res.append #member_attrs = GROUP_MEMBER_MAP.values() if groups is None: return () for group_id, group_dn in groups: dn = self.getRootDN(acl_folder) scope = self.getGroupScope(acl_folder) delegate = self.get_ldap_delegate() result = delegate.search(dn, scope, filter_format('(cn=%s)', (group_id,)), ['uniqueMember', 'member']) for val in result['results']: for dn in val['uniqueMember']: p_username = self._user_id_from_dn(dn) info = self.get_source_user_info(p_username) res_append(info) return res
def get_groups(self, use_lookup_base=False): """Return all LDAP groups below the adapted LDAPUserFolder's `groups_base` (or the `lookup_groups_base` if `use_lookup_base` is True). If defined, the `group_filter` property on the adapted LDAPUserFolder is used to further filter the results. """ # Build a filter expression that matches objectClasses for all # possible group objectClasseses encountered in the wild possible_classes = '' for oc in GROUP_MEMBER_MAP.keys(): # concatenate (objectClass=foo) pairs possible_classes += filter_format('(%s=%s)', ('objectClass', oc)) # Build the final OR expression: # (|(objectClass=aaa)(objectClass=bbb)(objectClass=ccc)) search_filter = '(|%s)' % possible_classes custom_filter = self.get_group_filter() search_filter = self._combine_filters(custom_filter, search_filter) if use_lookup_base: base_dn = getattr( self.context, 'lookup_groups_base', self.context.groups_base) else: base_dn = self.context.groups_base results = self.search(base_dn=base_dn, filter=search_filter) mapped_results = [] for result in results: dn, entry = result if dn is None: # This is likely a referral to be hunted down by # client-chasing. We don't support those. logger.info('Skipping referral: %r' % (result, )) continue mapped_results.append(self.apply_schema_map(result)) return mapped_results
def group_member_ids(self, group): ldap_folder = self.getUserFolder() root_dn = self.getRootDN(ldap_folder) scope = self.getGroupScope(ldap_folder) delegate = self.get_ldap_delegate() result = delegate.search(root_dn, scope, filter_format('cn=%s', (group,)), ['uniqueMember']) if result['size'] > 0: group_user_members = result['results'][result['size']-1]['uniqueMember'] group_users = [] for member in group_user_members: if member == '': continue # we found a placeholder member for empty groups try: uid = member.split(',')[0].split('=')[1] except IndexError: log.exception("Can't parse the uid %r, skipping", member) else: group_users.append(uid) return group_users else: return []
def getUsersByRole(self, acl_folder, groups=None): """ Return all those users that are in a group """ res = [] res_append = res.append if groups is None: return () for group_id, group_dn in groups: dn = self.getRootDN(acl_folder) scope = self.getGroupScope(acl_folder) delegate = self.get_ldap_delegate() result = delegate.search(dn, scope, filter_format('(cn=%s)', (group_id, )), ['uniqueMember', 'member']) for val in result['results']: for dn in val['uniqueMember']: p_username = self._user_id_from_dn(dn) info = self.get_source_user_info(p_username) res_append(info) return res
def safe_call(self): acl = getToolByName(self.context, 'acl_users') ldap = acl['ldap-plugin']['acl_users'] resp = ldap._delegate.search( base=ldap.groups_base, scope=2, filter=filter_format('(cn=%s)', [self.group]), attrs=['uniqueMember']) results = resp.get('results', []) if not results: logger.warning("Couldn't find email for %s", self.context.Title()) return "" member_dns = results[0]['uniqueMember'] uids = [dn.split(',')[0].split('=')[1] for dn in member_dns] tpl = "".join("(uid=%s)" % uid for uid in uids) filter = "(|%s)" % tpl resp = ldap._delegate.search( base=ldap.users_base, scope=1, filter=filter, attrs=['mail']) results = resp.get('results', []) mails = [m['mail'][0] for m in results] return ", ".join(mails) or ""
def group_member_ids(self, group): ldap_folder = self.getUserFolder() root_dn = self.getRootDN(ldap_folder) scope = self.getGroupScope(ldap_folder) delegate = self.get_ldap_delegate() result = delegate.search(root_dn, scope, filter_format('cn=%s', (group, )), ['uniqueMember']) if result['size'] > 0: group_user_members = result['results'][result['size'] - 1]['uniqueMember'] group_users = [] for member in group_user_members: if member == '': continue # we found a placeholder member for empty groups try: uid = member.split(',')[0].split('=')[1] except IndexError, e: log.exception("Can't parse the uid %r, skipping", member) else: group_users.append(uid) return group_users
def getAdditionalRoles(self, user, already_added=()): """ extend the user roles """ my_path = self.absolute_url(1) add_role_dict = {} if user is None: return [] if self.recurse == 1: self_path = self.getPhysicalPath() other_satellites = self.superValues('LDAPUserSatellite') other_satellites.reverse() for sat in other_satellites: if sat.getPhysicalPath() != self_path: add_role_list = sat.getAdditionalRoles(user, already_added) newly_added = {} for add_role in add_role_list: newly_added[add_role] = 1 for add_role in already_added: newly_added[add_role] = 1 already_added = tuple(newly_added.keys()) luf = self.getLUF() user_id = user.getId() user_expiration = user._created + luf.getCacheTimeout('authenticated') if (self._cache('users').has_key(user_id) and self._cache('expiration').get(user_id, 0) >= user_expiration): logger.debug('Used cached user "%s"' % user_id) return self._cache('users').get(user_id) if self.groups_base: # We were given a search base, so search there user_dn = user.getUserDN() member_attrs = list(Set(GROUP_MEMBER_MAP.values())) filt_list = [ filter_format('(%s=%s)', (m_attr, user_dn)) for m_attr in member_attrs ] group_filter = '(|%s)' % ''.join(filt_list) res = luf._delegate.search(self.groups_base, self.groups_scope, group_filter, attrs=['dn', 'cn']) if res['size'] > 0: resultset = res['results'] for i in range(res['size']): dn = resultset[i].get('dn') try: cn = resultset[i].get('cn')[0] except KeyError: # NDS oddity cn = luf._delegate.explode_dn(dn, 1)[0] add_role_dict[cn] = 1 for add_role in already_added: add_role_dict[add_role] = 1 already_added = () if self.groups_map: # We have a group mapping, so map away user_roles = list(user.getRoles()) roles = user_roles[:] roles.extend(add_role_dict.keys()) roles.extend(list(user._getLDAPGroups())) for role in roles: mapped_roles = self.groups_map.get(role, []) for mapped_role in mapped_roles: if mapped_role and mapped_role not in user_roles: add_role_dict[mapped_role] = 1 added_roles = add_role_dict.keys() if added_roles: add_roles = ', '.join(added_roles) logger.debug('Added roles "%s" to user "%s"' % (add_roles, user_id)) self._cacheRoles(user_id, added_roles, user_expiration) return added_roles
def getAdditionalRoles(self, user, already_added=()): """ extend the user roles """ my_path = self.absolute_url(1) add_role_dict = {} if user is None: return [] if self.recurse == 1: self_path = self.getPhysicalPath() other_satellites = self.superValues('LDAPUserSatellite') other_satellites.reverse() for sat in other_satellites: if sat.getPhysicalPath() != self_path: add_role_list = sat.getAdditionalRoles(user, already_added) newly_added = {} for add_role in add_role_list: newly_added[add_role] = 1 for add_role in already_added: newly_added[add_role] = 1 already_added = tuple(newly_added.keys()) luf = self.getLUF() user_id = user.getId() user_expiration = user._created + luf.getCacheTimeout('authenticated') if ( self._cache('users').has_key(user_id) and self._cache('expiration').get(user_id, 0) >= user_expiration ): logger.debug('Used cached user "%s"' % user_id) return self._cache('users').get(user_id) if self.groups_base: # We were given a search base, so search there user_dn = user.getUserDN() member_attrs = list(Set(GROUP_MEMBER_MAP.values())) filt_list = [ filter_format('(%s=%s)', (m_attr, user_dn)) for m_attr in member_attrs ] group_filter = '(|%s)' % ''.join(filt_list) res = luf._delegate.search( self.groups_base , self.groups_scope , group_filter , attrs = ['dn', 'cn'] ) if res['size'] > 0: resultset = res['results'] for i in range(res['size']): dn = resultset[i].get('dn') try: cn = resultset[i].get('cn')[0] except KeyError: # NDS oddity cn = luf._delegate.explode_dn(dn, 1)[0] add_role_dict[cn] = 1 for add_role in already_added: add_role_dict[add_role] = 1 already_added = () if self.groups_map: # We have a group mapping, so map away user_roles = list(user.getRoles()) roles = user_roles[:] roles.extend(add_role_dict.keys()) roles.extend(list(user._getLDAPGroups())) for role in roles: mapped_roles = self.groups_map.get(role, []) for mapped_role in mapped_roles: if mapped_role and mapped_role not in user_roles: add_role_dict[mapped_role] = 1 added_roles = add_role_dict.keys() if added_roles: add_roles = ', '.join(added_roles) logger.debug('Added roles "%s" to user "%s"' % (add_roles, user_id)) self._cacheRoles(user_id, added_roles, user_expiration) return added_roles
def searchUsers(self, attrs=(), exact_match=False, **kw): """ Look up matching user records based on one or mmore attributes This method takes any passed-in search parameters and values as keyword arguments and will sort out invalid keys automatically. It accepts all three forms an attribute can be known as, its real ldap name, the name an attribute is mapped to explicitly, and the friendly name it is known by. """ users = [] users_base = self.users_base search_scope = self.users_scope filt_list = [] if not attrs: attrs = self.getSchemaConfig().keys() schema_translator = {} for ldap_key, info in self.getSchemaConfig().items(): public_name = info.get('public_name', None) friendly_name = info.get('friendly_name', None) if friendly_name: schema_translator[friendly_name] = ldap_key if public_name: schema_translator[public_name] = ldap_key schema_translator[ldap_key] = ldap_key for (search_param, search_term) in kw.items(): if search_param == 'dn': users_base = search_term search_scope = self._delegate.BASE elif search_param == 'objectGUID': # we can't escape the objectGUID query piece using filter_format # because it replaces backslashes, which we need as a result # of guid2string users_base = self.users_base guid = guid2string(search_term) if exact_match: filt_list.append('(objectGUID=%s)' % guid) else: filt_list.append('(objectGUID=*%s*)' % guid) else: # If the keyword arguments contain unknown items we will # simply ignore them and continue looking. ldap_param = schema_translator.get(search_param, None) if ldap_param is None: return [] if search_term and exact_match: filt_list.append(filter_format('(%s=%s)' , (ldap_param, search_term) )) elif search_term: filt_list.append(filter_format('(%s=*%s*)' , (ldap_param, search_term) )) else: filt_list.append('(%s=*)' % ldap_param) if len(filt_list) == 0 and search_param != 'dn': # We have no useful filter criteria, bail now before bringing the # site down with a search that is overly broad. res = { 'exception' : 'No useful filter criteria given' } res['size'] = 0 search_str = '' else: search_str = self._getUserFilterString(filters=filt_list) res = self._delegate.search( base=users_base , scope=search_scope , filter=search_str , attrs=attrs ) if res['exception']: logger.debug('findUser Exception (%s)' % res['exception']) msg = 'findUser search filter "%s"' % search_str logger.debug(msg) users = [{ 'dn' : res['exception'] , 'cn' : 'n/a' , 'sn' : 'Error' }] elif res['size'] > 0: res_dicts = res['results'] for i in range(res['size']): dn = res_dicts[i].get('dn') rec_dict = {} rec_dict['sn'] = rec_dict['cn'] = '' for key, val in res_dicts[i].items(): rec_dict[key] = val[0] rec_dict['dn'] = dn users.append(rec_dict) return users