Skip to content

Commit 51f2c95

Browse files
author
Jamstah
committed
Merge remote branch 'upstream/master' into paging_control
2 parents 756529b + 5bc73d3 commit 51f2c95

File tree

7 files changed

+137
-6
lines changed

7 files changed

+137
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.rspec
12
spec/ldap.yml
23
.rvmrc
34
*.gemspec

Gemfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
source "http://rubygems.org"
2+
3+
gem 'hoe'
4+
gem 'hoe-git'
5+
6+
group :development do
7+
gem 'metaid'
8+
gem 'rspec', '~> 2.0'
9+
gem 'flexmock'
10+
end

Gemfile.lock

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
GEM
2+
remote: http://rubygems.org/
3+
specs:
4+
diff-lcs (1.1.2)
5+
flexmock (0.8.11)
6+
hoe (2.8.0)
7+
rake (>= 0.8.7)
8+
hoe-git (1.3.0)
9+
hoe (>= 2.2.0)
10+
metaid (1.0)
11+
rake (0.8.7)
12+
rspec (2.3.0)
13+
rspec-core (~> 2.3.0)
14+
rspec-expectations (~> 2.3.0)
15+
rspec-mocks (~> 2.3.0)
16+
rspec-core (2.3.1)
17+
rspec-expectations (2.3.0)
18+
diff-lcs (~> 1.1.2)
19+
rspec-mocks (2.3.0)
20+
21+
PLATFORMS
22+
ruby
23+
24+
DEPENDENCIES
25+
flexmock
26+
hoe
27+
hoe-git
28+
metaid
29+
rspec (~> 2.0)

lib/net/ldap/filter.rb

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# Encoding: UTF-8
12
# Copyright (C) 2006 by Francis Cianfrocca and other contributors. All
23
# Rights Reserved.
34
#
@@ -79,6 +80,8 @@ class << self
7980
# <tt>mail</tt> value containing the substring "anderson":
8081
#
8182
# f = Net::LDAP::Filter.eq("mail", "*anderson*")
83+
#
84+
# This filter does not perform any escaping
8285
def eq(attribute, value)
8386
new(:eq, attribute, value)
8487
end
@@ -136,10 +139,44 @@ def ex(attribute, value)
136139
# Creates a Filter object indicating that a particular attribute value
137140
# is either not present or does not match a particular string; see
138141
# Filter::eq for more information.
142+
#
143+
# This filter does not perform any escaping
139144
def ne(attribute, value)
140145
new(:ne, attribute, value)
141146
end
142147

148+
##
149+
# Creates a Filter object indicating that the value of a particular
150+
# attribute must match a particular string. The attribute value is
151+
# escaped, so the "*" character is interpreted literally.
152+
def equals(attribute, value)
153+
new(:eq, attribute, escape(value))
154+
end
155+
156+
##
157+
# Creates a Filter object indicating that the value of a particular
158+
# attribute must begin with a particular string. The attribute value is
159+
# escaped, so the "*" character is interpreted literally.
160+
def begins(attribute, value)
161+
new(:eq, attribute, escape(value) + "*")
162+
end
163+
164+
##
165+
# Creates a Filter object indicating that the value of a particular
166+
# attribute must end with a particular string. The attribute value is
167+
# escaped, so the "*" character is interpreted literally.
168+
def ends(attribute, value)
169+
new(:eq, attribute, "*" + escape(value))
170+
end
171+
172+
##
173+
# Creates a Filter object indicating that the value of a particular
174+
# attribute must contain a particular string. The attribute value is
175+
# escaped, so the "*" character is interpreted literally.
176+
def contains(attribute, value)
177+
new(:eq, attribute, "*" + escape(value) + "*")
178+
end
179+
143180
##
144181
# Creates a Filter object indicating that a particular attribute value
145182
# is greater than or equal to the specified value.
@@ -207,6 +244,30 @@ def present?(attribute)
207244
alias_method :present, :present?
208245
alias_method :pres, :present?
209246

247+
# http://tools.ietf.org/html/rfc4515 lists these exceptions from UTF1
248+
# charset for filters. All of the following must be escaped in any normal
249+
# string using a single backslash ('\') as escape.
250+
#
251+
ESCAPES = {
252+
'!' => '21', # EXCLAMATION = %x21 ; exclamation mark ("!")
253+
'&' => '26', # AMPERSAND = %x26 ; ampersand (or AND symbol) ("&")
254+
'*' => '2A', # ASTERISK = %x2A ; asterisk ("*")
255+
':' => '3A', # COLON = %x3A ; colon (":")
256+
'|' => '7C', # VERTBAR = %x7C ; vertical bar (or pipe) ("|")
257+
'~' => '7E', # TILDE = %x7E ; tilde ("~")
258+
}
259+
# Compiled character class regexp using the keys from the above hash.
260+
ESCAPE_RE = Regexp.new(
261+
"[" +
262+
ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
263+
"]")
264+
265+
##
266+
# Escape a string for use in an LDAP filter
267+
def escape(string)
268+
string.gsub(ESCAPE_RE) { |char| "\\" + ESCAPES[char] }
269+
end
270+
210271
##
211272
# Converts an LDAP search filter in BER format to an Net::LDAP::Filter
212273
# object. The incoming BER object most likely came to us by parsing an

spec/spec_helper.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
require 'net/ldap'
2-
require 'rubygems'
32

4-
Spec::Runner.configure do |config|
3+
RSpec.configure do |config|
54
config.mock_with :flexmock
65
end

spec/unit/ber/ber_spec.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
require 'net/ldap'
55

66
describe "BER encoding of" do
7-
def properly_encode_and_decode
8-
simple_matcher('properly encode and decode') do |given|
7+
8+
RSpec::Matchers.define :properly_encode_and_decode do
9+
match do |given|
910
given.to_ber.read_ber.should == given
1011
end
1112
end
12-
13+
1314
context "arrays" do
1415
it "should properly encode/decode []" do
1516
[].should properly_encode_and_decode

spec/unit/ldap/filter_spec.rb

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,35 @@
4949
Net::LDAP::Filter.construct("uid=O'Keefe").to_rfc2254.should == "(uid=O'Keefe)"
5050
end
5151
end
52-
52+
53+
describe "convenience filter constructors" do
54+
def eq(attribute, value)
55+
described_class.eq(attribute, value)
56+
end
57+
describe "<- .equals(attr, val)" do
58+
it "should delegate to .eq with escaping" do
59+
described_class.equals('dn', 'f*oo').should == eq('dn', 'f\2Aoo')
60+
end
61+
end
62+
describe "<- .begins(attr, val)" do
63+
it "should delegate to .eq with escaping" do
64+
described_class.begins('dn', 'f*oo').should == eq('dn', 'f\2Aoo*')
65+
end
66+
end
67+
describe "<- .ends(attr, val)" do
68+
it "should delegate to .eq with escaping" do
69+
described_class.ends('dn', 'f*oo').should == eq('dn', '*f\2Aoo')
70+
end
71+
end
72+
describe "<- .contains(attr, val)" do
73+
it "should delegate to .eq with escaping" do
74+
described_class.contains('dn', 'f*oo').should == eq('dn', '*f\2Aoo*')
75+
end
76+
end
77+
end
78+
describe "<- .escape(str)" do
79+
it "should escape !, &, *, :, | and ~" do
80+
Net::LDAP::Filter.escape('!&*:|~').should == "\\21\\26\\2A\\3A\\7C\\7E"
81+
end
82+
end
5383
end

0 commit comments

Comments
 (0)