diff --git a/lib/net/ldap/filter.rb b/lib/net/ldap/filter.rb index 8eec9f0..23a88f2 100644 --- a/lib/net/ldap/filter.rb +++ b/lib/net/ldap/filter.rb @@ -79,6 +79,8 @@ class Net::LDAP::Filter # mail 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 @@ -136,10 +138,44 @@ class Net::LDAP::Filter # 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. @@ -207,6 +243,12 @@ class Net::LDAP::Filter alias_method :present, :present? alias_method :pres, :present? + ## + # Escape a string for use in an LDAP filter + def escape(string) + string.gsub(/[\*\(\)\\\0]/) {|s| sprintf("\\%02x", s[0]) } + 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 diff --git a/test/test_filter.rb b/test/test_filter.rb index 88495f1..c7214a7 100644 --- a/test/test_filter.rb +++ b/test/test_filter.rb @@ -24,6 +24,13 @@ class TestFilter < Test::Unit::TestCase assert_equal("(uid=george *)", Filter.eq("uid", "george *").to_s) end + def test_convenience_filters + assert_equal("(uid=\\2a)", Filter.equals("uid", "*").to_s) + assert_equal("(uid=\\28*)", Filter.begins("uid", "(").to_s) + assert_equal("(uid=*\\29)", Filter.ends("uid", ")").to_s) + assert_equal("(uid=*\\5c*)", Filter.contains("uid", "\\").to_s) + end + def test_c2 assert_equal("(uid=george *)", Filter.from_rfc2254("uid=george *").to_rfc2254)