diff options
Diffstat (limited to 'vendor/gems/net-ldap-0.2.2/lib/net/ldap/dataset.rb')
-rw-r--r-- | vendor/gems/net-ldap-0.2.2/lib/net/ldap/dataset.rb | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/vendor/gems/net-ldap-0.2.2/lib/net/ldap/dataset.rb b/vendor/gems/net-ldap-0.2.2/lib/net/ldap/dataset.rb new file mode 100644 index 000000000..363d25971 --- /dev/null +++ b/vendor/gems/net-ldap-0.2.2/lib/net/ldap/dataset.rb @@ -0,0 +1,154 @@ +# -*- ruby encoding: utf-8 -*- +## +# An LDAP Dataset. Used primarily as an intermediate format for converting +# to and from LDIF strings and Net::LDAP::Entry objects. +class Net::LDAP::Dataset < Hash + ## + # Dataset object comments. + attr_reader :comments + + def initialize(*args, &block) # :nodoc: + super + @comments = [] + end + + ## + # Outputs an LDAP Dataset as an array of strings representing LDIF + # entries. + def to_ldif + ary = [] + ary += @comments unless @comments.empty? + keys.sort.each do |dn| + ary << "dn: #{dn}" + + attributes = self[dn].keys.map { |attr| attr.to_s }.sort + attributes.each do |attr| + self[dn][attr.to_sym].each do |value| + if attr == "userpassword" or value_is_binary?(value) + value = [value].pack("m").chomp.gsub(/\n/m, "\n ") + ary << "#{attr}:: #{value}" + else + ary << "#{attr}: #{value}" + end + end + end + + ary << "" + end + block_given? and ary.each { |line| yield line} + + ary + end + + ## + # Outputs an LDAP Dataset as an LDIF string. + def to_ldif_string + to_ldif.join("\n") + end + + ## + # Convert the parsed LDIF objects to Net::LDAP::Entry objects. + def to_entries + ary = [] + keys.each do |dn| + entry = Net::LDAP::Entry.new(dn) + self[dn].each do |attr, value| + entry[attr] = value + end + ary << entry + end + ary + end + + ## + # This is an internal convenience method to determine if a value requires + # base64-encoding before conversion to LDIF output. The standard approach + # in most LDAP tools is to check whether the value is a password, or if + # the first or last bytes are non-printable. Microsoft Active Directory, + # on the other hand, sometimes sends values that are binary in the middle. + # + # In the worst cases, this could be a nasty performance killer, which is + # why we handle the simplest cases first. Ideally, we would also test the + # first/last byte, but it's a bit harder to do this in a way that's + # compatible with both 1.8.6 and 1.8.7. + def value_is_binary?(value) # :nodoc: + value = value.to_s + return true if value[0] == ?: or value[0] == ?< + value.each_byte { |byte| return true if (byte < 32) || (byte > 126) } + false + end + private :value_is_binary? + + class << self + class ChompedIO # :nodoc: + def initialize(io) + @io = io + end + def gets + s = @io.gets + s.chomp if s + end + end + + ## + # Creates a Dataset object from an Entry object. Used mostly to assist + # with the conversion of + def from_entry(entry) + dataset = Net::LDAP::Dataset.new + hash = { } + entry.each_attribute do |attribute, value| + next if attribute == :dn + hash[attribute] = value + end + dataset[entry.dn] = hash + dataset + end + + ## + # Reads an object that returns data line-wise (using #gets) and parses + # LDIF data into a Dataset object. + def read_ldif(io) + ds = Net::LDAP::Dataset.new + io = ChompedIO.new(io) + + line = io.gets + dn = nil + + while line + new_line = io.gets + + if new_line =~ /^[\s]+/ + line << " " << $' + else + nextline = new_line + + if line =~ /^#/ + ds.comments << line + yield :comment, line if block_given? + elsif line =~ /^dn:[\s]*/i + dn = $' + ds[dn] = Hash.new { |k,v| k[v] = [] } + yield :dn, dn if block_given? + elsif line.empty? + dn = nil + yield :end, nil if block_given? + elsif line =~ /^([^:]+):([\:]?)[\s]*/ + # $1 is the attribute name + # $2 is a colon iff the attr-value is base-64 encoded + # $' is the attr-value + # Avoid the Base64 class because not all Ruby versions have it. + attrvalue = ($2 == ":") ? $'.unpack('m').shift : $' + ds[dn][$1.downcase.to_sym] << attrvalue + yield :attr, [$1.downcase.to_sym, attrvalue] if block_given? + end + + line = nextline + end + end + + ds + end + end +end + +require 'net/ldap/entry' unless defined? Net::LDAP::Entry |