BigW Consortium Gitlab

adapter.rb 2.4 KB
Newer Older
1 2 3
module Gitlab
  module LDAP
    class Adapter
4
      attr_reader :provider, :ldap
5

6 7 8
      def self.open(provider, &block)
        Net::LDAP.open(config(provider).adapter_options) do |ldap|
          block.call(self.new(provider, ldap))
9 10 11
        end
      end

12 13
      def self.config(provider)
        Gitlab::LDAP::Config.new(provider)
14 15
      end

16
      def initialize(provider, ldap = nil)
17 18
        @provider = provider
        @ldap = ldap || Net::LDAP.new(config.adapter_options)
19 20
      end

21 22
      def config
        Gitlab::LDAP::Config.new(provider)
23 24
      end

25
      def users(field, value, limit = nil)
26 27
        if field.to_sym == :dn
          options = {
28 29
            base: value,
            scope: Net::LDAP::SearchScope_BaseObject
30 31 32
          }
        else
          options = {
33
            base: config.base,
34 35 36 37
            filter: Net::LDAP::Filter.eq(field, value)
          }
        end

38 39
        if config.user_filter.present?
          user_filter = Net::LDAP::Filter.construct(config.user_filter)
40 41 42 43 44 45 46 47

          options[:filter] = if options[:filter]
                               Net::LDAP::Filter.join(options[:filter], user_filter)
                             else
                               user_filter
                             end
        end

48 49 50 51
        if limit.present?
          options.merge!(size: limit)
        end

52
        entries = ldap_search(options).select do |entry|
53 54 55 56
          entry.respond_to? config.uid
        end

        entries.map do |entry|
57
          Gitlab::LDAP::Person.new(entry, provider)
58 59 60 61 62 63 64
        end
      end

      def user(*args)
        users(*args).first
      end

65
      def dn_matches_filter?(dn, filter)
66 67 68 69
        ldap_search(base: dn,
                    filter: filter,
                    scope: Net::LDAP::SearchScope_BaseObject,
                    attributes: %w{dn}).any?
70 71
      end

72
      def ldap_search(*args)
73 74 75
        # Net::LDAP's `time` argument doesn't work. Use Ruby `Timeout` instead.
        Timeout.timeout(config.timeout) do
          results = ldap.search(*args)
76

77 78
          if results.nil?
            response = ldap.get_operation_result
79

80 81 82
            unless response.code.zero?
              Rails.logger.warn("LDAP search error: #{response.message}")
            end
83

84 85 86 87
            []
          else
            results
          end
88
        end
89 90 91
      rescue Timeout::Error
        Rails.logger.warn("LDAP search timed out after #{config.timeout} seconds")
        []
92
      end
93 94 95
    end
  end
end