summaryrefslogtreecommitdiff
path: root/lib/gitlab/ldap/person.rb
blob: 9a6f7827b16a633dff8aafb8501bdd700afa57a9 (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
module Gitlab
  module LDAP
    class Person
      # Active Directory-specific LDAP filter that checks if bit 2 of the
      # userAccountControl attribute is set.
      # Source: http://ctogonewild.com/2009/09/03/bitmask-searches-in-ldap/
      AD_USER_DISABLED = Net::LDAP::Filter.ex("userAccountControl:1.2.840.113556.1.4.803", "2")

      attr_accessor :entry, :provider

      def self.find_by_uid(uid, adapter)
        uid = Net::LDAP::Filter.escape(uid)
        adapter.user(adapter.config.uid, uid)
      end

      def self.find_by_dn(dn, adapter)
        adapter.user('dn', dn)
      end

      def self.find_by_email(email, adapter)
        email_fields = adapter.config.attributes['email']

        adapter.user(email_fields, email)
      end

      def self.disabled_via_active_directory?(dn, adapter)
        adapter.dn_matches_filter?(dn, AD_USER_DISABLED)
      end

      def self.ldap_attributes(config)
        [
          'dn', # Used in `dn`
          config.uid, # Used in `uid`
          *config.attributes['name'], # Used in `name`
          *config.attributes['email'] # Used in `email`
        ]
      end

      def initialize(entry, provider)
        Rails.logger.debug { "Instantiating #{self.class.name} with LDIF:\n#{entry.to_ldif}" }
        @entry = entry
        @provider = provider
      end

      def name
        attribute_value(:name).first
      end

      def uid
        entry.public_send(config.uid).first # rubocop:disable GitlabSecurity/PublicSend
      end

      def username
        uid
      end

      def email
        attribute_value(:email)
      end

      delegate :dn, to: :entry

      private

      def entry
        @entry
      end

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

      # Using the LDAP attributes configuration, find and return the first
      # attribute with a value. For example, by default, when given 'email',
      # this method looks for 'mail', 'email' and 'userPrincipalName' and
      # returns the first with a value.
      def attribute_value(attribute)
        attributes = Array(config.attributes[attribute.to_s])
        selected_attr = attributes.find { |attr| entry.respond_to?(attr) }

        return nil unless selected_attr

        entry.public_send(selected_attr) # rubocop:disable GitlabSecurity/PublicSend
      end
    end
  end
end