Welcome to mirror list, hosted at ThFree Co, Russian Federation.

adapter.rb « ldap « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 9100719da875c8000e0bfd47b0b058f0402fe8b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
module Gitlab
  module LDAP
    class Adapter
      attr_reader :provider, :ldap

      def self.open(provider, &block)
        Net::LDAP.open(config(provider).adapter_options) do |ldap|
          block.call(self.new(provider, ldap))
        end
      end

      def self.config(provider)
        Gitlab::LDAP::Config.new(provider)
      end

      def initialize(provider, ldap = nil)
        @provider = provider
        @ldap = ldap || Net::LDAP.new(config.adapter_options)
      end

      def config
        Gitlab::LDAP::Config.new(provider)
      end

      def users(field, value, limit = nil)
        options = user_options(field, value, limit)

        entries = ldap_search(options).select do |entry|
          entry.respond_to? config.uid
        end

        entries.map do |entry|
          Gitlab::LDAP::Person.new(entry, provider)
        end
      end

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

      def dn_matches_filter?(dn, filter)
        ldap_search(base: dn,
                    filter: filter,
                    scope: Net::LDAP::SearchScope_BaseObject,
                    attributes: %w{dn}).any?
      end

      def ldap_search(*args)
        # Net::LDAP's `time` argument doesn't work. Use Ruby `Timeout` instead.
        Timeout.timeout(config.timeout) do
          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
        end
      rescue Timeout::Error
        Rails.logger.warn("LDAP search timed out after #{config.timeout} seconds")
        []
      end

      private

      def user_options(field, value, limit)
        options = { attributes: %W(#{config.uid} cn mail dn) }
        options[:size] = limit if limit

        if field.to_sym == :dn
          options[:base] = value
          options[:scope] = Net::LDAP::SearchScope_BaseObject
          options[:filter] = user_filter
        else
          options[:base] = config.base
          options[:filter] = user_filter(Net::LDAP::Filter.eq(field, value))
        end

        options
      end

      def user_filter(filter = nil)
        if config.user_filter.present?
          user_filter = Net::LDAP::Filter.construct(config.user_filter)
        end

        if user_filter && filter
          Net::LDAP::Filter.join(filter, user_filter)
        elsif user_filter
          user_filter
        else
          filter
        end
      end
    end
  end
end