Class | ActiveLdap::Ldif::Parser |
In: |
lib/active_ldap/ldif.rb
|
Parent: | Object |
ATTRIBUTE_TYPE_CHARS | = | /[a-zA-Z][a-zA-Z0-9\-]*/ |
SAFE_CHAR | = | /[\x01-\x09\x0B-\x0C\x0E-\x7F]/ |
SAFE_INIT_CHAR | = | /[\x01-\x09\x0B-\x0C\x0E-\x1F\x21-\x39\x3B\x3D-\x7F]/ |
SAFE_STRING | = | /#{SAFE_INIT_CHAR}#{SAFE_CHAR}*/ |
FILL | = | / */ |
ldif | [R] |
# File lib/active_ldap/ldif.rb, line 96 96: def initialize(source) 97: @ldif = nil 98: source = source.to_s if source.is_a?(LDIF) 99: @source = source 100: end
# File lib/active_ldap/ldif.rb, line 107 107: def parse 108: return @ldif if @ldif 109: 110: @scanner = Scanner.new(@source) 111: raise version_spec_is_missing unless @scanner.scan(/version:/) 112: @scanner.scan(FILL) 113: 114: version = @scanner.scan(/\d+/) 115: raise version_number_is_missing if version.nil? 116: 117: version = Integer(version) 118: raise unsupported_version(version) if version != 1 119: 120: raise separator_is_missing unless @scanner.scan_separators 121: 122: records = parse_records 123: 124: @ldif = LDIF.new(records) 125: end
# File lib/active_ldap/ldif.rb, line 468 468: def attribute_spec_is_missing 469: invalid_ldif(_("attribute spec is missing")) 470: end
# File lib/active_ldap/ldif.rb, line 428 428: def attribute_type_is_missing 429: invalid_ldif(_("attribute type is missing")) 430: end
# File lib/active_ldap/ldif.rb, line 436 436: def attribute_value_separator_is_missing 437: invalid_ldif(_("':' is missing")) 438: end
# File lib/active_ldap/ldif.rb, line 452 452: def change_type_is_missing 453: invalid_ldif(_("change type is missing")) 454: end
# File lib/active_ldap/ldif.rb, line 464 464: def change_type_value_is_missing 465: invalid_ldif(_("change type value is missing")) 466: end
# File lib/active_ldap/ldif.rb, line 456 456: def control_type_is_missing 457: invalid_ldif(_("control type is missing")) 458: end
# File lib/active_ldap/ldif.rb, line 460 460: def criticality_is_missing 461: invalid_ldif(_("criticality is missing")) 462: end
# File lib/active_ldap/ldif.rb, line 480 480: def delete_old_rdn_mark_is_missing 481: invalid_ldif(_("'deleteoldrdn:' is missing")) 482: end
# File lib/active_ldap/ldif.rb, line 484 484: def delete_old_rdn_value_is_missing 485: invalid_ldif(_("delete old RDN value is missing")) 486: end
# File lib/active_ldap/ldif.rb, line 424 424: def dn_has_invalid_character(character) 425: invalid_ldif(_("DN has an invalid character: %s") % character) 426: end
# File lib/active_ldap/ldif.rb, line 416 416: def dn_is_missing 417: invalid_ldif(_("DN is missing")) 418: end
# File lib/active_ldap/ldif.rb, line 412 412: def dn_mark_is_missing 413: invalid_ldif(_("'dn:' is missing")) 414: end
# File lib/active_ldap/ldif.rb, line 420 420: def invalid_dn(dn_string, reason) 421: invalid_ldif(_("DN is invalid: %s: %s") % [dn_string, reason]) 422: end
# File lib/active_ldap/ldif.rb, line 392 392: def invalid_ldif(reason) 393: LdifInvalid.new(@source, reason, @scanner.line, @scanner.column) 394: end
# File lib/active_ldap/ldif.rb, line 440 440: def invalid_uri(uri_string, message) 441: invalid_ldif(_("URI is invalid: %s: %s") % [uri_string, message]) 442: end
# File lib/active_ldap/ldif.rb, line 444 444: def modify_spec_separator_is_missing 445: invalid_ldif(_("'-' is missing")) 446: end
# File lib/active_ldap/ldif.rb, line 472 472: def new_rdn_mark_is_missing 473: invalid_ldif(_("'newrdn:' is missing")) 474: end
# File lib/active_ldap/ldif.rb, line 476 476: def new_rdn_value_is_missing 477: invalid_ldif(_("new RDN value is missing")) 478: end
# File lib/active_ldap/ldif.rb, line 488 488: def new_superior_value_is_missing 489: invalid_ldif(_("new superior value is missing")) 490: end
# File lib/active_ldap/ldif.rb, line 432 432: def option_is_missing 433: invalid_ldif(_("option is missing")) 434: end
# File lib/active_ldap/ldif.rb, line 201 201: def parse_attribute 202: type, options = parse_attribute_description 203: value = parse_attribute_value 204: [type, options, value] 205: end
# File lib/active_ldap/ldif.rb, line 194 194: def parse_attribute_description 195: type = @scanner.scan(ATTRIBUTE_TYPE_CHARS) 196: raise attribute_type_is_missing if type.nil? 197: options = parse_options 198: [type, options] 199: end
# File lib/active_ldap/ldif.rb, line 217 217: def parse_attribute_value(accept_external_file=true) 218: raise attribute_value_separator_is_missing if @scanner.scan(/:/).nil? 219: if @scanner.scan(/:/) 220: @scanner.scan(FILL) 221: read_base64_value 222: elsif accept_external_file and @scanner.scan(/</) 223: @scanner.scan(FILL) 224: read_external_file 225: else 226: @scanner.scan(FILL) 227: @scanner.scan(SAFE_STRING) 228: end 229: end
# File lib/active_ldap/ldif.rb, line 163 163: def parse_attributes(least=0, &block) 164: i = 0 165: attributes = {} 166: block ||= Proc.new {@scanner.check_separator} 167: loop do 168: i += 1 169: if i >= least 170: break if block.call or @scanner.eos? 171: end 172: type, options, value = parse_attribute 173: if @scanner.scan_separator.nil? and !@scanner.eos? 174: raise separator_is_missing 175: end 176: attributes[type] ||= [] 177: container = attributes[type] 178: options.each do |option| 179: parent = container.find do |val| 180: val.is_a?(Hash) and val.has_key?(option) 181: end 182: if parent.nil? 183: parent = {option => []} 184: container << parent 185: end 186: container = parent[option] 187: end 188: container << value 189: end 190: raise attribute_spec_is_missing if attributes.size < least 191: attributes 192: end
# File lib/active_ldap/ldif.rb, line 256 256: def parse_change_type 257: return nil unless @scanner.scan(/changetype:/) 258: @scanner.scan(FILL) 259: type = @scanner.check(ATTRIBUTE_TYPE_CHARS) 260: raise change_type_value_is_missing if type.nil? 261: unless @scanner.scan(/add|delete|modrdn|moddn|modify/) 262: raise unknown_change_type(type) 263: end 264: 265: raise separator_is_missing unless @scanner.scan_separator 266: type 267: end
# File lib/active_ldap/ldif.rb, line 329 329: def parse_change_type_record(dn, controls, change_type) 330: case change_type 331: when "add" 332: attributes = parse_attributes(1) 333: AddRecord.new(dn, controls, attributes) 334: when "delete" 335: DeleteRecord.new(dn, controls) 336: when "moddn" 337: parse_modify_name_record(ModifyDNRecord, dn, controls) 338: when "modrdn" 339: parse_modify_name_record(ModifyRDNRecord, dn, controls) 340: when "modify" 341: parse_modify_record(dn, controls) 342: else 343: raise unknown_change_type(change_type) 344: end 345: end
# File lib/active_ldap/ldif.rb, line 231 231: def parse_control 232: return nil if @scanner.scan(/control:/).nil? 233: @scanner.scan(FILL) 234: type = @scanner.scan(/\d+(?:\.\d+)*/) 235: raise control_type_is_missing if type.nil? 236: criticality = nil 237: if @scanner.scan(/ +/) 238: criticality = @scanner.scan(/true|false/) 239: raise criticality_is_missing if criticality.nil? 240: end 241: value = parse_attribute_value if @scanner.check(/:/) 242: raise separator_is_missing unless @scanner.scan_separator 243: ChangeRecord::Control.new(type, criticality, value) 244: end
# File lib/active_ldap/ldif.rb, line 246 246: def parse_controls 247: controls = [] 248: loop do 249: control = parse_control 250: break if control.nil? 251: controls << control 252: end 253: controls 254: end
# File lib/active_ldap/ldif.rb, line 157 157: def parse_dn(dn_string) 158: DN.parse(dn_string).to_s 159: rescue DistinguishedNameInvalid 160: raise invalid_dn(dn_string, $!.reason) 161: end
# File lib/active_ldap/ldif.rb, line 269 269: def parse_modify_name_record(klass, dn, controls) 270: raise new_rdn_mark_is_missing unless @scanner.scan(/newrdn\b/) 271: new_rdn = parse_attribute_value(false) 272: raise new_rdn_value_is_missing if new_rdn.nil? 273: raise separator_is_missing unless @scanner.scan_separator 274: 275: unless @scanner.scan(/deleteoldrdn:/) 276: raise delete_old_rdn_mark_is_missing 277: end 278: @scanner.scan(FILL) 279: delete_old_rdn = @scanner.scan(/[01]/) 280: raise delete_old_rdn_value_is_missing if delete_old_rdn.nil? 281: raise separator_is_missing unless @scanner.scan_separator 282: 283: if @scanner.scan(/newsuperior\b/) 284: @scanner.scan(FILL) 285: new_superior = parse_attribute_value(false) 286: raise new_superior_value_is_missing if new_superior.nil? 287: new_superior = parse_dn(new_superior) 288: raise separator_is_missing unless @scanner.scan_separator 289: end 290: klass.new(dn, controls, new_rdn, delete_old_rdn, new_superior) 291: end
# File lib/active_ldap/ldif.rb, line 308 308: def parse_modify_record(dn, controls) 309: operations = [] 310: loop do 311: spec = parse_modify_spec 312: break if spec.nil? 313: type, attribute, options, attributes = spec 314: case type 315: when "add" 316: klass = ModifyRecord::AddOperation 317: when "delete" 318: klass = ModifyRecord::DeleteOperation 319: when "replace" 320: klass = ModifyRecord::ReplaceOperation 321: else 322: unknown_modify_type(type) 323: end 324: operations << klass.new(attribute, options, attributes) 325: end 326: ModifyRecord.new(dn, controls, operations) 327: end
# File lib/active_ldap/ldif.rb, line 293 293: def parse_modify_spec 294: return nil unless @scanner.check(/(#{ATTRIBUTE_TYPE_CHARS}):/) 295: type = @scanner[1] 296: unless @scanner.scan(/(?:add|delete|replace):/) 297: raise unknown_modify_type(type) 298: end 299: @scanner.scan(FILL) 300: attribute, options = parse_attribute_description 301: raise separator_is_missing unless @scanner.scan_separator 302: attributes = parse_attributes {@scanner.check(/-/)} 303: raise modify_spec_separator_is_missing unless @scanner.scan(/-/) 304: raise separator_is_missing unless @scanner.scan_separator 305: [type, attribute, options, attributes] 306: end
# File lib/active_ldap/ldif.rb, line 207 207: def parse_options 208: options = [] 209: while @scanner.scan(/;/) 210: option = @scanner.scan(ATTRIBUTE_TYPE_CHARS) 211: raise option_is_missing if option.nil? 212: options << option 213: end 214: options 215: end
# File lib/active_ldap/ldif.rb, line 347 347: def parse_record 348: raise dn_mark_is_missing unless @scanner.scan(/dn:/) 349: if @scanner.scan(/:/) 350: @scanner.scan(FILL) 351: dn = read_base64_value 352: raise dn_is_missing if dn.nil? 353: dn = parse_dn(dn) 354: else 355: @scanner.scan(FILL) 356: dn = @scanner.scan(/#{SAFE_STRING}$/) 357: if dn.nil? 358: partial_dn = @scanner.scan(SAFE_STRING) 359: raise dn_has_invalid_character(@scanner.check(/./)) if partial_dn 360: raise dn_is_missing 361: end 362: dn = parse_dn(dn) 363: end 364: 365: raise separator_is_missing unless @scanner.scan_separator 366: 367: controls = parse_controls 368: change_type = parse_change_type 369: raise change_type_is_missing if change_type.nil? and !controls.empty? 370: 371: if change_type 372: parse_change_type_record(dn, controls, change_type) 373: else 374: attributes = parse_attributes(1) 375: ContentRecord.new(dn, attributes) 376: end 377: end
# File lib/active_ldap/ldif.rb, line 379 379: def parse_records 380: records = [] 381: loop do 382: records << parse_record 383: break if @scanner.eos? 384: raise separator_is_missing if @scanner.scan_separator.nil? 385: 386: break if @scanner.eos? 387: break if @scanner.scan_separators and @scanner.eos? 388: end 389: records 390: end
# File lib/active_ldap/ldif.rb, line 128 128: def read_base64_value 129: value = @scanner.scan(/[a-zA-Z0-9\+\/=]+/) 130: return nil if value.nil? 131: encoding = value.encoding if value.respond_to?(:encoding) 132: value = value.unpack("m")[0].chomp 133: if value.respond_to?(:force_encoding) 134: value.force_encoding(encoding) 135: value.force_encoding("ascii-8bit") unless value.valid_encoding? 136: end 137: value 138: end
# File lib/active_ldap/ldif.rb, line 140 140: def read_external_file 141: uri_string = @scanner.scan(URI::ABS_URI) 142: raise uri_is_missing if uri_string.nil? 143: uri = nil 144: begin 145: uri = URI.parse(uri_string) 146: rescue URI::Error 147: raise invalid_uri(uri_string, $!.message) 148: end 149: 150: if uri.scheme == "file" 151: File.open(uri.path, "rb") {|file| file.read} 152: else 153: uri.read 154: end 155: end
# File lib/active_ldap/ldif.rb, line 408 408: def separator_is_missing 409: invalid_ldif(_("separator is missing")) 410: end
# File lib/active_ldap/ldif.rb, line 448 448: def unknown_change_type(change_type) 449: invalid_ldif(_("unknown change type: %s") % change_type) 450: end
# File lib/active_ldap/ldif.rb, line 492 492: def unknown_modify_type(type) 493: invalid_ldif(_("unknown modify type: %s") % type) 494: end
# File lib/active_ldap/ldif.rb, line 404 404: def unsupported_version(version) 405: invalid_ldif(_("unsupported version: %d") % version) 406: end
# File lib/active_ldap/ldif.rb, line 400 400: def version_number_is_missing 401: invalid_ldif(_("version number is missing")) 402: end