Skip to content

Commit

Permalink
Merge remote branch 'upstream/master' into paging_control
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamstah committed Jan 5, 2011
2 parents 756529b + 5bc73d3 commit 51f2c95
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.rspec
spec/ldap.yml
.rvmrc
*.gemspec
Expand Down
10 changes: 10 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
source "http://rubygems.org"

gem 'hoe'
gem 'hoe-git'

group :development do
gem 'metaid'
gem 'rspec', '~> 2.0'
gem 'flexmock'
end
29 changes: 29 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
GEM
remote: http://rubygems.org/
specs:
diff-lcs (1.1.2)
flexmock (0.8.11)
hoe (2.8.0)
rake (>= 0.8.7)
hoe-git (1.3.0)
hoe (>= 2.2.0)
metaid (1.0)
rake (0.8.7)
rspec (2.3.0)
rspec-core (~> 2.3.0)
rspec-expectations (~> 2.3.0)
rspec-mocks (~> 2.3.0)
rspec-core (2.3.1)
rspec-expectations (2.3.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.3.0)

PLATFORMS
ruby

DEPENDENCIES
flexmock
hoe
hoe-git
metaid
rspec (~> 2.0)
61 changes: 61 additions & 0 deletions lib/net/ldap/filter.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Encoding: UTF-8
# Copyright (C) 2006 by Francis Cianfrocca and other contributors. All
# Rights Reserved.
#
Expand Down Expand Up @@ -79,6 +80,8 @@ class << self
# <tt>mail</tt> value containing the substring "anderson":
#
# f = Net::LDAP::Filter.eq("mail", "*anderson*")
#
# This filter does not perform any escaping
def eq(attribute, value)
new(:eq, attribute, value)
end
Expand Down Expand Up @@ -136,10 +139,44 @@ def ex(attribute, value)
# Creates a Filter object indicating that a particular attribute value
# is either not present or does not match a particular string; see
# Filter::eq for more information.
#
# This filter does not perform any escaping
def ne(attribute, value)
new(:ne, attribute, value)
end

##
# Creates a Filter object indicating that the value of a particular
# attribute must match a particular string. The attribute value is
# escaped, so the "*" character is interpreted literally.
def equals(attribute, value)
new(:eq, attribute, escape(value))
end

##
# Creates a Filter object indicating that the value of a particular
# attribute must begin with a particular string. The attribute value is
# escaped, so the "*" character is interpreted literally.
def begins(attribute, value)
new(:eq, attribute, escape(value) + "*")
end

##
# Creates a Filter object indicating that the value of a particular
# attribute must end with a particular string. The attribute value is
# escaped, so the "*" character is interpreted literally.
def ends(attribute, value)
new(:eq, attribute, "*" + escape(value))
end

##
# Creates a Filter object indicating that the value of a particular
# attribute must contain a particular string. The attribute value is
# escaped, so the "*" character is interpreted literally.
def contains(attribute, value)
new(:eq, attribute, "*" + escape(value) + "*")
end

##
# Creates a Filter object indicating that a particular attribute value
# is greater than or equal to the specified value.
Expand Down Expand Up @@ -207,6 +244,30 @@ def present?(attribute)
alias_method :present, :present?
alias_method :pres, :present?

# http://tools.ietf.org/html/rfc4515 lists these exceptions from UTF1
# charset for filters. All of the following must be escaped in any normal
# string using a single backslash ('\') as escape.
#
ESCAPES = {
'!' => '21', # EXCLAMATION = %x21 ; exclamation mark ("!")
'&' => '26', # AMPERSAND = %x26 ; ampersand (or AND symbol) ("&")
'*' => '2A', # ASTERISK = %x2A ; asterisk ("*")
':' => '3A', # COLON = %x3A ; colon (":")
'|' => '7C', # VERTBAR = %x7C ; vertical bar (or pipe) ("|")
'~' => '7E', # TILDE = %x7E ; tilde ("~")
}
# Compiled character class regexp using the keys from the above hash.
ESCAPE_RE = Regexp.new(
"[" +
ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
"]")

##
# Escape a string for use in an LDAP filter
def escape(string)
string.gsub(ESCAPE_RE) { |char| "\\" + ESCAPES[char] }
end

##
# Converts an LDAP search filter in BER format to an Net::LDAP::Filter
# object. The incoming BER object most likely came to us by parsing an
Expand Down
3 changes: 1 addition & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
require 'net/ldap'
require 'rubygems'

Spec::Runner.configure do |config|
RSpec.configure do |config|
config.mock_with :flexmock
end
7 changes: 4 additions & 3 deletions spec/unit/ber/ber_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
require 'net/ldap'

describe "BER encoding of" do
def properly_encode_and_decode
simple_matcher('properly encode and decode') do |given|

RSpec::Matchers.define :properly_encode_and_decode do
match do |given|
given.to_ber.read_ber.should == given
end
end

context "arrays" do
it "should properly encode/decode []" do
[].should properly_encode_and_decode
Expand Down
32 changes: 31 additions & 1 deletion spec/unit/ldap/filter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,35 @@
Net::LDAP::Filter.construct("uid=O'Keefe").to_rfc2254.should == "(uid=O'Keefe)"
end
end


describe "convenience filter constructors" do
def eq(attribute, value)
described_class.eq(attribute, value)
end
describe "<- .equals(attr, val)" do
it "should delegate to .eq with escaping" do
described_class.equals('dn', 'f*oo').should == eq('dn', 'f\2Aoo')
end
end
describe "<- .begins(attr, val)" do
it "should delegate to .eq with escaping" do
described_class.begins('dn', 'f*oo').should == eq('dn', 'f\2Aoo*')
end
end
describe "<- .ends(attr, val)" do
it "should delegate to .eq with escaping" do
described_class.ends('dn', 'f*oo').should == eq('dn', '*f\2Aoo')
end
end
describe "<- .contains(attr, val)" do
it "should delegate to .eq with escaping" do
described_class.contains('dn', 'f*oo').should == eq('dn', '*f\2Aoo*')
end
end
end
describe "<- .escape(str)" do
it "should escape !, &, *, :, | and ~" do
Net::LDAP::Filter.escape('!&*:|~').should == "\\21\\26\\2A\\3A\\7C\\7E"
end
end
end

0 comments on commit 51f2c95

Please sign in to comment.