debian-mirror-gitlab/lib/gitlab/ldap/person.rb

121 lines
3.4 KiB
Ruby
Raw Normal View History

2014-09-02 18:07:02 +05:30
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")
2018-03-17 18:26:18 +05:30
InvalidEntryError = Class.new(StandardError)
2015-04-26 12:48:37 +05:30
attr_accessor :entry, :provider
def self.find_by_uid(uid, adapter)
uid = Net::LDAP::Filter.escape(uid)
adapter.user(adapter.config.uid, uid)
2014-09-02 18:07:02 +05:30
end
2015-04-26 12:48:37 +05:30
def self.find_by_dn(dn, adapter)
2014-09-02 18:07:02 +05:30
adapter.user('dn', dn)
end
2018-03-17 18:26:18 +05:30
def self.find_by_email(email, adapter)
email_fields = adapter.config.attributes['email']
adapter.user(email_fields, email)
end
2015-04-26 12:48:37 +05:30
def self.disabled_via_active_directory?(dn, adapter)
2014-09-02 18:07:02 +05:30
adapter.dn_matches_filter?(dn, AD_USER_DISABLED)
end
2017-09-10 17:25:29 +05:30
def self.ldap_attributes(config)
[
2018-03-17 18:26:18 +05:30
'dn',
config.uid,
*config.attributes['name'],
*config.attributes['email'],
*config.attributes['username']
].compact.uniq
end
def self.normalize_dn(dn)
::Gitlab::LDAP::DN.new(dn).to_normalized_s
rescue ::Gitlab::LDAP::DN::FormatError => e
Rails.logger.info("Returning original DN \"#{dn}\" due to error during normalization attempt: #{e.message}")
dn
end
# Returns the UID in a normalized form.
#
# 1. Excess spaces are stripped
# 2. The string is downcased (for case-insensitivity)
def self.normalize_uid(uid)
::Gitlab::LDAP::DN.normalize_value(uid)
rescue ::Gitlab::LDAP::DN::FormatError => e
Rails.logger.info("Returning original UID \"#{uid}\" due to error during normalization attempt: #{e.message}")
uid
2017-09-10 17:25:29 +05:30
end
2015-04-26 12:48:37 +05:30
def initialize(entry, provider)
2014-09-02 18:07:02 +05:30
Rails.logger.debug { "Instantiating #{self.class.name} with LDIF:\n#{entry.to_ldif}" }
@entry = entry
2015-04-26 12:48:37 +05:30
@provider = provider
2014-09-02 18:07:02 +05:30
end
def name
2017-08-17 22:00:37 +05:30
attribute_value(:name).first
2014-09-02 18:07:02 +05:30
end
def uid
2018-03-17 18:26:18 +05:30
entry.public_send(config.uid).first # rubocop:disable GitlabSecurity/PublicSend
2014-09-02 18:07:02 +05:30
end
def username
2018-03-17 18:26:18 +05:30
username = attribute_value(:username)
# Depending on the attribute, multiple values may
# be returned. We need only one for username.
# Ex. `uid` returns only one value but `mail` may
# return an array of multiple email addresses.
[username].flatten.first.tap do |username|
username.downcase! if config.lowercase_usernames
end
2014-09-02 18:07:02 +05:30
end
2015-04-26 12:48:37 +05:30
def email
2017-08-17 22:00:37 +05:30
attribute_value(:email)
2015-04-26 12:48:37 +05:30
end
2018-03-17 18:26:18 +05:30
def dn
self.class.normalize_dn(entry.dn)
end
2014-09-02 18:07:02 +05:30
private
def entry
@entry
end
def config
2015-04-26 12:48:37 +05:30
@config ||= Gitlab::LDAP::Config.new(provider)
2014-09-02 18:07:02 +05:30
end
2017-08-17 22:00:37 +05:30
# 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
2018-03-17 18:26:18 +05:30
entry.public_send(selected_attr) # rubocop:disable GitlabSecurity/PublicSend
2017-08-17 22:00:37 +05:30
end
2014-09-02 18:07:02 +05:30
end
end
end