lib/activeldap/base.rb in ruby-activeldap-debug-0.7.0 vs lib/activeldap/base.rb in ruby-activeldap-debug-0.7.1
- old
+ new
@@ -1,9 +1,10 @@
# === ActiveLDAP - an OO-interface to LDAP objects inspired by ActiveRecord
# Author: Will Drewry <will@alum.bu.edu>
# License: See LICENSE and COPYING.txt
-# Copyright 2004 Will Drewry <will@alum.bu.edu>
+# Copyright 2004-2006 Will Drewry <will@alum.bu.edu>
+# Some portions Copyright 2006 Google Inc
#
# == Summary
# ActiveLDAP lets you read and update LDAP entries in a completely object
# oriented fashion, even handling attributes with multiple names seamlessly.
# It was inspired by ActiveRecord so extending it to deal with custom
@@ -345,10 +346,16 @@
#TODO# Check for 'No message' when retrying
# The connection may have gone stale. Let's reconnect and retry.
retry if Base.reconnect()
# Do nothing on failure
@@logger.debug "No matches for #{config[:filter]} and attrs #{config[:attrs]}"
+ rescue => detail
+ if LDAP::err2exception(@@conn.err)[0] == LDAP::ServerDown
+ @@logger.debug("Failed to write: #{entry}")
+ retry if Base.reconnect()
+ end
+ raise detail
end
return values
end
# find
@@ -405,10 +412,16 @@
# The connection may have gone stale. Let's reconnect and retry.
retry if Base.reconnect()
# Do nothing on failure
@@logger.debug "no matches for #{attr}=#{val}"
+ rescue => detail
+ if LDAP::err2exception(@@conn.err)[0] == LDAP::ServerDown
+ @@logger.debug("Failed to write: #{entry}")
+ retry if Base.reconnect()
+ end
+ raise detail
end
return nil
end
private_class_method :find
@@ -462,10 +475,16 @@
# The connection may have gone stale. Let's reconnect and retry.
retry if Base.reconnect()
# Do nothing on failure
@@logger.debug "no matches for #{attr}=#{val}"
+ rescue => detail
+ if LDAP::err2exception(@@conn.err)[0] == LDAP::ServerDown
+ @@logger.debug("Failed to write: #{entry}")
+ retry if Base.reconnect()
+ end
+ raise detail
end
return matches
end
private_class_method :find_all
@@ -712,10 +731,14 @@
#todo# check for 'no message' when retrying
# the connection may have gone stale. let's reconnect and retry.
retry if Base.reconnect()
raise DeleteError, "Failed to delete LDAP entry: '#{@dn}'"
rescue LDAP::ResultError => detail
+ if LDAP::err2exception(@@conn.err)[0] == LDAP::ServerDown
+ @@logger.debug("Failed to write: #{entry}")
+ retry if Base.reconnect()
+ end
raise DeleteError, "Failed to delete LDAP entry: '#{@dn}'"
end
end
@@ -794,10 +817,12 @@
name, *suffix_a = pair[0].split(/;/)
suffix = ';'+ suffix_a.join(';') if suffix_a.size > 0
name = @attr_methods[name]
name = pair[0].split(/;/)[0] if name.nil? # for objectClass, or removed vals
value = data[name+suffix]
+ # If it doesn't exist, don't freak out.
+ value = [] if value.nil?
# Detect subtypes and account for them
binary = LDAP::LDAP_MOD_BVALUES if Base.schema.binary? name
replaceable.push(name+suffix)
@@ -825,10 +850,12 @@
name, *suffix_a = pair[0].split(/;/)
suffix = ';' + suffix_a.join(';') if suffix_a.size > 0
name = @attr_methods[name]
name = pair[0].split(/;/)[0] if name.nil? # for obj class or removed vals
value = pair[1]
+ # Make sure to change this to an Array if there was mistake earlier.
+ value = [] if value.nil?
if not replaceable.member? name+suffix
# Detect subtypes and account for them
binary = LDAP::LDAP_MOD_BVALUES if Base.schema.binary? name
@@logger.debug("adding attribute to existing entry: #{name+suffix}: #{value.inspect}")
@@ -841,15 +868,21 @@
begin
@@logger.debug("#write: modifying #{@dn}")
@@conn.modify(@dn, entry)
@@logger.debug("#write: modify successful")
rescue RuntimeError => detail
- #todo# check for 'no message' when retrying
+ #todo# check for SERVER_DOWN
# the connection may have gone stale. let's reconnect and retry.
retry if Base.reconnect()
raise WriteError, "Could not update LDAP entry: #{detail}"
rescue => detail
+ @@logger.debug(LDAP::err2exception(@@conn.err).inspect)
+ if LDAP::err2exception(@@conn.err)[0] == LDAP::ServerDown
+ @@logger.debug("Failed to write: #{entry}")
+ retry if Base.reconnect()
+ end
+ @@logger.debug("Failed to write: #{entry}")
raise WriteError, "Could not update LDAP entry: #{detail}"
end
else # add everything!
@@logger.debug("#write: adding all attribute value pairs")
@@logger.debug("#write: adding #{@attr_methods[dnattr()].inspect} = #{data[@attr_methods[dnattr()]].inspect}")
@@ -878,10 +911,14 @@
rescue RuntimeError => detail
# The connection may have gone stale. Let's reconnect and retry.
retry if Base.reconnect()
raise WriteError, "Could not add LDAP entry[#{Base.connection.err2string(Base.connection.err)}]: #{detail}"
rescue LDAP::ResultError => detail
+ if LDAP::err2exception(@@conn.err)[0] == LDAP::ServerDown
+ @@logger.debug("Failed to write: #{entry}")
+ retry if Base.reconnect()
+ end
raise WriteError, "Could not add LDAP entry[#{Base.connection.err2string(Base.connection.err)}]: #{detail}"
end
end
@@logger.debug("#write: resetting @ldap_data to a dup of @data")
@ldap_data = Marshal.load(Marshal.dump(@data))
@@ -1345,11 +1382,24 @@
# Check if it is the DN attribute
if dnattr() == attr
raise AttributeAssignmentError, 'cannot modify the DN attribute value'
end
+ # Enforce LDAP-pleasing values
+ @@logger.debug("value = #{value.inspect}, value.class = #{value.class}")
+ real_value = value
+ # Squash empty values
+ if value.class == Array
+ real_value = value.collect {|c| if c == ''; []; else c; end }.flatten
+ end
+ real_value = [] if real_value.nil?
+ real_value = [] if real_value == ''
+ real_value = [real_value] if real_value.class == String
+ real_value = [real_value.to_s] if real_value.class == Fixnum
+ # NOTE: Hashes are allowed for subtyping.
+
# Assign the value
- @data[attr] = value
+ @data[attr] = real_value
# Return the passed in value
@@logger.debug("stub: exitting attribute_method=")
return @data[attr]
end