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