Package ldaptor :: Module delta
[hide private]
[frames] | no frames]

Source Code for Module ldaptor.delta

  1  """ 
  2  Changes to the content of one single LDAP entry. 
  3   
  4  (This means these do not belong here: adding or deleting of entries, 
  5  changing of location in tree) 
  6  """ 
  7   
  8  from ldaptor import attributeset 
  9  from ldaptor.protocols import pureldap, pureber 
 10  from ldaptor.protocols.ldap import ldif, distinguishedname 
 11  import codecs 
12 -class Modification(attributeset.LDAPAttributeSet):
13 - def patch(self, entry):
14 raise NotImplementedError
15 16 _LDAP_OP = None 17
18 - def asLDAP(self):
19 if self._LDAP_OP is None: 20 raise NotImplementedError("%s.asLDAP not implemented" 21 % self.__class__.__name__) 22 tmplist = list(self) 23 newlist = [] 24 for x in range(len(tmplist)): 25 if (isinstance(tmplist[x], unicode)): 26 value = tmplist[x].encode('utf-8') 27 newlist.append(value) 28 else: 29 value = tmplist[x] 30 newlist.append(value) 31 32 return str(pureber.BERSequence([ 33 pureber.BEREnumerated(self._LDAP_OP), 34 pureber.BERSequence([ pureldap.LDAPAttributeDescription(self.key), 35 pureber.BERSet(map(pureldap.LDAPString, newlist)), 36 ]), 37 ]))
38
39 - def __eq__(self, other):
40 if not isinstance(other, self.__class__): 41 return False 42 return super(Modification, self).__eq__(other)
43
44 -class Add(Modification):
45 _LDAP_OP = 0 46
47 - def patch(self, entry):
48 if self.key in entry: 49 entry[self.key].update(self) 50 else: 51 entry[self.key] = self
52
53 - def asLDIF(self):
54 r=[] 55 values = list(self) 56 values.sort() 57 r.append(ldif.attributeAsLDIF('add', self.key)) 58 for v in values: 59 r.append(ldif.attributeAsLDIF(self.key, v)) 60 r.append('-\n') 61 return ''.join(r)
62
63 -class Delete(Modification):
64 _LDAP_OP = 1 65
66 - def patch(self, entry):
67 if not self: 68 del entry[self.key] 69 else: 70 for v in self: 71 entry[self.key].remove(v)
72
73 - def asLDIF(self):
74 r=[] 75 values = list(self) 76 values.sort() 77 r.append(ldif.attributeAsLDIF('delete', self.key)) 78 for v in values: 79 r.append(ldif.attributeAsLDIF(self.key, v)) 80 r.append('-\n') 81 return ''.join(r)
82
83 -class Replace(Modification):
84 _LDAP_OP = 2 85
86 - def patch(self, entry):
87 if self: 88 entry[self.key] = self 89 else: 90 try: 91 del entry[self.key] 92 except KeyError: 93 pass
94
95 - def asLDIF(self):
96 r=[] 97 values = list(self) 98 values.sort() 99 r.append(ldif.attributeAsLDIF('replace', self.key)) 100 for v in values: 101 r.append(ldif.attributeAsLDIF(self.key, v)) 102 r.append('-\n') 103 return ''.join(r)
104 105
106 -class Operation(object):
107 - def patch(self, root):
108 """ 109 Find the correct entry in IConnectedLDAPEntry and patch it. 110 111 @param root: IConnectedLDAPEntry that is at the root of the 112 subtree the patch applies to. 113 114 @returns: Deferred with None or failure. 115 """ 116 raise NotImplementedError
117
118 -class ModifyOp(Operation):
119 - def __init__(self, dn, modifications=[]):
120 if not isinstance(dn, distinguishedname.DistinguishedName): 121 dn=distinguishedname.DistinguishedName(stringValue=dn) 122 self.dn = dn 123 self.modifications = modifications[:]
124
125 - def asLDIF(self):
126 r = [] 127 r.append(ldif.attributeAsLDIF('dn', str(self.dn))) 128 r.append(ldif.attributeAsLDIF('changetype', 'modify')) 129 for m in self.modifications: 130 r.append(m.asLDIF()) 131 r.append("\n") 132 return ''.join(r)
133
134 - def asLDAP(self):
135 return pureldap.LDAPModifyRequest( 136 object=str(self.dn), 137 modification=[x.asLDAP() for x in self.modifications])
138
139 - def _getClassFromOp(class_, op):
140 for mod in [Add, Delete, Replace]: 141 if op == mod._LDAP_OP: 142 return mod 143 return None
144 _getClassFromOp = classmethod(_getClassFromOp) 145
146 - def fromLDAP(class_, request):
147 if not isinstance(request, pureldap.LDAPModifyRequest): 148 raise RuntimeError("%s.fromLDAP needs an LDAPModifyRequest" 149 % class_.__name__) 150 dn = request.object 151 result = [] 152 for op, mods in request.modification: 153 op = op.value 154 klass = class_._getClassFromOp(op) 155 if klass is None: 156 raise RuntimeError("Unknown LDAP op number %r in %s.fromLDAP" 157 % (op, class_.__name__)) 158 159 key, vals = mods 160 key = key.value 161 vals = [x.value for x in vals] 162 m = klass(key, vals) 163 result.append(m) 164 return class_(dn, result)
165 fromLDAP = classmethod(fromLDAP) 166
167 - def patch(self, root):
168 d = root.lookup(self.dn) 169 def gotEntry(entry, modifications): 170 for mod in self.modifications: 171 mod.patch(entry) 172 return entry
173 d.addCallback(gotEntry, self.modifications) 174 return d
175
176 - def __repr__(self):
177 return (self.__class__.__name__ 178 + '(' 179 + 'dn=%r' % str(self.dn) 180 + ', ' 181 + 'modifications=%r' % self.modifications 182 + ')')
183
184 - def __eq__(self, other):
185 if not isinstance(other, self.__class__): 186 return 0 187 if self.dn != other.dn: 188 return 0 189 if self.modifications != other.modifications: 190 return 0 191 return 1
192
193 - def __ne__(self, other):
194 return not self==other
195
196 -class AddOp(Operation):
197 - def __init__(self, entry):
198 self.entry = entry
199
200 - def asLDIF(self):
201 l = str(self.entry).splitlines() 202 assert l[0].startswith('dn:') 203 l[1:1] = [ldif.attributeAsLDIF('changetype', 'add').rstrip('\n')] 204 return ''.join([x+'\n' for x in l])
205
206 - def patch(self, root):
207 d = root.lookup(self.entry.dn.up()) 208 def gotParent(parent, entry): 209 parent.addChild(entry.dn.split()[0], entry)
210 d.addCallback(gotParent, self.entry) 211 return d
212
213 - def __repr__(self):
214 return (self.__class__.__name__ 215 + '(' 216 + '%r' % self.entry 217 + ')')
218
219 - def __eq__(self, other):
220 if not isinstance(other, self.__class__): 221 return False 222 if self.entry != other.entry: 223 return False 224 return True
225
226 - def __ne__(self, other):
227 return not self==other
228
229 -class DeleteOp(Operation):
230 - def __init__(self, dn):
231 self.dn = dn
232
233 - def asLDIF(self):
234 r = [] 235 r.append(ldif.attributeAsLDIF('dn', str(self.dn))) 236 r.append(ldif.attributeAsLDIF('changetype', 'delete')) 237 r.append("\n") 238 return ''.join(r)
239
240 - def patch(self, root):
241 d = root.lookup(self.dn) 242 def gotEntry(entry): 243 return entry.delete()
244 d.addCallback(gotEntry) 245 return d
246
247 - def __repr__(self):
248 return (self.__class__.__name__ 249 + '(' 250 + '%r' % self.dn 251 + ')')
252
253 - def __eq__(self, other):
254 if not isinstance(other, self.__class__): 255 return False 256 if self.dn != other.dn: 257 return False 258 return True
259
260 - def __ne__(self, other):
261 return not self==other
262