1 from twisted.internet import defer
2 from ldaptor import delta, ldapfilter
3 from ldaptor.protocols import pureldap
4 from ldaptor.protocols.ldap import ldapsyntax, ldaperrors
5
11
17 def rdnToChild(rdn, l):
18 r = [x for x in l if x.dn.split()[0] == rdn]
19 assert len(r) == 1
20 return r[0]
21
22 my = set([x.dn.split()[0] for x in myChildren])
23 his = set([x.dn.split()[0] for x in otherChildren])
24
25
26 commonRDN = list(my & his)
27 commonRDN.sort()
28 d = self._diffTree_commonChildren([
29 (rdnToChild(rdn, myChildren), rdnToChild(rdn, otherChildren))
30 for rdn in commonRDN
31 ], result)
32
33
34 addedRDN = list(his - my)
35 addedRDN.sort()
36 d2 = self._diffTree_addedChildren([
37 rdnToChild(rdn, otherChildren)
38 for rdn in addedRDN
39 ], result)
40 d.addCallback(lambda _: d2)
41
42
43 deletedRDN = list(my - his)
44 deletedRDN.sort()
45 d3 = self._diffTree_deletedChildren([
46 rdnToChild(rdn, myChildren)
47 for rdn in deletedRDN
48 ], result)
49 d.addCallback(lambda _: d3)
50
51 return d
52
61
63 if not children:
64 return result
65 first, rest = children[0], children[1:]
66
67 d = first.subtree()
68 def _gotSubtree(l, result):
69 for c in l:
70 o = delta.AddOp(c)
71 result.append(o)
72 return result
73 d.addCallback(_gotSubtree, result)
74
75 d.addCallback(lambda _: self._diffTree_addedChildren(rest, result))
76 return d
77
90 d.addCallback(_gotSubtree, result)
91
92 d.addCallback(lambda _: self._diffTree_deletedChildren(rest, result))
93 return d
94
96 assert self.dn == other.dn, \
97 ("diffTree arguments must refer to same LDAP tree:"
98 "%r != %r" % (str(self.dn), str(other.dn))
99 )
100 if result is None:
101 result = []
102
103
104 rootDiff = self.diff(other)
105 if rootDiff is not None:
106 result.append(rootDiff)
107
108 d = self.children()
109 d.addCallback(self._diffTree_gotMyChildren, other, result)
110
111 return d
112
115 if callback is None:
116 result = []
117 d = self.subtree(callback=result.append)
118 d.addCallback(lambda _: result)
119 return d
120 else:
121 callback(self)
122 d = self.children()
123 def _processOneChild(_, children, callback):
124 if not children:
125 return None
126
127 c = children.pop()
128 d = c.subtree(callback)
129 d.addCallback(_processOneChild, children, callback)
130 def _gotChildren(children, callback):
131 _processOneChild(None, children, callback)
132 d.addCallback(_gotChildren, callback)
133 return d
134
136 - def match(self, filter):
137 if isinstance(filter, pureldap.LDAPFilter_present):
138 return filter.value in self
139 elif isinstance(filter, pureldap.LDAPFilter_equalityMatch):
140
141 if (filter.assertionValue.value.lower() in
142 [val.lower()
143 for val in self.get(filter.attributeDesc.value, [])]):
144 return True
145 return False
146 elif isinstance(filter, pureldap.LDAPFilter_substrings):
147 if filter.type not in self:
148 return False
149 possibleMatches = self[filter.type]
150 substrings = filter.substrings[:]
151
152 if (substrings
153 and isinstance(filter.substrings[0],
154 pureldap.LDAPFilter_substrings_initial)):
155 possibleMatches = [
156 x[len(filter.substrings[0].value):]
157 for x in possibleMatches
158 if x.lower().startswith(filter.substrings[0].value.lower())
159 ]
160 del substrings[0]
161
162 if (substrings
163 and isinstance(filter.substrings[-1],
164 pureldap.LDAPFilter_substrings_final)):
165 possibleMatches = [
166 x[:-len(filter.substrings[0].value)]
167 for x in possibleMatches
168 if x.lower().endswith(filter.substrings[-1].value.lower())
169 ]
170 del substrings[-1]
171
172 while possibleMatches and substrings:
173 assert isinstance(substrings[0], pureldap.LDAPFilter_substrings_any)
174 r = []
175 for possible in possibleMatches:
176 i = possible.lower().find(substrings[0].value.lower())
177 if i >= 0:
178 r.append(possible[i:])
179 possibleMatches = r
180 del substrings[0]
181 if possibleMatches and not substrings:
182 return True
183 return False
184 elif isinstance(filter, pureldap.LDAPFilter_greaterOrEqual):
185 if filter.attributeDesc not in self:
186 return False
187 for value in self[filter.attributeDesc]:
188 if value >= filter.assertionValue:
189 return True
190 return False
191 elif isinstance(filter, pureldap.LDAPFilter_lessOrEqual):
192 if filter.attributeDesc not in self:
193 return False
194 for value in self[filter.attributeDesc]:
195 if value <= filter.assertionValue:
196 return True
197 return False
198 elif isinstance(filter, pureldap.LDAPFilter_and):
199 for filt in filter:
200 if not self.match(filt):
201 return False
202 return True
203 elif isinstance(filter, pureldap.LDAPFilter_or):
204 for filt in filter:
205 if self.match(filt):
206 return True
207 return False
208 elif isinstance(filter, pureldap.LDAPFilter_not):
209 return not self.match(filter.value)
210 else:
211 raise ldapsyntax.MatchNotImplemented, filter
212
214 - def search(self,
215 filterText=None,
216 filterObject=None,
217 attributes=(),
218 scope=None,
219 derefAliases=None,
220 sizeLimit=0,
221 timeLimit=0,
222 typesOnly=0,
223 callback=None):
248 iterator = iterateSelf
249 else:
250 raise ldaperrors.LDAPProtocolError, \
251 'unknown search scope: %r' % scope
252
253 results = []
254 if callback is None:
255 matchCallback = results.append
256 else:
257 matchCallback = callback
258
259
260 def _tryMatch(entry):
261 if entry.match(filterObject):
262 matchCallback(entry)
263
264 d = iterator(callback=_tryMatch)
265
266 if callback is None:
267 return defer.succeed(results)
268 else:
269 return defer.succeed(None)
270