summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2013-01-31 11:56:47 +0100
committerMartin Kosek <mkosek@redhat.com>2013-03-01 16:59:47 +0100
commitf17aa00ff01e3fff35d3b3ac75f001d076827ec8 (patch)
tree50fbf505f1e2a35ff6286e3a466c044e9de6afc0 /ipaserver
parent8f46ca5dd20f2e69595dfb3bf9ab11d6f978dfbd (diff)
downloadfreeipa-f17aa00ff01e3fff35d3b3ac75f001d076827ec8.tar.gz
freeipa-f17aa00ff01e3fff35d3b3ac75f001d076827ec8.tar.xz
freeipa-f17aa00ff01e3fff35d3b3ac75f001d076827ec8.zip
Aggregate IPASimpleLDAPObject in LDAPEntry.
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/ipaldap.py58
-rw-r--r--ipaserver/plugins/ldap2.py8
2 files changed, 53 insertions, 13 deletions
diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index ef0febabe..9cff10169 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -403,7 +403,7 @@ class IPASimpleLDAPObject(object):
original_dn = dn_tuple[0]
original_attrs = dn_tuple[1]
- ipa_entry = LDAPEntry(DN(original_dn))
+ ipa_entry = LDAPEntry(self, DN(original_dn))
for attr, original_values in original_attrs.items():
target_type = self._SYNTAX_MAPPING.get(self.get_syntax(attr), unicode_from_utf8)
@@ -583,11 +583,31 @@ class IPASimpleLDAPObject(object):
# r[0] == r.dn
# r[1] == r.data
class LDAPEntry(dict):
- __slots__ = ('_dn', '_names', '_orig')
+ __slots__ = ('_conn', '_dn', '_names', '_orig')
- def __init__(self, _dn=None, _obj=None, **kwargs):
+ def __init__(self, _conn, _dn=None, _obj=None, **kwargs):
+ """
+ LDAPEntry constructor.
+
+ Takes 1 to 3 positional arguments and an arbitrary number of keyword
+ arguments. The 3 forms of positional arguments are:
+
+ * LDAPEntry(entry) - create a shallow copy of an existing LDAPEntry.
+ * LDAPEntry(dn, entry) - create a shallow copy of an existing
+ LDAPEntry with a different DN.
+ * LDAPEntry(conn, dn, mapping) - create a new LDAPEntry using the
+ specified IPASimpleLDAPObject and DN and optionally initialize
+ attributes from the specified mapping object.
+
+ Keyword arguments can be used to override values of specific attributes.
+ """
super(LDAPEntry, self).__init__()
+ if isinstance(_conn, LDAPEntry):
+ assert _dn is None
+ _dn = _conn
+ _conn = _conn._conn
+
if isinstance(_dn, LDAPEntry):
assert _obj is None
_obj = _dn
@@ -598,19 +618,22 @@ class LDAPEntry(dict):
else:
if _obj is None:
_obj = {}
- orig = None
+ orig = self
+ assert isinstance(_conn, IPASimpleLDAPObject)
assert isinstance(_dn, DN)
+ self._conn = _conn
self._dn = _dn
self._orig = orig
self._names = CIDict()
- if orig is None:
- self.commit()
-
self.update(_obj, **kwargs)
+ @property
+ def conn(self):
+ return self._conn
+
# properties for Entry and Entity compatibility
@property
def dn(self):
@@ -638,9 +661,26 @@ class LDAPEntry(dict):
def copy(self):
return LDAPEntry(self)
+ def clone(self):
+ result = LDAPEntry(self._conn, self._dn)
+
+ for name in self.iterkeys():
+ super(LDAPEntry, result).__setitem__(
+ name, deepcopy(super(LDAPEntry, self).__getitem__(name)))
+
+ result._names = deepcopy(self._names)
+ if self._orig is not self:
+ result._orig = self._orig.clone()
+
+ return result
+
def commit(self):
+ """
+ Make the current state of the entry a new reference point for change
+ tracking.
+ """
self._orig = self
- self._orig = deepcopy(self)
+ self._orig = self.clone()
def _attr_name(self, name):
if not isinstance(name, basestring):
@@ -971,7 +1011,7 @@ class LDAPClient(object):
return DN((primary_key, entry_attrs[primary_key]), parent_dn)
def make_entry(self, _dn=None, _obj=None, **kwargs):
- return LDAPEntry(_dn, _obj, **kwargs)
+ return LDAPEntry(self.conn, _dn, _obj, **kwargs)
# generating filters for find_entry
# some examples:
diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
index 360e6e2e2..9483611bd 100644
--- a/ipaserver/plugins/ldap2.py
+++ b/ipaserver/plugins/ldap2.py
@@ -27,7 +27,6 @@ Backend plugin for LDAP.
# binding encodes them into the appropriate representation. This applies to
# everything except the CrudBackend methods, where dn is part of the entry dict.
-import copy
import os
import re
import pwd
@@ -207,7 +206,8 @@ class ldap2(LDAPClient, CrudBackend):
try:
config_entry = getattr(context, 'config_entry')
- return copy.deepcopy(config_entry)
+ if config_entry.conn is self.conn:
+ return config_entry.clone()
except AttributeError:
# Not in our context yet
pass
@@ -220,11 +220,11 @@ class ldap2(LDAPClient, CrudBackend):
raise errors.LimitsExceeded()
config_entry = entry[0]
except errors.NotFound:
- config_entry = {}
+ config_entry = self.make_entry(cdn)
for a in self.config_defaults:
if a not in config_entry:
config_entry[a] = self.config_defaults[a]
- context.config_entry = copy.deepcopy(config_entry)
+ context.config_entry = config_entry.clone()
return config_entry
def has_upg(self):