lib/active_ldap/adapter/base.rb in activeldap-1.0.2 vs lib/active_ldap/adapter/base.rb in activeldap-1.0.9
- old
+ new
@@ -22,10 +22,12 @@
attr_reader :runtime
def initialize(configuration={})
@runtime = 0
@connection = nil
@disconnected = false
+ @bound = false
+ @bind_tried = false
@entry_attributes = {}
@configuration = configuration.dup
@logger = @configuration.delete(:logger)
@configuration.assert_valid_keys(VALID_ADAPTER_CONFIGURATION_KEYS)
VALID_ADAPTER_CONFIGURATION_KEYS.each do |name|
@@ -42,27 +44,31 @@
host = options[:host] || @host
method = options[:method] || @method || :plain
port = options[:port] || @port || ensure_port(method)
method = ensure_method(method)
@disconnected = false
+ @bound = false
+ @bind_tried = false
@connection, @uri, @with_start_tls = yield(host, port, method)
prepare_connection(options)
bind(options)
end
def disconnect!(options={})
- return if @connection.nil?
unbind(options)
@connection = @uri = @with_start_tls = nil
+ @disconnected = true
end
def rebind(options={})
unbind(options) if bound?
connect(options)
end
def bind(options={})
+ @bind_tried = true
+
bind_dn = options[:bind_dn] || @bind_dn
try_sasl = options.has_key?(:try_sasl) ? options[:try_sasl] : @try_sasl
if options.has_key?(:allow_anonymous)
allow_anonymous = options[:allow_anonymous]
else
@@ -84,23 +90,31 @@
message = yield if block_given?
message ||= _('All authentication methods for %s exhausted.') % target
raise AuthenticationError, message
end
- bound?
+ @bound = true
+ @bound
end
+ def unbind(options={})
+ yield if @connection and (@bind_tried or bound?)
+ @bind_tried = @bound = false
+ end
+
def bind_as_anonymous(options={})
- operation(options) do
- yield
- end
+ yield
end
def connecting?
!@connection.nil? and !@disconnected
end
+ def bound?
+ connecting? and @bound
+ end
+
def schema(options={})
@schema ||= operation(options) do
base = options[:base]
attrs = options[:attributes]
@@ -162,11 +176,10 @@
end
def delete(targets, options={})
targets = [targets] unless targets.is_a?(Array)
return if targets.empty?
- target = nil
begin
operation(options) do
targets.each do |target|
begin
yield(target)
@@ -291,15 +304,23 @@
passwd
end
def with_timeout(try_reconnect=true, options={}, &block)
+ n_retries = 0
+ retry_limit = options[:retry_limit] || @retry_limit
begin
Timeout.alarm(@timeout, &block)
rescue Timeout::Error => e
@logger.error {_('Requested action timed out.')}
- retry if @retry_on_timeout and try_reconnect and reconnect(options)
+ if @retry_on_timeout and retry_limit < 0 and n_retries <= retry_limit
+ if connecting?
+ retry
+ elsif try_reconnect
+ retry if with_timeout(false, options) {reconnect(options)}
+ end
+ end
@logger.error {e.message}
raise TimeoutError, e.message
end
end
@@ -316,14 +337,11 @@
end
sasl_mechanisms = options[:sasl_mechanisms] || @sasl_mechanisms
sasl_mechanisms.each do |mechanism|
next unless mechanisms.include?(mechanism)
- operation(options) do
- yield(bind_dn, mechanism, sasl_quiet)
- return true if bound?
- end
+ return true if yield(bind_dn, mechanism, sasl_quiet)
end
false
end
def simple_bind(bind_dn, options={})
@@ -341,14 +359,11 @@
_("Can't use empty password for simple bind.")
end
end
begin
- operation(options) do
- yield(bind_dn, passwd)
- bound?
- end
+ yield(bind_dn, passwd)
rescue LdapError::InvalidDnSyntax
raise DistinguishedNameInvalid.new(bind_dn)
rescue LdapError::InvalidCredentials
false
end
@@ -482,11 +497,15 @@
value.gsub(/(?:[()\\\0]|\*\*?)/) do |s|
if s == "*"
s
else
s = "*" if s == "**"
- "\\%02X" % s[0]
+ if s.respond_to?(:getbyte)
+ "\\%02X" % s.getbyte(0)
+ else
+ "\\%02X" % s[0]
+ end
end
end
end
def construct_filter(components, operator=nil)
@@ -542,51 +561,56 @@
retry_limit = options[:retry_limit] || @retry_limit
retry_wait = options[:retry_wait] || @retry_wait
options[:reconnect_attempts] ||= 0
loop do
- unless can_reconnect?(options)
- raise ConnectionError,
- _('Giving up trying to reconnect to LDAP server.')
- end
-
@logger.debug {_('Attempting to reconnect')}
disconnect!
# Reset the attempts if this was forced.
options[:reconnect_attempts] = 0 if force
options[:reconnect_attempts] += 1 if retry_limit >= 0
begin
connect(options)
break
+ rescue AuthenticationError
+ raise
rescue => detail
@logger.error do
_("Reconnect to server failed: %s\n" \
"Reconnect to server failed backtrace:\n" \
"%s") % [detail.exception, detail.backtrace.join("\n")]
end
# Do not loop if forced
raise ConnectionError, detail.message if force
end
+ unless can_reconnect?(options)
+ raise ConnectionError,
+ _('Giving up trying to reconnect to LDAP server.')
+ end
+
# Sleep before looping
sleep retry_wait
end
true
end
def reconnect_if_need(options={})
- reconnect(options) if !connecting? and can_reconnect?(options)
+ return if connecting?
+ with_timeout(false, options) do
+ reconnect(options)
+ end
end
# Determine if we have exceed the retry limit or not.
# True is reconnecting is allowed - False if not.
def can_reconnect?(options={})
retry_limit = options[:retry_limit] || @retry_limit
reconnect_attempts = options[:reconnect_attempts] || 0
- retry_limit < 0 or reconnect_attempts < (retry_limit - 1)
+ retry_limit < 0 or reconnect_attempts <= retry_limit
end
def root_dse_values(key, options={})
dse = root_dse([key], options)[0]
return [] if dse.nil?