From 497e2be4e725a8807bcec05bfc3386de914d6abf Mon Sep 17 00:00:00 2001 From: blackhedd Date: Mon, 17 Apr 2006 20:39:54 +0000 Subject: [PATCH] Added unit tests for search-filters --- lib/net/ldap/filter.rb | 35 +++++++++++++++++++++++++++++++++++ tests/testldap.rb | 2 +- testserver/ldapserver.rb | 32 +++++++++++++++++++------------- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/lib/net/ldap/filter.rb b/lib/net/ldap/filter.rb index 4ad9abf..4293ef5 100644 --- a/lib/net/ldap/filter.rb +++ b/lib/net/ldap/filter.rb @@ -171,6 +171,41 @@ class Filter end + + # We get a Ruby object which comes from parsing an RFC-1777 "Filter" + # object. Convert it to a Net::LDAP::Filter. + # TODO, we're hardcoding the RFC-1777 BER-encodings of the various + # filter types. Could pull them out into a constant. + # + def Filter::parse_ldap_filter obj + case obj.ber_identifier + when 0x87 # present. context-specific primitive 7. + Filter.eq( obj.to_s, "*" ) + when 0xa3 # equalityMatch. context-specific constructed 3. + Filter.eq( obj[0], obj[1] ) + else + raise LdapError.new( "unknown ldap search-filter type: #{obj.ber_identifier}" ) + end + end + + + # We got a hash of attribute values. + # Do we match the attributes? + # Return T/F, and call match recursively as necessary. + def match entry + case @op + when :eq + if @right == "*" + l = entry[@left] and l.length > 0 + else + l = entry[@left] and l = l.to_a and l.index(@right) + end + else + raise LdapError.new( "unknown filter type in match: #{@op}" ) + end + end + + end # class Net::LDAP::Filter end # class Net::LDAP diff --git a/tests/testldap.rb b/tests/testldap.rb index 0c2c206..2f86d89 100644 --- a/tests/testldap.rb +++ b/tests/testldap.rb @@ -141,7 +141,7 @@ class TestLdapClient < Test::Unit::TestCase ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth search = { :base => "dc=bayshorenetworks,dc=com", - :filter => Net::LDAP::Filter.eq( "sn", "Verdon" ) + :filter => Net::LDAP::Filter.eq( "sn", "Fosse" ) } ldap.search( search ) {|res| diff --git a/testserver/ldapserver.rb b/testserver/ldapserver.rb index c7e7911..60b8572 100644 --- a/testserver/ldapserver.rb +++ b/testserver/ldapserver.rb @@ -122,6 +122,7 @@ module LdapServer # } def handle_search_request pdu unless @authenticated + # NOTE, early exit. send_ldap_response 5, pdu[0].to_i, 50, "", "Who did you say you were?" return end @@ -143,23 +144,28 @@ module LdapServer end filters = pdu[1][6] - if filters.length > 0 - p filters.ber_identifier + if filters.length == 0 + # NOTE, early exit. + send_ldap_response 5, pdu[0].to_i, 53, "", "No filter specified" end + # TODO, what if this returns nil? + filter = Net::LDAP::Filter.parse_ldap_filter( filters ) + $ldif.each {|dn, entry| + if filter.match( entry ) + attrs = [] + entry.each {|k, v| + if requested_attrs == :all or requested_attrs.include?(k.downcase) + attrvals = v.map {|v1| v1.to_ber}.to_ber_set + attrs << [k.to_ber, attrvals].to_ber_sequence + end + } - attrs = [] - entry.each {|k, v| - if requested_attrs == :all or requested_attrs.include?(k.downcase) - attrvals = v.map {|v1| v1.to_ber}.to_ber_set - attrs << [k.to_ber, attrvals].to_ber_sequence - end - } - - appseq = [dn.to_ber, attrs.to_ber_sequence].to_ber_appsequence(4) - pkt = [msgid.to_ber, appseq].to_ber_sequence - send_data pkt + appseq = [dn.to_ber, attrs.to_ber_sequence].to_ber_appsequence(4) + pkt = [msgid.to_ber, appseq].to_ber_sequence + send_data pkt + end }