Skip to content

Commit a382439

Browse files
committed
+ 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.
1 parent 3e07125 commit a382439

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed

lib/net/ber/ber_parser.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def read_ber syntax=nil
102102
n.ber_identifier = id
103103
n
104104
else
105-
raise BerError.new( "unsupported object type: id=#{id}" )
105+
raise BerError, "unsupported object type: id=0x#{id.to_s(16)}"
106106
end
107107

108108
obj

lib/net/ldap.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ class LdapError < StandardError; end
283283
0 => :string, # password
284284
1 => :string, # Kerberos v4
285285
2 => :string, # Kerberos v5
286+
3 => :string, # SearchFilter-extensible
287+
4 => :string, # SearchFilter-extensible
286288
7 => :string, # serverSaslCreds
287289
},
288290
:constructed => {
@@ -294,6 +296,7 @@ class LdapError < StandardError; end
294296
5 => :array, # SearchFilter-GE
295297
6 => :array, # SearchFilter-LE
296298
7 => :array, # serverSaslCreds
299+
9 => :array, # SearchFilter-extensible
297300
}
298301
}
299302
})

lib/net/ldap/filter.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,32 @@ def parse_ber(ber)
247247
eq(ber.first.to_s, str)
248248
when 0xa5 # context-specific constructed 5, "greaterOrEqual"
249249
ge(ber.first.to_s, ber.last.to_s)
250-
when 0xa6 # context-specific constructed 5, "lessOrEqual"
250+
when 0xa6 # context-specific constructed 6, "lessOrEqual"
251251
le(ber.first.to_s, ber.last.to_s)
252252
when 0x87 # context-specific primitive 7, "present"
253253
# call to_s to get rid of the BER-identifiedness of the incoming string.
254254
present?(ber.to_s)
255+
when 0xa9 # context-specific constructed 9, "extensible comparison"
256+
raise Net::LDAP::LdapError, "Invalid extensible search filter, should be at least two elements" if ber.size<2
257+
258+
# Reassembles the extensible filter parts
259+
# (["sn", "2.4.6.8.10", "Barbara Jones", '1'])
260+
type = value = dn = rule = nil
261+
ber.each do |element|
262+
case element.ber_identifier
263+
when 0x81 then rule=element
264+
when 0x82 then type=element
265+
when 0x83 then value=element
266+
when 0x84 then dn='dn'
267+
end
268+
end
269+
270+
attribute = ''
271+
attribute << type if type
272+
attribute << ":#{dn}" if dn
273+
attribute << ":#{rule}" if rule
274+
275+
ex(attribute, value)
255276
else
256277
raise Net::LDAP::LdapError, "Invalid BER tag-value (#{ber.ber_identifier}) in search filter."
257278
end

spec/unit/ldap/filter_spec.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require 'spec_helper'
2+
3+
describe Net::LDAP::Filter do
4+
describe "<- .ex(attr, value)" do
5+
context "('foo', 'bar')" do
6+
attr_reader :filter
7+
before(:each) do
8+
@filter = Net::LDAP::Filter.ex('foo', 'bar')
9+
end
10+
it "should convert to 'foo:=bar'" do
11+
filter.to_s.should == '(foo:=bar)'
12+
end
13+
it "should survive roundtrip via to_s/from_rfc2254" do
14+
Net::LDAP::Filter.from_rfc2254(filter.to_s).should == filter
15+
end
16+
it "should survive roundtrip conversion to/from ber" do
17+
ber = filter.to_ber
18+
Net::LDAP::Filter.parse_ber(ber.read_ber(Net::LDAP::AsnSyntax)).should ==
19+
filter
20+
end
21+
end
22+
context "various legal inputs" do
23+
[
24+
'(o:dn:=Ace Industry)',
25+
'(:dn:2.4.8.10:=Dino)',
26+
'(cn:dn:1.2.3.4.5:=John Smith)',
27+
'(sn:dn:2.4.6.8.10:=Barbara Jones)',
28+
].each do |filter_str|
29+
context "from_rfc2254(#{filter_str.inspect})" do
30+
attr_reader :filter
31+
before(:each) do
32+
@filter = Net::LDAP::Filter.from_rfc2254(filter_str)
33+
end
34+
35+
it "should decode into a Net::LDAP::Filter" do
36+
filter.should be_an_instance_of(Net::LDAP::Filter)
37+
end
38+
it "should survive roundtrip conversion to/from ber" do
39+
ber = filter.to_ber
40+
Net::LDAP::Filter.parse_ber(ber.read_ber(Net::LDAP::AsnSyntax)).should ==
41+
filter
42+
end
43+
end
44+
end
45+
end
46+
end
47+
48+
end

0 commit comments

Comments
 (0)