This repository has been archived by the owner on Jan 23, 2021. It is now read-only.
forked from rbarrois/python-ldap
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ldap.modlist.modifyModlist(): New key-word argument
case_ignore_attr_types used to define attribute types for which comparison of old and new values should be case-insensitive
- Loading branch information
stroeder
committed
Jun 6, 2011
1 parent
b898904
commit 88d35a8
Showing
2 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
""" | ||
ldap.modlist - create add/modify modlist's | ||
See http://www.python-ldap.org/ for details. | ||
$Id: modlist.py,v 1.18 2011/06/06 13:07:38 stroeder Exp $ | ||
Python compability note: | ||
This module is known to work with Python 2.0+ but should work | ||
with Python 1.5.2 as well. | ||
""" | ||
|
||
from ldap import __version__ | ||
|
||
import string,ldap,ldap.cidict | ||
|
||
|
||
def list_dict(l,case_insensitive=0): | ||
""" | ||
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 | ||
""" | ||
if case_insensitive: | ||
d = ldap.cidict.cidict() | ||
else: | ||
d = {} | ||
for i in l: | ||
d[i]=None | ||
return d | ||
|
||
|
||
def addModlist(entry,ignore_attr_types=None): | ||
"""Build modify list for call of method LDAPObject.add()""" | ||
ignore_attr_types = list_dict(map(string.lower,(ignore_attr_types or []))) | ||
modlist = [] | ||
for attrtype in entry.keys(): | ||
if ignore_attr_types.has_key(string.lower(attrtype)): | ||
# This attribute type is ignored | ||
continue | ||
# Eliminate empty attr value strings in list | ||
attrvaluelist = filter(lambda x:x!=None,entry[attrtype]) | ||
if attrvaluelist: | ||
modlist.append((attrtype,entry[attrtype])) | ||
return modlist # addModlist() | ||
|
||
|
||
def modifyModlist( | ||
old_entry,new_entry,ignore_attr_types=None,ignore_oldexistent=0,case_ignore_attr_types=None | ||
): | ||
""" | ||
Build differential modify list for calling LDAPObject.modify()/modify_s() | ||
old_entry | ||
Dictionary holding the old entry | ||
new_entry | ||
Dictionary holding what the new entry should be | ||
ignore_attr_types | ||
List of attribute type names to be ignored completely | ||
ignore_oldexistent | ||
If non-zero 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. | ||
case_ignore_attr_types | ||
List of attribute type names for which comparison will be made | ||
case-insensitive | ||
""" | ||
ignore_attr_types = list_dict(map(string.lower,(ignore_attr_types or []))) | ||
case_ignore_attr_types = list_dict(map(string.lower,(case_ignore_attr_types or []))) | ||
modlist = [] | ||
attrtype_lower_map = {} | ||
for a in old_entry.keys(): | ||
attrtype_lower_map[string.lower(a)]=a | ||
for attrtype in new_entry.keys(): | ||
attrtype_lower = string.lower(attrtype) | ||
if ignore_attr_types.has_key(attrtype_lower): | ||
# This attribute type is ignored | ||
continue | ||
# Filter away null-strings | ||
new_value = filter(lambda x:x!=None,new_entry[attrtype]) | ||
if attrtype_lower_map.has_key(attrtype_lower): | ||
old_value = old_entry.get(attrtype_lower_map[attrtype_lower],[]) | ||
old_value = filter(lambda x:x!=None,old_value) | ||
del attrtype_lower_map[attrtype_lower] | ||
else: | ||
old_value = [] | ||
if not old_value and new_value: | ||
# Add a new attribute to entry | ||
modlist.append((ldap.MOD_ADD,attrtype,new_value)) | ||
elif old_value and new_value: | ||
# Replace existing attribute | ||
replace_attr_value = len(old_value)!=len(new_value) | ||
if not replace_attr_value: | ||
case_insensitive = case_ignore_attr_types.has_key(attrtype_lower) | ||
old_value_dict=list_dict(old_value,case_insensitive) | ||
new_value_dict=list_dict(new_value,case_insensitive) | ||
delete_values = [] | ||
for v in old_value: | ||
if not new_value_dict.has_key(v): | ||
replace_attr_value = 1 | ||
break | ||
add_values = [] | ||
if not replace_attr_value: | ||
for v in new_value: | ||
if not old_value_dict.has_key(v): | ||
replace_attr_value = 1 | ||
break | ||
if replace_attr_value: | ||
modlist.append((ldap.MOD_DELETE,attrtype,None)) | ||
modlist.append((ldap.MOD_ADD,attrtype,new_value)) | ||
elif old_value and not new_value: | ||
# Completely delete an existing attribute | ||
modlist.append((ldap.MOD_DELETE,attrtype,None)) | ||
if not ignore_oldexistent: | ||
# Remove all attributes of old_entry which are not present | ||
# in new_entry at all | ||
for a in attrtype_lower_map.keys(): | ||
if ignore_attr_types.has_key(a): | ||
# This attribute type is ignored | ||
continue | ||
attrtype = attrtype_lower_map[a] | ||
modlist.append((ldap.MOD_DELETE,attrtype,None)) | ||
return modlist # modifyModlist() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
""" | ||
Tests for module ldap.modlist | ||
""" | ||
|
||
import ldap | ||
|
||
from ldap.modlist import addModlist,modifyModlist | ||
|
||
print '\nTesting function addModlist():' | ||
addModlist_tests = [ | ||
( | ||
{ | ||
'objectClass':['person','pilotPerson'], | ||
'cn':['Michael Str\303\266der','Michael Stroeder'], | ||
'sn':['Str\303\266der'], | ||
'dummy1':[], | ||
'dummy2':['2'], | ||
'dummy3':[''], | ||
}, | ||
[ | ||
('objectClass',['person','pilotPerson']), | ||
('cn',['Michael Str\303\266der','Michael Stroeder']), | ||
('sn',['Str\303\266der']), | ||
('dummy2',['2']), | ||
('dummy3',['']), | ||
] | ||
), | ||
] | ||
for entry,test_modlist in addModlist_tests: | ||
test_modlist.sort() | ||
result_modlist = addModlist(entry) | ||
result_modlist.sort() | ||
if test_modlist!=result_modlist: | ||
print 'addModlist(%s) returns\n%s\ninstead of\n%s.' % ( | ||
repr(entry),repr(result_modlist),repr(test_modlist) | ||
) | ||
|
||
print '\nTesting function modifyModlist():' | ||
modifyModlist_tests = [ | ||
|
||
( | ||
{ | ||
'objectClass':['person','pilotPerson'], | ||
'cn':['Michael Str\303\266der','Michael Stroeder'], | ||
'sn':['Str\303\266der'], | ||
'enum':['a','b','c'], | ||
'c':['DE'], | ||
}, | ||
{ | ||
'objectClass':['person','inetOrgPerson'], | ||
'cn':['Michael Str\303\266der','Michael Stroeder'], | ||
'sn':[], | ||
'enum':['a','b','d'], | ||
'mail':['[email protected]'], | ||
}, | ||
[], | ||
[ | ||
(ldap.MOD_DELETE,'objectClass',None), | ||
(ldap.MOD_ADD,'objectClass',['person','inetOrgPerson']), | ||
(ldap.MOD_DELETE,'c',None), | ||
(ldap.MOD_DELETE,'sn',None), | ||
(ldap.MOD_ADD,'mail',['[email protected]']), | ||
(ldap.MOD_DELETE,'enum',None), | ||
(ldap.MOD_ADD,'enum',['a','b','d']), | ||
] | ||
), | ||
|
||
( | ||
{ | ||
'c':['DE'], | ||
}, | ||
{ | ||
'c':['FR'], | ||
}, | ||
[], | ||
[ | ||
(ldap.MOD_DELETE,'c',None), | ||
(ldap.MOD_ADD,'c',['FR']), | ||
] | ||
), | ||
|
||
# Now a weird test-case for catching all possibilities | ||
# of removing an attribute with MOD_DELETE,attr_type,None | ||
( | ||
{ | ||
'objectClass':['person'], | ||
'cn':[None], | ||
'sn':[''], | ||
'c':['DE'], | ||
}, | ||
{ | ||
'objectClass':[], | ||
'cn':[], | ||
'sn':[None], | ||
}, | ||
[], | ||
[ | ||
(ldap.MOD_DELETE,'c',None), | ||
(ldap.MOD_DELETE,'objectClass',None), | ||
(ldap.MOD_DELETE,'sn',None), | ||
] | ||
), | ||
|
||
( | ||
{ | ||
'objectClass':['person'], | ||
'cn':['Michael Str\303\266der','Michael Stroeder'], | ||
'sn':['Str\303\266der'], | ||
'enum':['a','b','C'], | ||
}, | ||
{ | ||
'objectClass':['Person'], | ||
'cn':['Michael Str\303\266der','Michael Stroeder'], | ||
'sn':[], | ||
'enum':['a','b','c'], | ||
}, | ||
['objectClass'], | ||
[ | ||
(ldap.MOD_DELETE,'sn',None), | ||
(ldap.MOD_DELETE,'enum',None), | ||
(ldap.MOD_ADD,'enum',['a','b','c']), | ||
] | ||
), | ||
|
||
] | ||
for old_entry,new_entry,case_ignore_attr_types,test_modlist in modifyModlist_tests: | ||
test_modlist.sort() | ||
result_modlist = modifyModlist(old_entry,new_entry,case_ignore_attr_types=case_ignore_attr_types) | ||
result_modlist.sort() | ||
|
||
if test_modlist!=result_modlist: | ||
print 'modifyModlist(%s,%s) returns\n%s\ninstead of\n%s.' % ( | ||
repr(old_entry), | ||
repr(new_entry), | ||
repr(result_modlist), | ||
repr(test_modlist) | ||
) |