| 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 11
11: def initialize(source)
12: @dn = nil
13: source = source.to_s if source.is_a?(DN)
14: unless source.is_a?(String)
15: raise DistinguishedNameInputInvalid.new(source)
16: end
17: @source = source
18: end
# File lib/active_ldap/distinguished_name.rb, line 20
20: def parse
21: return @dn if @dn
22:
23: rdns = []
24: scanner = StringScanner.new(@source)
25:
26: scanner.scan(/\s*/)
27: raise rdn_is_missing if scanner.scan(/\s*\+\s*/)
28: raise name_component_is_missing if scanner.scan(/\s*,\s*/)
29:
30: rdn = {}
31: until scanner.eos?
32: type = scan_attribute_type(scanner)
33: skip_attribute_type_and_value_separator(scanner)
34: value = scan_attribute_value(scanner)
35: rdn[type] = value
36: if scanner.scan(/\s*\+\s*/)
37: raise rdn_is_missing if scanner.eos?
38: elsif scanner.scan(/\s*\,\s*/)
39: rdns << rdn
40: rdn = {}
41: raise name_component_is_missing if scanner.eos?
42: else
43: scanner.scan(/\s*/)
44: rdns << rdn if scanner.eos?
45: end
46: end
47:
48: @dn = DN.new(*rdns)
49: @dn
50: end
# File lib/active_ldap/distinguished_name.rb, line 143
143: def attribute_type_is_missing
144: invalid_dn(_("attribute type is missing"))
145: end
# File lib/active_ldap/distinguished_name.rb, line 147
147: def attribute_value_is_missing
148: invalid_dn(_("attribute value is missing"))
149: end
# File lib/active_ldap/distinguished_name.rb, line 118
118: def collect_pairs(scanner)
119: result = ""
120: while scanner.scan(PAIR_RE)
121: if scanner[2]
122: result << [scanner[2].hex].pack("C*")
123: else
124: result << scanner[1]
125: end
126: end
127: result.force_encoding("utf-8") if result.respond_to?(:force_encoding)
128: result
129: end
# File lib/active_ldap/distinguished_name.rb, line 151
151: def found_unmatched_quotation
152: invalid_dn(_("found unmatched quotation"))
153: end
# File lib/active_ldap/distinguished_name.rb, line 131
131: def invalid_dn(reason)
132: DistinguishedNameInvalid.new(@source, reason)
133: end
# File lib/active_ldap/distinguished_name.rb, line 135
135: def name_component_is_missing
136: invalid_dn(_("name component is missing"))
137: end
# File lib/active_ldap/distinguished_name.rb, line 139
139: def rdn_is_missing
140: invalid_dn(_("relative distinguished name (RDN) is missing"))
141: end
# File lib/active_ldap/distinguished_name.rb, line 54
54: def scan_attribute_type(scanner)
55: raise attribute_type_is_missing unless scanner.scan(ATTRIBUTE_TYPE_RE)
56: scanner[1]
57: end
# File lib/active_ldap/distinguished_name.rb, line 67
67: def scan_attribute_value(scanner)
68: if scanner.scan(HEX_STRING_RE)
69: value = scanner[1].scan(/../).collect do |hex_pair|
70: hex_pair.hex
71: end.pack("C*")
72: elsif scanner.scan(/\"/)
73: value = scan_quoted_attribute_value(scanner)
74: else
75: value = scan_not_quoted_attribute_value(scanner)
76: end
77: raise attribute_value_is_missing if value.blank?
78:
79: value
80: end
# File lib/active_ldap/distinguished_name.rb, line 99
99: def scan_not_quoted_attribute_value(scanner)
100: result = ""
101: until scanner.eos?
102: prev_size = result.size
103: pairs = collect_pairs(scanner)
104: strings = scanner.scan(STRING_CHARS_RE)
105: result << pairs if !pairs.nil? and !pairs.empty?
106: unless strings.nil?
107: if scanner.peek(1) == ","
108: result << strings.rstrip
109: else
110: result << strings
111: end
112: end
113: break if prev_size == result.size
114: end
115: result
116: end
# File lib/active_ldap/distinguished_name.rb, line 82
82: def scan_quoted_attribute_value(scanner)
83: result = ""
84: until scanner.scan(/\"/)
85: scanner.scan(/([^\\\"]*)/)
86: quoted_strings = scanner[1]
87: pairs = collect_pairs(scanner)
88:
89: if scanner.eos? or (quoted_strings.empty? and pairs.empty?)
90: raise found_unmatched_quotation
91: end
92:
93: result << quoted_strings
94: result << pairs
95: end
96: result
97: end