| Class | ActiveLdap::DistinguishedName::Parser |
| In: |
lib/active_ldap/distinguished_name.rb
|
| Parent: | Object |
| ATTRIBUTE_TYPE_RE | = | /\s*([a-zA-Z][a-zA-Z\d\-]*|\d+(?:\.\d+)*)\s*/ |
| HEX_PAIR | = | "(?:[\\da-fA-F]{2})" |
| STRING_CHARS_RE | = | /[^,=\+<>\#;\\\"]*/ |
| PAIR_RE | = | /\\([,=\+<>\#;]|\\|\"|(#{HEX_PAIR}))/ |
| HEX_STRING_RE | = | /\#(#{HEX_PAIR}+)/ |
| dn | [R] |
# File lib/active_ldap/distinguished_name.rb, line 7
7: def initialize(source)
8: @dn = nil
9: @source = source
10: end
# File lib/active_ldap/distinguished_name.rb, line 12
12: def parse
13: return @dn if @dn
14:
15: rdns = []
16: scanner = StringScanner.new(@source)
17:
18: scanner.scan(/\s*/)
19: raise rdn_is_missing if scanner.scan(/\s*\+\s*/)
20: raise name_component_is_missing if scanner.scan(/\s*,\s*/)
21:
22: rdn = {}
23: until scanner.eos?
24: type = scan_attribute_type(scanner)
25: skip_attribute_type_and_value_separator(scanner)
26: value = scan_attribute_value(scanner)
27: rdn[type] = value
28: if scanner.scan(/\s*\+\s*/)
29: raise rdn_is_missing if scanner.eos?
30: elsif scanner.scan(/\s*\,\s*/)
31: rdns << rdn
32: rdn = {}
33: raise name_component_is_missing if scanner.eos?
34: else
35: scanner.scan(/\s*/)
36: rdns << rdn if scanner.eos?
37: end
38: end
39:
40: @dn = DN.new(*rdns)
41: @dn
42: end
# File lib/active_ldap/distinguished_name.rb, line 134
134: def attribute_type_is_missing
135: invalid_dn("attribute type is missing")
136: end
# File lib/active_ldap/distinguished_name.rb, line 138
138: def attribute_value_is_missing
139: invalid_dn("attribute value is missing")
140: end
# File lib/active_ldap/distinguished_name.rb, line 110
110: def collect_pairs(scanner)
111: result = ""
112: while scanner.scan(PAIR_RE)
113: if scanner[2]
114: result << [scanner[2].hex].pack("C*")
115: else
116: result << scanner[1]
117: end
118: end
119: result
120: end
# File lib/active_ldap/distinguished_name.rb, line 142
142: def found_unmatched_quotation
143: invalid_dn("found unmatched quotation")
144: end
# File lib/active_ldap/distinguished_name.rb, line 122
122: def invalid_dn(reason)
123: DistinguishedNameInvalid.new(@source, reason)
124: end
# File lib/active_ldap/distinguished_name.rb, line 126
126: def name_component_is_missing
127: invalid_dn("name component is missing")
128: end
# File lib/active_ldap/distinguished_name.rb, line 130
130: def rdn_is_missing
131: invalid_dn("relative distinguished name (RDN) is missing")
132: end
# File lib/active_ldap/distinguished_name.rb, line 46
46: def scan_attribute_type(scanner)
47: raise attribute_type_is_missing unless scanner.scan(ATTRIBUTE_TYPE_RE)
48: scanner[1]
49: end
# File lib/active_ldap/distinguished_name.rb, line 59
59: def scan_attribute_value(scanner)
60: if scanner.scan(HEX_STRING_RE)
61: value = scanner[1].scan(/../).collect do |hex_pair|
62: hex_pair.hex
63: end.pack("C*")
64: elsif scanner.scan(/\"/)
65: value = scan_quoted_attribute_value(scanner)
66: else
67: value = scan_not_quoted_attribute_value(scanner)
68: end
69: raise attribute_value_is_missing if value.blank?
70:
71: value
72: end
# File lib/active_ldap/distinguished_name.rb, line 91
91: def scan_not_quoted_attribute_value(scanner)
92: result = ""
93: until scanner.eos?
94: prev_size = result.size
95: pairs = collect_pairs(scanner)
96: strings = scanner.scan(STRING_CHARS_RE)
97: result << pairs if !pairs.nil? and !pairs.empty?
98: unless strings.nil?
99: if scanner.peek(1) == ","
100: result << strings.rstrip
101: else
102: result << strings
103: end
104: end
105: break if prev_size == result.size
106: end
107: result
108: end
# File lib/active_ldap/distinguished_name.rb, line 74
74: def scan_quoted_attribute_value(scanner)
75: result = ""
76: until scanner.scan(/\"/)
77: scanner.scan(/([^\\\"]*)/)
78: quoted_strings = scanner[1]
79: pairs = collect_pairs(scanner)
80:
81: if scanner.eos? or (quoted_strings.empty? and pairs.empty?)
82: raise found_unmatched_quotation
83: end
84:
85: result << quoted_strings
86: result << pairs
87: end
88: result
89: end