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