class OmniAuth::LDAP::Adaptor

Constants

ENCRYPTION_METHOD
MUST_HAVE_KEYS

A list of needed keys. Possible alternatives are specified using sub-lists.

VALID_ADAPTER_CONFIGURATION_KEYS

Attributes

auth[R]
base[R]
bind_dn[RW]
connection[R]
filter[R]
password[RW]
uid[R]

Public Class Methods

new(configuration={}) click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 61
def initialize(configuration={})
  Adaptor.validate(configuration)
  @configuration = configuration.dup
  @configuration[:allow_anonymous] ||= false
  @logger = @configuration.delete(:logger)
  VALID_ADAPTER_CONFIGURATION_KEYS.each do |name|
    instance_variable_set("@#{name}", @configuration[name])
  end
  config = {
    base: @base,
    hosts: @hosts,
    host: @host,
    port: @port,
    encryption: encryption_options
  }
  @bind_method = @try_sasl ? :sasl : (@allow_anonymous||!@bind_dn||!@password ? :anonymous : :simple)


  @auth = sasl_auths({:username => @bind_dn, :password => @password}).first if @bind_method == :sasl
  @auth ||= { :method => @bind_method,
              :username => @bind_dn,
              :password => @password
            }
  config[:auth] = @auth
  @connection = Net::LDAP.new(config)
end
validate(configuration={}) click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 49
def self.validate(configuration={})
  message = []
  MUST_HAVE_KEYS.each do |names|
    names = [names].flatten
    missing_keys = names.select{|name| configuration[name].nil?}
    if missing_keys == names
      message << names.join(' or ')
    end
  end
  raise ArgumentError.new(message.join(",") +" MUST be provided") unless message.empty?
end

Public Instance Methods

bind_as(args = {}) click to toggle source

:base => “dc=yourcompany, dc=com”,

:filter => "(mail=#{user})",
:password => psw
# File lib/omniauth-ldap/adaptor.rb, line 91
def bind_as(args = {})
  result = false
  @connection.open do |me|
    rs = me.search args
    if rs and rs.first and dn = rs.first.dn
      password = args[:password]
      method = args[:method] || @method
      password = password.call if password.respond_to?(:call)
      if method == 'sasl'
      result = rs.first if me.bind(sasl_auths({:username => dn, :password => password}).first)
      else
      result = rs.first if me.bind(:method => :simple, :username => dn,
                          :password => password)
      end
    end
  end
  result
end

Private Instance Methods

default_options() click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 203
def default_options
  if @disable_verify_certificates
    # It is important to explicitly set verify_mode for two reasons:
    # 1. The behavior of OpenSSL is undefined when verify_mode is not set.
    # 2. The net-ldap gem implementation verifies the certificate hostname
    #    unless verify_mode is set to VERIFY_NONE.
    { verify_mode: OpenSSL::SSL::VERIFY_NONE }
  else
    OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.dup
  end
end
encryption_options() click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 112
def encryption_options
  translated_method = translate_method
  return nil unless translated_method

  {
    method: translated_method,
    tls_options: tls_options(translated_method)
  }
end
sanitize_hash_values(hash) click to toggle source

Removes keys that have blank values

This gem may not always be in the context of Rails so we do this rather than `.blank?`.

# File lib/omniauth-ldap/adaptor.rb, line 219
def sanitize_hash_values(hash)
  hash.delete_if do |_, value|
    value.nil? ||
    (value.is_a?(String) && value !~ /\S/)
  end
end
sasl_auths(options={}) click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 156
def sasl_auths(options={})
  auths = []
  sasl_mechanisms = options[:sasl_mechanisms] || @sasl_mechanisms
  sasl_mechanisms.each do |mechanism|
    normalized_mechanism = mechanism.downcase.gsub(/-/, '_')
    sasl_bind_setup = "sasl_bind_setup_#{normalized_mechanism}"
    next unless respond_to?(sasl_bind_setup, true)
    initial_credential, challenge_response = send(sasl_bind_setup, options)
    auths << {
      :method => :sasl,
      :initial_credential => initial_credential,
      :mechanism => mechanism,
      :challenge_response => challenge_response
    }
  end
  auths
end
sasl_bind_setup_digest_md5(options) click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 174
def sasl_bind_setup_digest_md5(options)
  bind_dn = options[:username]
  initial_credential = ""
  challenge_response = Proc.new do |cred|
    pref = SASL::Preferences.new :digest_uri => "ldap/#{@host}", :username => bind_dn, :has_password? => true, :password => options[:password]
    sasl = SASL.new("DIGEST-MD5", pref)
    response = sasl.receive("challenge", cred)
    response[1]
  end
  [initial_credential, challenge_response]
end
sasl_bind_setup_gss_spnego(options) click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 186
def sasl_bind_setup_gss_spnego(options)
  bind_dn = options[:username]
  psw = options[:password]
  raise LdapError.new( "invalid binding information" ) unless (bind_dn && psw)

  nego = proc {|challenge|
    t2_msg = Net::NTLM::Message.parse( challenge )
    bind_dn, domain = bind_dn.split('\\').reverse
    t2_msg.target_name = Net::NTLM::encode_utf16le(domain) if domain
    t3_msg = t2_msg.response( {:user => bind_dn, :password => psw}, {:ntlmv2 => true} )
    t3_msg.serialize
  }
  [Net::NTLM::Message::Type1.new.serialize, nego]
end
symbolize_hash_keys(hash) click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 226
def symbolize_hash_keys(hash)
  hash.keys.each do |key|
    hash[key.to_sym] = hash[key]
  end

  hash
end
tls_options(translated_method) click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 136
def tls_options(translated_method)
  return {} if translated_method == nil # (plain)

  options = default_options

  if @tls_options
    # Prevent blank config values from overwriting SSL defaults
    configured_options = sanitize_hash_values(@tls_options)
    configured_options = symbolize_hash_keys(configured_options)

    options.merge!(configured_options)
  end

  # Retain backward compatibility until deprecated configs are removed.
  options[:ca_file] = @ca_file if @ca_file
  options[:ssl_version] = @ssl_version if @ssl_version

  options
end
translate_method() click to toggle source
# File lib/omniauth-ldap/adaptor.rb, line 122
def translate_method
  method = @encryption || @method
  method ||= "plain"
  normalized_method = method.to_s.downcase.to_sym

  unless ENCRYPTION_METHOD.has_key?(normalized_method)
    available_methods = ENCRYPTION_METHOD.keys.collect {|m| m.inspect}.join(", ")
    format = "%s is not one of the available connect methods: %s"
    raise ConfigurationError, format % [method.inspect, available_methods]
  end

  ENCRYPTION_METHOD[normalized_method]
end