lib/omniauth-ldap/adaptor.rb in gitlab_omniauth-ldap-1.2.1 vs lib/omniauth-ldap/adaptor.rb in gitlab_omniauth-ldap-2.0.0
- old
+ new
@@ -11,23 +11,41 @@
class LdapError < StandardError; end
class ConfigurationError < StandardError; end
class AuthenticationError < StandardError; end
class ConnectionError < StandardError; end
- VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :bind_dn, :password, :try_sasl, :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter]
+ VALID_ADAPTER_CONFIGURATION_KEYS = [
+ :hosts, :host, :port, :encryption, :disable_verify_certificates, :bind_dn, :password, :try_sasl,
+ :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter, :ca_file, :ssl_version,
+ # Deprecated
+ :method
+ ]
+
# A list of needed keys. Possible alternatives are specified using sub-lists.
- MUST_HAVE_KEYS = [:host, :port, :method, [:uid, :filter], :base]
+ MUST_HAVE_KEYS = [
+ :base,
+ [:encryption, :method], # :method is deprecated
+ [:hosts, :host],
+ [:hosts, :port],
+ [:uid, :filter]
+ ]
- METHOD = {
+ ENCRYPTION_METHOD = {
+ :simple_tls => :simple_tls,
+ :start_tls => :start_tls,
+ :plain => nil,
+
+ # Deprecated. This mapping aimed to be user-friendly, but only caused
+ # confusion. Better to pass-through the actual `Net::LDAP` encryption type.
:ssl => :simple_tls,
:tls => :start_tls,
- :plain => nil,
}
attr_accessor :bind_dn, :password
attr_reader :connection, :uid, :base, :auth, :filter
+
def self.validate(configuration={})
message = []
MUST_HAVE_KEYS.each do |names|
names = [names].flatten
missing_keys = names.select{|name| configuration[name].nil?}
@@ -35,36 +53,36 @@
message << names.join(' or ')
end
end
raise ArgumentError.new(message.join(",") +" MUST be provided") unless message.empty?
end
+
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
- method = ensure_method(@method)
config = {
- :host => @host,
- :port => @port,
- :encryption => method,
- :base => @base
+ base: @base,
+ hosts: @hosts,
+ host: @host,
+ port: @port,
}
-
@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)
+ @connection.encryption(encryption_options)
end
#:base => "dc=yourcompany, dc=com",
# :filter => "(mail=#{user})",
# :password => psw
@@ -86,17 +104,49 @@
end
result
end
private
- def ensure_method(method)
- method ||= "plain"
- normalized_method = method.to_s.downcase.to_sym
- return METHOD[normalized_method] if METHOD.has_key?(normalized_method)
- available_methods = METHOD.keys.collect {|m| m.inspect}.join(", ")
+ def encryption_options
+ translated_method = translate_method
+
+ {
+ method: translated_method,
+ tls_options: tls_options(translated_method)
+ }
+ end
+
+ 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
+
+ def tls_options(translated_method)
+ return {} if translated_method == nil # (plain)
+
+ tls_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
+ end
+
+ tls_options[:ca_file] = @ca_file if @ca_file
+ tls_options[:ssl_version] = @ssl_version if @ssl_version
+ tls_options
end
def sasl_auths(options={})
auths = []
sasl_mechanisms = options[:sasl_mechanisms] || @sasl_mechanisms