def test_escape_and_equal(self): def custom_escaper(s): return ''.join(bin(ord(c)) for c in s) filter1 = pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('foo'), assertionValue=pureldap.LDAPAttributeValue('1'), escaper=custom_escaper ), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('foo'), assertionValue=pureldap.LDAPAttributeValue('2') ), ]) filter2 = pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('foo'), assertionValue=pureldap.LDAPAttributeValue('1') ), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('foo'), assertionValue=pureldap.LDAPAttributeValue('2'), escaper=custom_escaper ), ]) self.assertEqual(filter1, filter2)
def test_nested_equal(self): filter1 = pureldap.LDAPFilter_or([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('foo'), assertionValue=pureldap.LDAPAttributeValue('1')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('bar'), assertionValue=pureldap.LDAPAttributeValue('2')), pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('baz'), assertionValue=pureldap.LDAPAttributeValue('1')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('bob'), assertionValue=pureldap.LDAPAttributeValue('2')), ]), ]) filter2 = pureldap.LDAPFilter_or([ pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('bob'), assertionValue=pureldap.LDAPAttributeValue('2')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('baz'), assertionValue=pureldap.LDAPAttributeValue('1')), ]), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('bar'), assertionValue=pureldap.LDAPAttributeValue('2')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('foo'), assertionValue=pureldap.LDAPAttributeValue('1')), ]) self.assertEqual(filter1, filter2)
def getNets(e, filter): filt = pureldap.LDAPFilter_and( value=( pureldap.LDAPFilter_present("cn"), pureldap.LDAPFilter_present("ipNetworkNumber"), pureldap.LDAPFilter_present("ipNetmaskNumber"), ) ) if filter: filt = pureldap.LDAPFilter_and(value=(filter, filt)) d = e.search( filterObject=filt, attributes=[ "cn", "ipNetworkNumber", "ipNetmaskNumber", "router", "dhcpRange", "winsServer", "domainNameServer", "sharedNetworkName", ], ) d.addCallback(_cbGetNets) return d
def getNets(e, filter): filt = pureldap.LDAPFilter_and(value=( pureldap.LDAPFilter_present("cn"), pureldap.LDAPFilter_present("ipNetworkNumber"), pureldap.LDAPFilter_present("ipNetmaskNumber"), )) if filter: filt = pureldap.LDAPFilter_and(value=(filter, filt)) d = e.search( filterObject=filt, attributes=[ "cn", "ipNetworkNumber", "ipNetmaskNumber", ], ) def _cbGotNets(nets): r = [] for e in nets: net = Net( str(e.dn), str(only(e, "cn")), str(only(e, "ipNetworkNumber")), str(only(e, "ipNetmaskNumber")), ) net.printZone() r.append(net) return r d.addCallback(_cbGotNets) return d
def getGroups(hosts, e, filter): """Add group info to hosts.""" def buildFilter(hosts): for host in hosts: f = pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription("member"), assertionValue=pureber.BEROctetString(str(host.dn)), ) yield f filt = pureldap.LDAPFilter_and( value=( # the only reason we do groups is for the bootFile, # so require one to be present pureldap.LDAPFilter_present("bootFile"), pureldap.LDAPFilter_or(value=list(buildFilter(hosts))), ) ) if filter: filt = pureldap.LDAPFilter_and(value=(filter, filt)) d = e.search(filterObject=filt, attributes=["member", "bootFile"]) d.addCallback(_cbGetGroups, hosts) return d
def user_filter_object(self, username_matches=None): """ Return a filterObject for searching for a dict of username attributes. If username_match is not None, add a filter requiring that at least one of the username attributes match the specified value. ex. {'uid': 'jack', 'mail': '*****@*****.**'} would require one of these fields to be set to the specified value """ filter_objs = [] if username_matches: filter_objs.append( self._create_username_attribute_filter(username_matches)) # Requires that the user is in the security group if one is provided. # Group must be either one of the user's memberof attributes or the primarygroupid attribute. security_group_filter_obj = yield self._create_security_group_filter() if security_group_filter_obj: filter_objs.append(security_group_filter_obj) # Add filter to match only objects that are users. filter_objs.append(self.factory.user_filter) # Config can supply an optional extra filter expression to # be AND'd with the above. if self.factory.ldap_filter is not None: filter_objs.append(self.factory.ldap_filter) defer.returnValue(pureldap.LDAPFilter_and(filter_objs))
def test_and_or(self): text = "(&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))" filt = pureldap.LDAPFilter_and( [ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value="objectClass" ), assertionValue=pureldap.LDAPAssertionValue(value="Person"), ), pureldap.LDAPFilter_or( [ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription(value="sn"), assertionValue=pureldap.LDAPAssertionValue(value="Jensen"), ), pureldap.LDAPFilter_substrings( type="cn", substrings=[ pureldap.LDAPFilter_substrings_initial(value="Babs J") ], ), ] ), ] ) self.assertEqual(ldapfilter.parseFilter(text), filt) self.assertEqual(filt.asText(), text)
def test_andornot(self): text = r"(&(!(|(cn=foo)(cn=bar)))(sn=a*b*c*d))" filt = pureldap.LDAPFilter_and( [ pureldap.LDAPFilter_not( pureldap.LDAPFilter_or( [ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value="cn" ), assertionValue=pureldap.LDAPAssertionValue(value="foo"), ), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value="cn" ), assertionValue=pureldap.LDAPAssertionValue(value="bar"), ), ] ) ), pureldap.LDAPFilter_substrings( type="sn", substrings=[ pureldap.LDAPFilter_substrings_initial("a"), pureldap.LDAPFilter_substrings_any("b"), pureldap.LDAPFilter_substrings_any("c"), pureldap.LDAPFilter_substrings_final("d"), ], ), ] ) self.assertEqual(ldapfilter.parseFilter(text), filt) self.assertEqual(filt.asText(), text)
def test_andornot(self): text = r'(&(!(|(cn=foo)(cn=bar)))(sn=a*b*c*d))' filt = pureldap.LDAPFilter_and([ pureldap.LDAPFilter_not( pureldap.LDAPFilter_or([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value='cn'), assertionValue=pureldap.LDAPAssertionValue( value='foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( value='cn'), assertionValue=pureldap.LDAPAssertionValue( value='bar')), ])), pureldap.LDAPFilter_substrings( type='sn', substrings=[ pureldap.LDAPFilter_substrings_initial('a'), pureldap.LDAPFilter_substrings_any('b'), pureldap.LDAPFilter_substrings_any('c'), pureldap.LDAPFilter_substrings_final('d'), ]) ]) self.assertEqual(ldapfilter.parseFilter(text), filt) self.assertEqual(filt.asText(), text)
def search( self, filterText=None, filterObject=None, attributes=(), scope=None, derefAliases=None, sizeLimit=0, timeLimit=0, typesOnly=0, callback=None, ): if filterObject is None and filterText is None: filterObject = pureldap.LDAPFilterMatchAll elif filterObject is None and filterText is not None: filterObject = ldapfilter.parseFilter(filterText) elif filterObject is not None and filterText is None: pass elif filterObject is not None and filterText is not None: f = ldapfilter.parseFilter(filterText) filterObject = pureldap.LDAPFilter_and((f, filterObject)) if scope is None: scope = pureldap.LDAP_SCOPE_wholeSubtree if derefAliases is None: derefAliases = pureldap.LDAP_DEREF_neverDerefAliases # choose iterator: base/children/subtree if scope == pureldap.LDAP_SCOPE_wholeSubtree: iterator = self.subtree elif scope == pureldap.LDAP_SCOPE_singleLevel: iterator = self.children elif scope == pureldap.LDAP_SCOPE_baseObject: def iterateSelf(callback): callback(self) return defer.succeed(None) iterator = iterateSelf else: raise ldaperrors.LDAPProtocolError("unknown search scope: %r" % scope) results = [] if callback is None: matchCallback = results.append else: matchCallback = callback # gather results, send them def _tryMatch(entry): if entry.match(filterObject): matchCallback(entry) iterator(callback=_tryMatch) if callback is None: return defer.succeed(results) else: return defer.succeed(None)
def getHosts(nets, e, filter): filt = pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription("objectClass"), assertionValue=pureber.BEROctetString("ipHost"), ) if filter: filt = pureldap.LDAPFilter_and(value=(filter, filt)) def _cbGotHost(e): host = Host(str(e.dn), str(only(e, "cn")), list(str(i) for i in e["ipHostNumber"])) for hostIP in host.ipAddresses: parent = None for net in nets: if net.isInNet(hostIP.ipAddress): parent = net break if parent: hostIP.printZone(parent.name) else: sys.stderr.write("IP address %s is in no net, discarding.\n" % hostIP) d = e.search(filterObject=filt, attributes=["ipHostNumber", "cn"], callback=_cbGotHost) return d
def _tryService(self, services, baseEntry, request, controls, reply): try: serviceName = services.pop(0) except IndexError: return None timestamp = self.timestamp() d = baseEntry.search( filterObject=pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription( 'objectClass'), assertionValue=pureldap.LDAPAssertionValue( 'serviceSecurityObject')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('owner'), assertionValue=pureldap.LDAPAssertionValue(request.dn)), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('cn'), assertionValue=pureldap.LDAPAssertionValue(serviceName)), pureldap.LDAPFilter_or([ # no time pureldap.LDAPFilter_not( pureldap.LDAPFilter_present('validFrom')), # or already valid pureldap.LDAPFilter_lessOrEqual( attributeDesc=pureldap.LDAPAttributeDescription( 'validFrom'), assertionValue=pureldap.LDAPAssertionValue(timestamp)), ]), pureldap.LDAPFilter_or([ # no time pureldap.LDAPFilter_not( pureldap.LDAPFilter_present('validUntil')), # or still valid pureldap.LDAPFilter_greaterOrEqual( attributeDesc=pureldap.LDAPAttributeDescription( 'validUntil'), assertionValue=pureldap.LDAPAssertionValue(timestamp)), ]), ]), attributes=('1.1', )) def _gotEntries(entries): if not entries: return None assert len(entries) == 1 #TODO e = entries[0] d = e.bind(request.auth) return d d.addCallback(_gotEntries) d.addCallbacks(callback=self._loopIfNone, callbackArgs=(services, baseEntry, request, controls, reply), errback=self._loopIfBindError, errbackArgs=(services, baseEntry, request, controls, reply)) return d
def search(self, filterText=None, filterObject=None, attributes=(), scope=None, derefAliases=None, sizeLimit=0, sizeLimitIsNonFatal=False, timeLimit=0, typesOnly=0, callback=None): self._checkState() d = defer.Deferred() if filterObject is None and filterText is None: filterObject = pureldap.LDAPFilterMatchAll elif filterObject is None and filterText is not None: filterObject = ldapfilter.parseFilter(filterText) elif filterObject is not None and filterText is None: pass elif filterObject is not None and filterText is not None: f = ldapfilter.parseFilter(filterText) filterObject = pureldap.LDAPFilter_and((f, filterObject)) if scope is None: scope = pureldap.LDAP_SCOPE_wholeSubtree if derefAliases is None: derefAliases = pureldap.LDAP_DEREF_neverDerefAliases if attributes is None: attributes = ['1.1'] results = [] if callback is None: cb = results.append else: cb = callback try: op = pureldap.LDAPSearchRequest(baseObject=str(self.dn), scope=scope, derefAliases=derefAliases, sizeLimit=sizeLimit, timeLimit=timeLimit, typesOnly=typesOnly, filter=filterObject, attributes=attributes) self.client.send_multiResponse( op, self._cbSearchMsg, d, cb, complete=not attributes, sizeLimitIsNonFatal=sizeLimitIsNonFatal) except ldapclient.LDAPClientConnectionLostException: d.errback(Failure()) else: if callback is None: d.addCallback(lambda dummy: results) return d
def getNets(e, domain, forward, reverse, filter): filt = pureldap.LDAPFilter_and( value=( pureldap.LDAPFilter_present("cn"), pureldap.LDAPFilter_present("ipNetworkNumber"), pureldap.LDAPFilter_present("ipNetmaskNumber"), ) ) if filter: filt = pureldap.LDAPFilter_and(value=(filter, filt)) d = e.search( filterObject=filt, attributes=[ "cn", "ipNetworkNumber", "ipNetmaskNumber", ], ) def _cbGotNets(nets, forward, reverse): r = [] for e in nets: net = Net( str(e.dn), str(only(e, "cn")), str(only(e, "ipNetworkNumber")), str(only(e, "ipNetmaskNumber")), ) print(net.getForward(), file=forward) for data in reverse: ip = dns.aton(net.address) if ip & data["netmask"] == data["address"]: if "file" not in data: data["tempname"] = "%s.%d.tmp" % (data["filename"], os.getpid()) data["file"] = open(data["tempname"], "w") print(net.getReverse(domain), file=data["file"]) net.reverseZone = data r.append(net) return r d.addCallback(_cbGotNets, forward, reverse) return d
def test_basic_and_not_equal(self): filter1 = pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('foo'), assertionValue=pureldap.LDAPAttributeValue('1')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('bar'), assertionValue=pureldap.LDAPAttributeValue('2')), ]) filter2 = pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('bar'), assertionValue=pureldap.LDAPAttributeValue('1')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('foo'), assertionValue=pureldap.LDAPAttributeValue('1')), ]) self.assertNotEqual(filter1, filter2)
def getHosts(e, filter): filt = pureldap.LDAPFilter_and(value=( pureldap.LDAPFilter_present("cn"), pureldap.LDAPFilter_present("ipHostNumber"), )) if filter: filt = pureldap.LDAPFilter_and(value=(filter, filt)) d = e.search( filterObject=filt, attributes=[ "cn", "ipHostNumber", "macAddress", "bootFile", ], ) d.addCallback(_cbGetHosts) return d
def test_and_item(self): text = r'(&(cn=foo)(cn=bar))' filt = pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription(value='cn'), assertionValue=pureldap.LDAPAssertionValue(value='foo')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription(value='cn'), assertionValue=pureldap.LDAPAssertionValue(value='bar')), ]) self.assertEqual(ldapfilter.parseFilter(text), filt) self.assertEqual(filt.asText(), text)
def test_and_noMatch(self): o = inmemory.ReadOnlyInMemoryLDAPEntry(dn='cn=foo,dc=example,dc=com', attributes={ 'objectClass': ['a', 'b'], 'aValue': ['a'], 'bValue': ['b'], }) result = o.match( pureldap.LDAPFilter_and([ pureldap.LDAPFilter_present('cValue'), pureldap.LDAPFilter_present('dValue'), ])) self.assertEqual(result, False)
def test_and_noMatch(self): o = inmemory.ReadOnlyInMemoryLDAPEntry( dn="cn=foo,dc=example,dc=com", attributes={ "objectClass": ["a", "b"], "aValue": ["a"], "bValue": ["b"], }, ) result = o.match( pureldap.LDAPFilter_and([ pureldap.LDAPFilter_present("cValue"), pureldap.LDAPFilter_present("dValue"), ])) self.assertEqual(result, False)
def _getSearchFilter(self): filters = [] for attr, value in self.data.items(): if value is not None: f = ldapfilter.parseMaybeSubstring(attr, value) filters.append(f) if not filters: return None searchFilter = pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('objectClass'), assertionValue=pureldap.LDAPAssertionValue( 'addressbookPerson')) ] + filters) return searchFilter
def test_and_or(self): text = '(&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))' filt = pureldap.LDAPFilter_and( [ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription(value='objectClass'), assertionValue=pureldap.LDAPAssertionValue(value='Person')), pureldap.LDAPFilter_or([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription(value='sn'), assertionValue=pureldap.LDAPAssertionValue(value='Jensen')), pureldap.LDAPFilter_substrings( type='cn', substrings=[ pureldap.LDAPFilter_substrings_initial(value='Babs J') ]) ]), ]) self.assertEqual(ldapfilter.parseFilter(text), filt) self.assertEqual(filt.asText(), text)
def data_servicePasswords(self, ctx, data): user = ctx.locate(inevow.ISession).getLoggedInRoot().loggedIn config = interfaces.ILDAPConfig(ctx) e = ldapsyntax.LDAPEntry(client=user.client, dn=config.getBaseDN()) d = e.search(filterObject=pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('objectClass'), assertionValue=pureldap.LDAPAssertionValue( 'serviceSecurityObject')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('owner'), assertionValue=pureldap.LDAPAssertionValue(str(self.dn))), pureldap.LDAPFilter_present('cn'), ]), attributes=['cn']) return d
def create_service_account_user_filter_object(self, username_matches): """ Return a filterObject for searching for a potential service account user with the provided username_matches. While this method could find objects that aren't service accounts, use with caution because this filter does not check extra configuration options like security_group_dn or ldap_filter. The returned filter will only make sure that the object is a user type object and that they have an attribute that matches the provided username. That last bit is determined by username_matches. Args: username_matches: {'uid': 'jack', 'mail': '*****@*****.**'} """ filter_objs = [ self._create_username_attribute_filter(username_matches), self.factory.user_filter, ] return pureldap.LDAPFilter_and(filter_objs)
def main(cfg, filter_text): try: baseDN = cfg.getBaseDN() except config.MissingBaseDNError as e: print("{}: {}.".format(sys.argv[0], e), file=sys.stderr) sys.exit(1) filt = ldapfilter.parseFilter("(objectClass=posixAccount)") if filter_text is not None: filt = pureldap.LDAPFilter_and( [filt, ldapfilter.parseFilter(filter_text)]) c = ldapconnector.LDAPClientCreator(reactor, ldapclient.LDAPClient) d = c.connectAnonymously(dn=baseDN, overrides=cfg.getServiceLocationOverrides()) d.addCallback(search, baseDN, filt) d.addErrback(error) d.addBoth(lambda x: reactor.stop()) reactor.run() sys.exit(exitStatus)
def search(self, filterText=None, filterObject=None, attributes=(), scope=None, derefAliases=None, sizeLimit=0, sizeLimitIsNonFatal=False, timeLimit=0, typesOnly=0, callback=None, controls=None, return_controls=False): self._checkState() d = defer.Deferred() if filterObject is None and filterText is None: filterObject = pureldap.LDAPFilterMatchAll elif filterObject is None and filterText is not None: filterObject = ldapfilter.parseFilter(filterText) elif filterObject is not None and filterText is None: pass elif filterObject is not None and filterText is not None: f = ldapfilter.parseFilter(filterText) filterObject = pureldap.LDAPFilter_and((f, filterObject)) if scope is None: scope = pureldap.LDAP_SCOPE_wholeSubtree if derefAliases is None: derefAliases = pureldap.LDAP_DEREF_neverDerefAliases if attributes is None: attributes = ['1.1'] results = [] if callback is None: cb = results.append else: cb = callback try: op = pureldap.LDAPSearchRequest(baseObject=self.dn.getText(), scope=scope, derefAliases=derefAliases, sizeLimit=sizeLimit, timeLimit=timeLimit, typesOnly=typesOnly, filter=filterObject, attributes=attributes) dsend = self.client.send_multiResponse_ex( op, controls, self._cbSearchMsg, d, cb, complete=not attributes, sizeLimitIsNonFatal=sizeLimitIsNonFatal) except ldapclient.LDAPClientConnectionLostException: d.errback(Failure()) else: if callback is None: if return_controls: d.addCallback(lambda ctls: (results, ctls)) else: d.addCallback(lambda dummy: results) def rerouteerr(e): d.errback(e) # returning None will stop the error # from being propagated and logged. dsend.addErrback(rerouteerr) return d
dnAttributes=dn) extensible.setParseAction(_p_extensible) item = simple ^ present ^ substring ^ extensible item.setName('item') item.leaveWhitespace() not_ = Suppress(Literal('!')) + filter_ not_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_not(t[0])) not_.setName('not') filterlist = OneOrMore(filter_) or_ = Suppress(Literal('|')) + filterlist or_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_or(t)) or_.setName('or') and_ = Suppress(Literal('&')) + filterlist and_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_and(t)) and_.setName('and') filtercomp = and_ | or_ | not_ | item filtercomp.setName('filtercomp') filter_ << (Suppress(Literal('(').leaveWhitespace()) + filtercomp + Suppress(Literal(')').leaveWhitespace())) filter_.setName('filter') filtercomp.leaveWhitespace() filter_.leaveWhitespace() toplevel = (StringStart().leaveWhitespace() + filter_ + StringEnd().leaveWhitespace()) toplevel.leaveWhitespace() toplevel.setName('toplevel')
class SearchForm(configurable.Configurable): implements(inevow.IContainer) filter = None def __init__(self): super(SearchForm, self).__init__(None) self.data = {} def getBindingNames(self, ctx): return ['search'] def bind_search(self, ctx): l = [] l.append(annotate.Argument('ctx', annotate.Context())) for field in config.getSearchFieldNames(): l.append(annotate.Argument('search_%s' % field, annotate.String(label=field))) l.append(annotate.Argument('searchfilter', annotate.String(label=_("Advanced search")))) l.append(annotate.Argument( 'scope', annotate.Choice(label=_("Search depth"), choices=[ pureldap.LDAP_SCOPE_wholeSubtree, pureldap.LDAP_SCOPE_singleLevel, pureldap.LDAP_SCOPE_baseObject, ], stringify=strScope, default=pureldap.LDAP_SCOPE_wholeSubtree))) return annotate.MethodBinding( name='search', action=_("Search"), typeValue=annotate.Method(arguments=l, label=_('Search'))) def search(self, ctx, scope, searchfilter, **kw): filt=[] for k,v in kw.items(): assert k.startswith('search_') if not k.startswith("search_"): continue k=k[len("search_"):] if v is None: continue v=v.strip() if v=='': continue # TODO escape ) in v # TODO handle unknown filter name right (old form open in browser etc) filter_ = config.getSearchFieldByName(k, vars={'input': v}) filt.append(ldapfilter.parseFilter(filter_)) if searchfilter: try: filt.append(ldapfilter.parseFilter(searchfilter)) except ldapfilter.InvalidLDAPFilter, e: raise annotate.ValidateError( {'searchfilter': str(e), }, partialForm=inevow.IRequest(ctx).args) if filt: if len(filt)==1: query=filt[0] else: query=pureldap.LDAPFilter_and(filt) else: query=pureldap.LDAPFilterMatchAll self.data.update(kw) # annotate.Choice in nevow 0.3 maps choices to a list, and # passes indexes to this list to client. annotate.Choice in # 0.4pre converts choice to string and back with callbacks, # defaulting to str, and leaving the value as string. We # can't use the 0.4pre mechanism as long as we need 0.3 # compatibility, so work around that by explicitly making sure # scope is an integer. scope = int(scope) self.data['scope'] = scope self.data['searchfilter'] = searchfilter self.filter = query return self