diff --git a/lib/gitlab/ldap/auth_hash.rb b/lib/gitlab/ldap/auth_hash.rb index bf4dd9542d5d4aea9ec687ddaf8182176b5b7c7a..95378e5a7693039bbc676de71fceb1dad0d6a4b0 100644 --- a/lib/gitlab/ldap/auth_hash.rb +++ b/lib/gitlab/ldap/auth_hash.rb @@ -25,7 +25,7 @@ def get_info(key) end def get_raw(key) - auth_hash.extra[:raw_info][key] + auth_hash.extra[:raw_info][key] if auth_hash.extra end def ldap_config diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb index e9e20af5eebbd3705a4260e731e2b476bdb9bdd6..f1e29d479e000d7c02246debf23c619ec2a3c7bd 100644 --- a/lib/gitlab/ldap/config.rb +++ b/lib/gitlab/ldap/config.rb @@ -116,7 +116,7 @@ def block_auto_created_users end def attributes - options['attributes'] + default_attributes.merge(options['attributes']) end def timeout @@ -143,6 +143,16 @@ def name_proc end end + def default_attributes + { + 'username' => %w(uid userid sAMAccountName), + 'email' => %w(mail email userPrincipalName), + 'name' => 'cn', + 'first_name' => 'givenName', + 'last_name' => 'sn' + } + end + protected def base_options diff --git a/lib/gitlab/ldap/person.rb b/lib/gitlab/ldap/person.rb index 7a039d6c18d4b52f6adb934ecec912f7c8c94096..933091b48b60ee25b91e0266e0d2cb97f82f2d1a 100644 --- a/lib/gitlab/ldap/person.rb +++ b/lib/gitlab/ldap/person.rb @@ -30,7 +30,7 @@ def initialize(entry, provider) end def name - entry.cn.first + attribute_value(:name).first end def uid @@ -42,7 +42,7 @@ def username end def email - entry.try(:mail) + attribute_value(:email) end def dn @@ -58,6 +58,19 @@ def entry 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) + end end end end diff --git a/spec/lib/gitlab/ldap/config_spec.rb b/spec/lib/gitlab/ldap/config_spec.rb index cab52e79d0772ae98beafc181ff685e9020385d8..640faab2f75c1c3fd7ab800e4fbf2f9b9b1bb471 100644 --- a/spec/lib/gitlab/ldap/config_spec.rb +++ b/spec/lib/gitlab/ldap/config_spec.rb @@ -129,4 +129,27 @@ expect(config.has_auth?).to be_falsey end end + + describe '#attributes' do + it 'uses default attributes when no custom attributes are configured' do + expect(config.attributes).to eq(config.default_attributes) + end + + it 'merges the configuration attributes with default attributes' do + stub_ldap_config( + options: { + 'attributes' => { + 'username' => %w(sAMAccountName), + 'email' => %w(userPrincipalName) + } + } + ) + + expect(config.attributes).to include({ + 'username' => %w(sAMAccountName), + 'email' => %w(userPrincipalName), + 'name' => 'cn' + }) + end + end end diff --git a/spec/lib/gitlab/ldap/person_spec.rb b/spec/lib/gitlab/ldap/person_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..9a556cde5d56bc9872eb7f0637c38ce6735a97cc --- /dev/null +++ b/spec/lib/gitlab/ldap/person_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe Gitlab::LDAP::Person do + include LdapHelpers + + let(:entry) { ldap_user_entry('john.doe') } + + before do + stub_ldap_config( + options: { + 'attributes' => { + 'name' => 'cn', + 'email' => %w(mail email userPrincipalName) + } + } + ) + end + + describe '#name' do + it 'uses the configured name attribute and handles values as an array' do + name = 'John Doe' + entry['cn'] = [name] + person = Gitlab::LDAP::Person.new(entry, 'ldapmain') + + expect(person.name).to eq(name) + end + end + + describe '#email' do + it 'returns the value of mail, if present' do + mail = 'john@example.com' + entry['mail'] = mail + person = Gitlab::LDAP::Person.new(entry, 'ldapmain') + + expect(person.email).to eq([mail]) + end + + it 'returns the value of userPrincipalName, if mail and email are not present' do + user_principal_name = 'john.doe@example.com' + entry['userPrincipalName'] = user_principal_name + person = Gitlab::LDAP::Person.new(entry, 'ldapmain') + + expect(person.email).to eq([user_principal_name]) + end + end +end