lib/chaltron/ldap/connection.rb in chaltron-1.1.7 vs lib/chaltron/ldap/connection.rb in chaltron-2.0.0

- old
+ new

@@ -1,191 +1,193 @@ -require 'net/ldap' -require 'chaltron/ldap/person' +if defined?(Net::LDAP) + require 'net/ldap' + require 'chaltron/ldap/person' -module Chaltron - module LDAP - class Connection - NET_LDAP_ENCRYPTION_METHOD = { - simple_tls: :simple_tls, - start_tls: :start_tls, - plain: nil - }.freeze + module Chaltron + module LDAP + class Connection + NET_LDAP_ENCRYPTION_METHOD = { + simple_tls: :simple_tls, + start_tls: :start_tls, + plain: nil + }.freeze - attr_reader :ldap + attr_reader :ldap - def initialize(params = {}) - @ldap = Net::LDAP.new(adapter_options) - end + def initialize(params = {}) + @ldap = Net::LDAP.new(adapter_options) + end - def auth(login, password) - filter = Net::LDAP::Filter.eq(uid, login) - ldap.bind_as(base: base, filter: filter, password: password) - end + def auth(login, password) + filter = Net::LDAP::Filter.eq(uid, login) + ldap.bind_as(base: base, filter: filter, password: password) + end - def find_by_uid(id) - opts = {} - opts[uid.to_sym] = id - ret = find_user(opts) - end + def find_by_uid(id) + opts = {} + opts[uid.to_sym] = id + ret = find_user(opts) + end - def find_user(*args) - find_users(*args).first - end + def find_user(*args) + find_users(*args).first + end - def ldap_search(*args) - results = ldap.search(*args) - if results.nil? - response = ldap.get_operation_result - unless response.code.zero? - Rails.logger.warn("LDAP search error: #{response.message}") + def ldap_search(*args) + results = ldap.search(*args) + if results.nil? + response = ldap.get_operation_result + unless response.code.zero? + Rails.logger.warn("LDAP search error: #{response.message}") + end + [] + else + results end - [] - else - results end - end - def find_users(args) - return [] if args.empty? - limit = args.delete(:limit) - fields = args.keys + def find_users(args) + return [] if args.empty? + limit = args.delete(:limit) + fields = args.keys - if fields.include?(:dn) - options = { - base: args[:dn], - scope: Net::LDAP::SearchScope_BaseObject - } - else - filters = fields.map do |field| - f = translate_field(field) - Net::LDAP::Filter.eq(f, args[field]) if f + if fields.include?(:dn) + options = { + base: args[:dn], + scope: Net::LDAP::SearchScope_BaseObject + } + else + filters = fields.map do |field| + f = translate_field(field) + Net::LDAP::Filter.eq(f, args[field]) if f + end + options = { + base: base, + filter: filters.inject { |sum, n| Net::LDAP::Filter.join(sum, n) } + } end + options.merge!(size: limit) unless limit.nil? + ldap_search(options).map do |entry| + Chaltron::LDAP::Person.new(entry, uid) if entry.respond_to? uid + end.compact + end + + def find_groups_by_member(entry) options = { - base: base, - filter: filters.inject { |sum, n| Net::LDAP::Filter.join(sum, n) } + base: Chaltron.ldap_group_base || base, + filter: Chaltron.ldap_group_member_filter.call(entry) } + ldap_search(options) end - options.merge!(size: limit) unless limit.nil? - ldap_search(options).map do |entry| - Chaltron::LDAP::Person.new(entry, uid) if entry.respond_to? uid - end.compact - end - def find_groups_by_member(entry) - options = { - base: Chaltron.ldap_group_base || base, - filter: Chaltron.ldap_group_member_filter.call(entry) - } - ldap_search(options) - end + def update_attributes(dn, args) + ldap.modify dn: dn, operations: args.map { |k,v| [:replace, k, v] } + end - def update_attributes(dn, args) - ldap.modify dn: dn, operations: args.map { |k,v| [:replace, k, v] } - end + private - private + def options + Devise.omniauth_configs[:ldap].options + end - def options - Devise.omniauth_configs[:ldap].options - end + def translate_field field + return uid if field.to_sym == :uid + return Chaltron.ldap_field_mappings[field.to_sym] unless Chaltron.ldap_field_mappings[field.to_sym].nil? + field + end - def translate_field field - return uid if field.to_sym == :uid - return Chaltron.ldap_field_mappings[field.to_sym] unless Chaltron.ldap_field_mappings[field.to_sym].nil? - field - end + def adapter_options + opts = { + host: options[:host], + port: options[:port], + encryption: encryption_options, + verbose: true + } + opts.merge!(auth_options) if has_auth? + opts + end - def adapter_options - opts = { - host: options[:host], - port: options[:port], - encryption: encryption_options, - verbose: true - } - opts.merge!(auth_options) if has_auth? - opts - end + def base + options[:base] + end - def base - options[:base] - end + def uid + options[:uid] + end - def uid - options[:uid] - end + def encryption_options + method = translate_method + return unless method + { + method: method, + tls_options: tls_options + } + end - def encryption_options - method = translate_method - return unless method - { - method: method, - tls_options: tls_options - } - end + def translate_method + NET_LDAP_ENCRYPTION_METHOD[options[:encryption]&.to_sym] + end - def translate_method - NET_LDAP_ENCRYPTION_METHOD[options[:encryption]&.to_sym] - end + def tls_options + return @tls_options if defined?(@tls_options) - def tls_options - return @tls_options if defined?(@tls_options) + method = translate_method + return unless method - method = translate_method - return unless method + opts = if options[: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 + # Dup so we don't accidentally overwrite the constant + OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.dup + end - opts = if options[: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 - # Dup so we don't accidentally overwrite the constant - OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.dup - end + opts.merge!(custom_tls_options) - opts.merge!(custom_tls_options) + @tls_options = opts + end - @tls_options = opts - end + def custom_tls_options + return {} unless options['tls_options'] - def custom_tls_options - return {} unless options['tls_options'] + # Dup so we don't overwrite the original value + custom_options = options['tls_options'].dup.delete_if { |_, value| value.nil? || value.blank? } + custom_options.symbolize_keys! - # Dup so we don't overwrite the original value - custom_options = options['tls_options'].dup.delete_if { |_, value| value.nil? || value.blank? } - custom_options.symbolize_keys! - - if custom_options[:cert] - begin - custom_options[:cert] = OpenSSL::X509::Certificate.new(custom_options[:cert]) - rescue OpenSSL::X509::CertificateError => e - Rails.logger.error "LDAP TLS Options 'cert' is invalid for provider #{provider}: #{e.message}" + if custom_options[:cert] + begin + custom_options[:cert] = OpenSSL::X509::Certificate.new(custom_options[:cert]) + rescue OpenSSL::X509::CertificateError => e + Rails.logger.error "LDAP TLS Options 'cert' is invalid for provider #{provider}: #{e.message}" + end end - end - if custom_options[:key] - begin - custom_options[:key] = OpenSSL::PKey.read(custom_options[:key]) - rescue OpenSSL::PKey::PKeyError => e - Rails.logger.error "LDAP TLS Options 'key' is invalid for provider #{provider}: #{e.message}" + if custom_options[:key] + begin + custom_options[:key] = OpenSSL::PKey.read(custom_options[:key]) + rescue OpenSSL::PKey::PKeyError => e + Rails.logger.error "LDAP TLS Options 'key' is invalid for provider #{provider}: #{e.message}" + end end + custom_options end - custom_options - end - def auth_options - { - auth: { - method: :simple, - username: options[:bind_dn], - password: options[:password] + def auth_options + { + auth: { + method: :simple, + username: options[:bind_dn], + password: options[:password] + } } - } - end + end - def has_auth? - options[:password] || options[:bind_dn] + def has_auth? + options[:password] || options[:bind_dn] + end end end end end