Aggregate IPASimpleLDAPObject in LDAPEntry.

This commit is contained in:
Jan Cholasta
2013-01-31 11:56:47 +01:00
committed by Martin Kosek
parent 8f46ca5dd2
commit f17aa00ff0
3 changed files with 57 additions and 14 deletions

View File

@@ -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:

View File

@@ -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):

View File

@@ -156,7 +156,10 @@ class test_ldap(object):
dn1 = DN(('cn', cn1[0]))
dn2 = DN(('cn', cn2[0]))
e = LDAPEntry(dn1, cn=cn1)
self.conn = ldap2(shared_instance=False, ldap_uri=self.ldapuri)
self.conn.connect()
e = LDAPEntry(self.conn.conn, dn1, cn=cn1)
assert e.dn is dn1
assert u'cn' in e
assert u'cn' in e.keys()