summaryrefslogtreecommitdiff
path: root/lib/gitlab/ldap/adapter.rb
blob: e36616f0e666833ef64c54a21a26b7d1d8d35e70 (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
104
105
106
107
module Gitlab
  module LDAP
    class Adapter
      attr_reader :ldap

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

      def self.config
        Gitlab.config.ldap
      end

      def self.adapter_options
        encryption = config['method'].to_s == 'ssl' ? :simple_tls : nil

        options = {
          host: config['host'],
          port: config['port'],
          encryption: encryption
        }

        auth_options = {
          auth: {
            method: :simple,
            username: config['bind_dn'],
            password: config['password']
          }
        }

        if config['password'] || config['bind_dn']
          options.merge!(auth_options)
        end
        options
      end


      def initialize(ldap=nil)
        @ldap = ldap || Net::LDAP.new(self.class.adapter_options)
      end

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

        if config['user_filter'].present?
          user_filter = Net::LDAP::Filter.construct(config['user_filter'])

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

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

        entries.map do |entry|
          Gitlab::LDAP::Person.new(entry)
        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)
        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

      private

      def config
        @config ||= self.class.config
      end
    end
  end
end