diff options
author | Jan Cholasta <jcholast@redhat.com> | 2013-12-10 11:45:10 +0100 |
---|---|---|
committer | Petr Viktorin <pviktori@redhat.com> | 2014-01-10 14:41:39 +0100 |
commit | 61887ac3929ac3bd5135867f31ad414a547327c9 (patch) | |
tree | 564f5857eafdf8525705af0a5028460a1936fdf1 /ipapython | |
parent | 9d4bcb63dead51e927ac2a4b554ee0d98aed052f (diff) | |
download | freeipa-61887ac3929ac3bd5135867f31ad414a547327c9.tar.gz freeipa-61887ac3929ac3bd5135867f31ad414a547327c9.tar.xz freeipa-61887ac3929ac3bd5135867f31ad414a547327c9.zip |
Add LDAPEntry method generate_modlist.
Use LDAPEntry.generate_modlist instead of LDAPClient._generate_modlist and
remove LDAPClient._generate_modlist.
https://fedorahosted.org/freeipa/ticket/3488
Diffstat (limited to 'ipapython')
-rw-r--r-- | ipapython/ipaldap.py | 85 |
1 files changed, 39 insertions, 46 deletions
diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py index 6fcd1228b..c553feac4 100644 --- a/ipapython/ipaldap.py +++ b/ipapython/ipaldap.py @@ -992,6 +992,44 @@ class LDAPEntry(collections.MutableMapping): return NotImplemented return other is not self + def generate_modlist(self): + modlist = [] + + names = set(self.iterkeys()) + names.update(self._orig.iterkeys()) + for name in names: + new = self.raw.get(name) + old = self._orig.raw.get(name) + if old and not new: + modlist.append((ldap.MOD_DELETE, name, None)) + continue + if not old: + modlist.append((ldap.MOD_REPLACE, name, new)) + continue + + # We used to convert to sets and use difference to calculate + # the changes but this did not preserve order which is important + # particularly for schema + adds = [value for value in new if value not in old] + dels = [value for value in old if value not in new] + if adds and self.conn.get_single_value(name): + if len(adds) > 1: + raise errors.OnlyOneValueAllowed(attr=name) + modlist.append((ldap.MOD_REPLACE, name, adds)) + else: + if adds: + modlist.append((ldap.MOD_ADD, name, adds)) + if dels: + modlist.append((ldap.MOD_DELETE, name, dels)) + + # Usually the modlist order does not matter. + # However, for schema updates, we want 'attributetypes' before + # 'objectclasses'. + # A simple sort will ensure this. + modlist.sort(key=lambda m: m[1].lower() != 'attributetypes') + + return modlist + # FIXME: Remove when python-ldap tuple compatibility is dropped def __iter__(self): yield self._dn @@ -1587,51 +1625,6 @@ class LDAPClient(object): self.conn.rename_s(dn, new_rdn, delold=int(del_old)) time.sleep(.3) # Give memberOf plugin a chance to work - def _generate_modlist(self, dn, entry_attrs): - assert isinstance(dn, DN) - - # generate modlist - # for multi value attributes: no MOD_REPLACE to handle simultaneous - # updates better - # for single value attribute: always MOD_REPLACE - modlist = [] - for (k, v) in entry_attrs.raw.iteritems(): - if not v and k in entry_attrs.orig_data: - modlist.append((ldap.MOD_DELETE, k, None)) - else: - v = set(v) - old_v = set(entry_attrs.orig_data.raw.get(k, [])) - - adds = list(v.difference(old_v)) - rems = list(old_v.difference(v)) - - is_single_value = self.get_single_value(k) - - value_count = len(old_v) + len(adds) - len(rems) - if is_single_value and value_count > 1: - raise errors.OnlyOneValueAllowed(attr=k) - - force_replace = False - if len(v) > 0 and len(v.intersection(old_v)) == 0: - force_replace = True - - if adds: - if force_replace: - modlist.append((ldap.MOD_REPLACE, k, adds)) - else: - modlist.append((ldap.MOD_ADD, k, adds)) - if rems: - if not force_replace: - modlist.append((ldap.MOD_DELETE, k, rems)) - - # Usually the modlist order does not matter. - # However, for schema updates, we want 'attributetypes' before - # 'objectclasses'. - # A simple sort will ensure this. - modlist.sort(key=lambda m: m[1].lower()) - - return modlist - def update_entry(self, entry, entry_attrs=None): """Update entry's attributes. @@ -1645,7 +1638,7 @@ class LDAPClient(object): entry.update(entry_attrs) # generate modlist - modlist = self._generate_modlist(entry.dn, entry) + modlist = entry.generate_modlist() if not modlist: raise errors.EmptyModlist() |