From a3824392bf31a4ed3a75932251011e340e57749b Mon Sep 17 00:00:00 2001 From: Kaspar Schiess Date: Mon, 22 Mar 2010 15:17:26 +0100 Subject: [PATCH] + Adds a specification for the new ldap extensible filter I am not sure about this, since I haven't been able to find documentation about what this does. This should work, though. Cleanup of comments and exceptions, adds specification for Filter.ex and a parser method. --- lib/net/ber/ber_parser.rb | 2 +- lib/net/ldap.rb | 3 +++ lib/net/ldap/filter.rb | 23 ++++++++++++++++- spec/unit/ldap/filter_spec.rb | 48 +++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 spec/unit/ldap/filter_spec.rb diff --git a/lib/net/ber/ber_parser.rb b/lib/net/ber/ber_parser.rb index 4846958..f24e550 100644 --- a/lib/net/ber/ber_parser.rb +++ b/lib/net/ber/ber_parser.rb @@ -102,7 +102,7 @@ module Net n.ber_identifier = id n else - raise BerError.new( "unsupported object type: id=#{id}" ) + raise BerError, "unsupported object type: id=0x#{id.to_s(16)}" end obj diff --git a/lib/net/ldap.rb b/lib/net/ldap.rb index cd16a40..7d16093 100644 --- a/lib/net/ldap.rb +++ b/lib/net/ldap.rb @@ -283,6 +283,8 @@ module Net 0 => :string, # password 1 => :string, # Kerberos v4 2 => :string, # Kerberos v5 + 3 => :string, # SearchFilter-extensible + 4 => :string, # SearchFilter-extensible 7 => :string, # serverSaslCreds }, :constructed => { @@ -294,6 +296,7 @@ module Net 5 => :array, # SearchFilter-GE 6 => :array, # SearchFilter-LE 7 => :array, # serverSaslCreds + 9 => :array, # SearchFilter-extensible } } }) diff --git a/lib/net/ldap/filter.rb b/lib/net/ldap/filter.rb index 83b795f..fd50cf0 100644 --- a/lib/net/ldap/filter.rb +++ b/lib/net/ldap/filter.rb @@ -247,11 +247,32 @@ class Net::LDAP::Filter eq(ber.first.to_s, str) when 0xa5 # context-specific constructed 5, "greaterOrEqual" ge(ber.first.to_s, ber.last.to_s) - when 0xa6 # context-specific constructed 5, "lessOrEqual" + when 0xa6 # context-specific constructed 6, "lessOrEqual" le(ber.first.to_s, ber.last.to_s) when 0x87 # context-specific primitive 7, "present" # call to_s to get rid of the BER-identifiedness of the incoming string. present?(ber.to_s) + when 0xa9 # context-specific constructed 9, "extensible comparison" + raise Net::LDAP::LdapError, "Invalid extensible search filter, should be at least two elements" if ber.size<2 + + # Reassembles the extensible filter parts + # (["sn", "2.4.6.8.10", "Barbara Jones", '1']) + type = value = dn = rule = nil + ber.each do |element| + case element.ber_identifier + when 0x81 then rule=element + when 0x82 then type=element + when 0x83 then value=element + when 0x84 then dn='dn' + end + end + + attribute = '' + attribute << type if type + attribute << ":#{dn}" if dn + attribute << ":#{rule}" if rule + + ex(attribute, value) else raise Net::LDAP::LdapError, "Invalid BER tag-value (#{ber.ber_identifier}) in search filter." end diff --git a/spec/unit/ldap/filter_spec.rb b/spec/unit/ldap/filter_spec.rb new file mode 100644 index 0000000..9585ff0 --- /dev/null +++ b/spec/unit/ldap/filter_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +describe Net::LDAP::Filter do + describe "<- .ex(attr, value)" do + context "('foo', 'bar')" do + attr_reader :filter + before(:each) do + @filter = Net::LDAP::Filter.ex('foo', 'bar') + end + it "should convert to 'foo:=bar'" do + filter.to_s.should == '(foo:=bar)' + end + it "should survive roundtrip via to_s/from_rfc2254" do + Net::LDAP::Filter.from_rfc2254(filter.to_s).should == filter + end + it "should survive roundtrip conversion to/from ber" do + ber = filter.to_ber + Net::LDAP::Filter.parse_ber(ber.read_ber(Net::LDAP::AsnSyntax)).should == + filter + end + end + context "various legal inputs" do + [ + '(o:dn:=Ace Industry)', + '(:dn:2.4.8.10:=Dino)', + '(cn:dn:1.2.3.4.5:=John Smith)', + '(sn:dn:2.4.6.8.10:=Barbara Jones)', + ].each do |filter_str| + context "from_rfc2254(#{filter_str.inspect})" do + attr_reader :filter + before(:each) do + @filter = Net::LDAP::Filter.from_rfc2254(filter_str) + end + + it "should decode into a Net::LDAP::Filter" do + filter.should be_an_instance_of(Net::LDAP::Filter) + end + it "should survive roundtrip conversion to/from ber" do + ber = filter.to_ber + Net::LDAP::Filter.parse_ber(ber.read_ber(Net::LDAP::AsnSyntax)).should == + filter + end + end + end + end + end + +end \ No newline at end of file