# Copyright 2012-2014 Brian May## This file is part of python-tldap.## python-tldap is free software: you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation, either version 3 of the License, or# (at your option) any later version.## python-tldap is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with python-tldap If not, see <http://www.gnu.org/licenses/>."""This module contains a ``modifyModlist`` function adopted from:py:mod:`ldap:ldap.modlist`."""fromtypingimportDict,Iterator,List,Optional,Tupleimportldap3importldap3.utils.convimporttldap.dictdef_list_dict(line:Iterator[str],case_insensitive:bool=False):""" return a dictionary with all items of l being the keys of the dictionary If argument case_insensitive is non-zero ldap.cidict.cidict will be used for case-insensitive string keys """ifcase_insensitive:raiseNotImplementedError()d=tldap.dict.CaseInsensitiveDict()else:d={}foriinline:d[i]=Nonereturnd
[docs]defaddModlist(entry:dict,ignore_attr_types:Optional[List[str]]=None)->Dict[str,List[bytes]]:"""Build modify list for call of method LDAPObject.add()"""ignore_attr_types=_list_dict(map(str.lower,(ignore_attr_typesor[])))modlist:Dict[str,List[bytes]]={}forattrtypeinentry.keys():ifattrtype.lower()inignore_attr_types:# This attribute type is ignoredcontinueforvalueinentry[attrtype]:assertvalueisnotNoneiflen(entry[attrtype])>0:modlist[attrtype]=escape_list(entry[attrtype])returnmodlist# addModlist()
[docs]defmodifyModlist(old_entry:dict,new_entry:dict,ignore_attr_types:Optional[List[str]]=None,ignore_oldexistent:bool=False)->Dict[str,Tuple[str,List[bytes]]]:""" Build differential modify list for calling LDAPObject.modify()/modify_s() :param old_entry: Dictionary holding the old entry :param new_entry: Dictionary holding what the new entry should be :param ignore_attr_types: List of attribute type names to be ignored completely :param ignore_oldexistent: If true attribute type names which are in old_entry but are not found in new_entry at all are not deleted. This is handy for situations where your application sets attribute value to '' for deleting an attribute. In most cases leave zero. :return: List of tuples suitable for :py:meth:`ldap:ldap.LDAPObject.modify`. This function is the same as :py:func:`ldap:ldap.modlist.modifyModlist` except for the following changes: * MOD_DELETE/MOD_DELETE used in preference to MOD_REPLACE when updating an existing value. """ignore_attr_types=_list_dict(map(str.lower,(ignore_attr_typesor[])))modlist:Dict[str,Tuple[str,List[bytes]]]={}attrtype_lower_map={}forainold_entry.keys():attrtype_lower_map[a.lower()]=aforattrtypeinnew_entry.keys():attrtype_lower=attrtype.lower()ifattrtype_lowerinignore_attr_types:# This attribute type is ignoredcontinue# Filter away null-stringsnew_value=list(filter(lambdax:xisnotNone,new_entry[attrtype]))ifattrtype_lowerinattrtype_lower_map:old_value=old_entry.get(attrtype_lower_map[attrtype_lower],[])old_value=list(filter(lambdax:xisnotNone,old_value))delattrtype_lower_map[attrtype_lower]else:old_value=[]ifnotold_valueandnew_value:# Add a new attribute to entrymodlist[attrtype]=(ldap3.MODIFY_ADD,escape_list(new_value))elifold_valueandnew_value:# Replace existing attributeold_value_dict=_list_dict(old_value)new_value_dict=_list_dict(new_value)delete_values=[]forvinold_value:ifvnotinnew_value_dict:delete_values.append(v)add_values=[]forvinnew_value:ifvnotinold_value_dict:add_values.append(v)iflen(delete_values)>0orlen(add_values)>0:modlist[attrtype]=(ldap3.MODIFY_REPLACE,escape_list(new_value))elifold_valueandnotnew_value:# Completely delete an existing attributemodlist[attrtype]=(ldap3.MODIFY_DELETE,[])ifnotignore_oldexistent:# Remove all attributes of old_entry which are not present# in new_entry at allforainattrtype_lower_map.keys():ifainignore_attr_types:# This attribute type is ignoredcontinueattrtype=attrtype_lower_map[a]modlist[attrtype]=(ldap3.MODIFY_DELETE,[])returnmodlist# modifyModlist()