Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion 7 Doc/reference/ldap-modlist.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The :mod:`ldap.modlist` module defines the following functions:
in the result at all.


.. function:: modifyModlist( old_entry, new_entry [, ignore_attr_types=[] [, ignore_oldexistent=0 [, case_ignore_attr_types=None]]]) -> list
.. function:: modifyModlist( old_entry, new_entry [, ignore_attr_types=[] [, ignore_oldexistent=0 [, case_ignore_attr_types=None, strict_order_attr_types=None]]]) -> list

This function builds a list suitable for passing it directly as argument
*modlist* to method :py:meth:`ldap.ldapobject.LDAPObject.modify` or
Expand Down Expand Up @@ -49,6 +49,11 @@ The :mod:`ldap.modlist` module defines the following functions:
situations where a LDAP server normalizes values and one wants to avoid
unnecessary changes (e.g. case of attribute type names in DNs).

*strict_order_attr_types* is a list of attribute type names for which
value ordering should be considered - differences in the order of values
without a difference in the value contents will be treated as a change
for these attribute types instead of being ignored.

.. note::
Replacing attribute values is always done with a
:py:const:`ldap.MOD_DELETE`/:py:const:`ldap.MOD_ADD` pair instead of
Expand Down
22 changes: 17 additions & 5 deletions 22 Lib/ldap/modlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def addModlist(entry,ignore_attr_types=None):


def modifyModlist(
old_entry,new_entry,ignore_attr_types=None,ignore_oldexistent=0,case_ignore_attr_types=None
old_entry,new_entry,ignore_attr_types=None,ignore_oldexistent=0,case_ignore_attr_types=None, strict_order_attr_types=None,
):
"""
Build differential modify list for calling LDAPObject.modify()/modify_s()
Expand All @@ -45,9 +45,13 @@ def modifyModlist(
case_ignore_attr_types
List of attribute type names for which comparison will be made
case-insensitive
strict_order_attr_types
List of attribute type names for which comparison will be made
with strict ordering (by default, value ordering changes will be ignored)
"""
ignore_attr_types = {v.lower() for v in ignore_attr_types or []}
case_ignore_attr_types = {v.lower() for v in case_ignore_attr_types or []}
strict_order_attr_types = {v.lower() for v in strict_order_attr_types or []}
modlist = []
attrtype_lower_map = {}
for a in old_entry:
Expand All @@ -73,11 +77,19 @@ def modifyModlist(
replace_attr_value = len(old_value)!=len(new_value)
if not replace_attr_value:
if attrtype_lower in case_ignore_attr_types:
old_value_set = {v.lower() for v in old_value}
new_value_set = {v.lower() for v in new_value}
if attrtype_lower in strict_order_attr_types:
old_value_set = [v.lower() for v in old_value]
new_value_set = [v.lower() for v in new_value]
else:
old_value_set = {v.lower() for v in old_value}
new_value_set = {v.lower() for v in new_value}
else:
old_value_set = set(old_value)
new_value_set = set(new_value)
if attrtype_lower in strict_order_attr_types:
old_value_set = [old_value]
new_value_set = [new_value]
else:
old_value_set = set(old_value)
new_value_set = set(new_value)
replace_attr_value = new_value_set != old_value_set
if replace_attr_value:
modlist.append((ldap.MOD_DELETE,attrtype,None))
Expand Down
88 changes: 86 additions & 2 deletions 88 Tests/t_ldap_modlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def test_addModlist(self):
'mail':[b'michael@stroeder.com'],
},
[],
[],
[
(ldap.MOD_DELETE,'objectClass',None),
(ldap.MOD_ADD,'objectClass',[b'person',b'inetOrgPerson']),
Expand All @@ -76,6 +77,84 @@ def test_addModlist(self):
]
),

(
{
'objectClass':[b'person',b'pilotPerson'],
'cn':[b'Max Mustermann'],
'sn':[b'Mustermann'],
'mail':[b'max@example.com'],
},
{
'objectClass':[b'person',b'pilotPerson'],
'cn':[b'Max Mustermann'],
'sn':[b'Mustermann'],
'mail':[b'max@example.com'],
},
[],
['mail'], # strict_order_attr_types
[]
),

(
{
'objectClass':[b'person',b'pilotPerson'],
'cn':[b'Max Mustermann'],
'sn':[b'Mustermann'],
'mail':[b'max@example.com'],
},
{
'objectClass':[b'person',b'pilotPerson'],
'cn':[b'Max Mustermann'],
'sn':[b'Mustermann'],
'mail':[b'max@example.com', b'max@example.net'],
},
[],
['mail'], # strict_order_attr_types
[
(ldap.MOD_DELETE,'mail',None),
(ldap.MOD_ADD,'mail',[b'max@example.com', b'max@example.net']),
]
),

(
{
'objectClass':[b'person',b'pilotPerson'],
'cn':[b'Max Mustermann'],
'sn':[b'Mustermann'],
'mail':[b'max@example.com', b'max@example.net'],
},
{
'objectClass':[b'person',b'pilotPerson'],
'cn':[b'Max Mustermann'],
'sn':[b'Mustermann'],
'mail':[b'max@example.net', b'max@example.com'],
},
[],
['mail'], # strict_order_attr_types
[
(ldap.MOD_DELETE,'mail',None),
(ldap.MOD_ADD,'mail',[b'max@example.net', b'max@example.com']),
]
),

(
{
'objectClass':[b'person',b'pilotPerson'],
'cn':[b'Max Mustermann'],
'sn':[b'Mustermann'],
'mail':[b'max@example.com', b'max@example.net'],
},
{
'objectClass':[b'person',b'pilotPerson'],
'cn':[b'Max Mustermann'],
'sn':[b'Mustermann'],
'mail':[b'max@example.net', b'max@example.com'],
},
[],
[], # strict_order_attr_types
[]
),

(
{
'c':[b'DE'],
Expand All @@ -84,6 +163,7 @@ def test_addModlist(self):
'c':[b'FR'],
},
[],
[],
[
(ldap.MOD_DELETE,'c',None),
(ldap.MOD_ADD,'c',[b'FR']),
Expand All @@ -105,6 +185,7 @@ def test_addModlist(self):
'sn':[None],
},
[],
[],
[
(ldap.MOD_DELETE,'c',None),
(ldap.MOD_DELETE,'objectClass',None),
Expand All @@ -126,6 +207,7 @@ def test_addModlist(self):
'enum':[b'a',b'b',b'c'],
},
['objectClass'],
[],
[
(ldap.MOD_DELETE,'sn',None),
(ldap.MOD_DELETE,'enum',None),
Expand All @@ -136,11 +218,13 @@ def test_addModlist(self):
]

def test_modifyModlist(self):
for old_entry, new_entry, case_ignore_attr_types, test_modlist in self.modifyModlist_tests:
for old_entry, new_entry, case_ignore_attr_types, strict_order_attr_types, test_modlist in self.modifyModlist_tests:
test_modlist.sort()
result_modlist = modifyModlist(
old_entry, new_entry,
case_ignore_attr_types=case_ignore_attr_types)
case_ignore_attr_types=case_ignore_attr_types,
strict_order_attr_types=strict_order_attr_types,
)
result_modlist.sort()

self.assertEqual(
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.