Commit 2af3f6a8 authored by Drew Blessing's avatar Drew Blessing Committed by Drew Blessing

Refactor Kerberos simple LDAP linking

Refactor to make code more clear and add tests for the
simple LDAP linking feature.
parent d5232a09
--- ---
title: Add simple_ldap_linking kerberos options to make the mapping between ldap and title: Make mapping between LDAP and Kerberos configurable
kerberos configureable merge_request: 9962
merge_request:
author: Christopher Schenk author: Christopher Schenk
type: added type: added
...@@ -30,23 +30,23 @@ module EE ...@@ -30,23 +30,23 @@ module EE
def find_by_kerberos_principal(principal, adapter) def find_by_kerberos_principal(principal, adapter)
uid, domain = principal.split('@', 2) uid, domain = principal.split('@', 2)
return unless uid && domain return unless uid && domain
return unless allowed_realm?(domain, adapter)
if ::Gitlab.config.kerberos.simple_ldap_linking_allowed_realms.blank? find_by_uid(uid, adapter)
end
# In multi-forest setups, there may be several users with matching def allowed_realm?(domain, adapter)
# uids but differing DNs, so skip adapters configured to connect to return domain.casecmp(domain_from_dn(adapter.config.base)) == 0 unless simple_ldap_linking?
# non-matching domains
return unless domain.casecmp(domain_from_dn(adapter.config.base)) == 0
find_by_uid(uid, adapter) simple_ldap_linking_allowed_realms.select { |realm| domain.casecmp(realm) == 0 }.any?
end
else def simple_ldap_linking_allowed_realms
::Gitlab.config.kerberos.simple_ldap_linking_allowed_realms.each do |realm| ::Gitlab.config.kerberos.simple_ldap_linking_allowed_realms
if domain.casecmp(realm) == 0 end
return find_by_uid(uid, adapter)
end def simple_ldap_linking?
end simple_ldap_linking_allowed_realms.present?
end
end end
# Extracts the rightmost unbroken set of domain components from an # Extracts the rightmost unbroken set of domain components from an
......
...@@ -60,32 +60,63 @@ RSpec.describe Gitlab::Auth::Ldap::Person do ...@@ -60,32 +60,63 @@ RSpec.describe Gitlab::Auth::Ldap::Person do
describe '.find_by_kerberos_principal' do describe '.find_by_kerberos_principal' do
let(:adapter) { ldap_adapter } let(:adapter) { ldap_adapter }
let(:username) { 'foo' } let(:username) { 'foo' }
let(:principal) { username + '@' + kerberos_realm }
let(:ldap_server) { 'ad.example.com' } let(:ldap_server) { 'ad.example.com' }
subject { described_class.find_by_kerberos_principal(principal, adapter) } subject(:ldap_person) { described_class.find_by_kerberos_principal(principal, adapter) }
before do before do
stub_ldap_config(uid: 'sAMAccountName', base: 'ou=foo,dc=' + ldap_server.gsub('.', ',dc=')) stub_ldap_config(uid: 'sAMAccountName', base: 'ou=foo,dc=' + ldap_server.gsub('.', ',dc='))
end end
context 'LDAP server is not for kerberos realm' do context 'when simple LDAP linking is not configured' do
let(:kerberos_realm) { 'kerberos.example.com' } let(:principal) { username + '@' + kerberos_realm }
it 'returns nil without searching' do context 'LDAP server is not for kerberos realm' do
expect(adapter).not_to receive(:user) let(:kerberos_realm) { 'kerberos.example.com' }
is_expected.to be_nil it 'returns nil without searching' do
expect(adapter).not_to receive(:user)
is_expected.to be_nil
end
end
context 'LDAP server is for kerberos realm' do
let(:kerberos_realm) { ldap_server }
it 'searches by configured uid attribute' do
expect(adapter).to receive(:user).with('sAMAccountName', username).and_return(:fake_user)
is_expected.to eq(:fake_user)
end
end end
end end
context 'LDAP server is for kerberos realm' do context 'when simple LDAP linking is enabled' do
let(:kerberos_realm) { ldap_server } let(:allowed_realms) { ['kerberos.example.com', ldap_server] }
before do
stub_config(kerberos: { simple_ldap_linking_allowed_realms: allowed_realms })
end
context 'principal domain matches an allowed realm' do
let(:principal) { "#{username}@#{allowed_realms[0]}" }
it 'searches by configured uid attribute' do
expect(adapter).to receive(:user).with('sAMAccountName', username).and_return(:fake_user)
expect(ldap_person).to eq(:fake_user)
end
end
context 'principal domain does not match an allowed realm' do
let(:principal) { "#{username}@alternate.example.com" }
it 'searches by configured uid attribute' do it 'returns nil without searching' do
expect(adapter).to receive(:user).with('sAMAccountName', username).and_return(:fake_user) expect(adapter).not_to receive(:user)
is_expected.to eq(:fake_user) is_expected.to be_nil
end
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment