This repository has been archived by the owner on Sep 3, 2023. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Different attributes have different matching semantics, (e.g., case-sensitive vs case-insensitive). For known matching algorithms, model our local comparison semantics after server side ones.
- Loading branch information
Showing
4 changed files
with
129 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
require 'ldaptic/syntaxes' | ||
|
||
module Ldaptic | ||
# RFC4517 - Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules | ||
# RFC4518 - Lightweight Directory Access Protocol (LDAP): Internationalized | ||
# String Preparation | ||
module MatchingRules | ||
def self.for(name) | ||
name = name.to_s | ||
name = name[0..0].upcase + name[1..-1].to_s | ||
if !name.empty? && const_defined?(name) | ||
const_get(name) | ||
else | ||
CaseIgnoreMatch | ||
end | ||
end | ||
|
||
class OctetStringMatch | ||
def matchable(value) | ||
value | ||
end | ||
|
||
def match(one, two) | ||
matchable(one) == matchable(two) | ||
end | ||
end | ||
|
||
class Boolean < OctetStringMatch | ||
end | ||
|
||
class CaseExactMatch < OctetStringMatch | ||
def matchable(value) | ||
super.gsub(/ +/, ' ').sub(/\A */, ' ').sub(/ *\z/, ' ') | ||
end | ||
end | ||
|
||
class CaseExactIA5Match < CaseExactMatch | ||
end | ||
|
||
class CaseIgnoreMatch < CaseExactMatch | ||
def matchable(value) | ||
super.downcase | ||
end | ||
end | ||
|
||
class CaseIgnoreIA5Match < CaseIgnoreMatch | ||
end | ||
|
||
class CaseIgnoreListMatch < CaseIgnoreMatch | ||
end | ||
|
||
class GeneralizedTimeMatch < OctetStringMatch | ||
def matchable(value) | ||
Ldaptic::Syntaxes::GeneralizedTime.parse(value) | ||
end | ||
end | ||
|
||
class NumericStringMatch < OctetStringMatch | ||
def matchable(value) | ||
super.delete(' ') | ||
end | ||
end | ||
|
||
class DistinguishedNameMatch < OctetStringMatch | ||
def matchable(value) | ||
Ldaptic::DN(value) | ||
end | ||
end | ||
|
||
class TelephoneNumberMatch < CaseIgnoreMatch | ||
# Doesn't remove unicode hyphen equivalents \u058A, \u2010, \u2011, | ||
# \u2212, \ufe63, or \uff0d on account of unicode being so darn difficult | ||
# to get right in both 1.8 and 1.9. | ||
def matchable(value) | ||
super.delete(' ').delete('-') | ||
end | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper') | ||
require 'ldaptic/matching_rules' | ||
|
||
class LdapticMatchingRulesTest < Test::Unit::TestCase | ||
include Ldaptic::MatchingRules | ||
|
||
def test_for | ||
assert_equal GeneralizedTimeMatch, Ldaptic::MatchingRules.for("generalizedTimeMatch") | ||
end | ||
|
||
def test_case_exact_match | ||
assert CaseExactMatch.new.match(' A bc', 'A bc') | ||
assert !CaseExactMatch.new.match(' A bc', 'a bC') | ||
end | ||
|
||
def test_case_ignore_match | ||
assert CaseIgnoreMatch.new.match(' A bc', 'a bC') | ||
end | ||
|
||
def test_generalized_time_match | ||
assert_equal Time.utc(2000,1,1,12,34,56), GeneralizedTimeMatch.new.matchable("20000101123456.0Z") | ||
end | ||
|
||
def test_numeric_string | ||
assert NumericStringMatch.new.match(' 123 4', '123 4') | ||
assert !NumericStringMatch.new.match('1234', '1235') | ||
end | ||
|
||
def test_distinguished_name_match | ||
assert DistinguishedNameMatch.new.match('a=1+b=2', 'B=2+A=1') | ||
assert !DistinguishedNameMatch.new.match('a=1,b=2', 'b=2,a=1') | ||
end | ||
|
||
def test_telephone_number_match | ||
assert TelephoneNumberMatch.new.match("911", "9 1-1-") | ||
end | ||
|
||
end |