From d4dfd750b722071c9b8f1ad4a2b7b59f82656966 Mon Sep 17 00:00:00 2001 From: Lars Kruse Date: Wed, 8 Sep 2021 12:02:59 +0200 Subject: [PATCH] Closes #3225 - LDAP: apply user filter during auth on bind. --- lib/ldap/user.rb | 3 +- spec/lib/ldap/user_spec.rb | 56 ++++++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/lib/ldap/user.rb b/lib/ldap/user.rb index e5db465b6..311a3e5fa 100644 --- a/lib/ldap/user.rb +++ b/lib/ldap/user.rb @@ -95,7 +95,7 @@ class Ldap def valid?(username, password) bind_success = @ldap.connection.bind_as( base: @ldap.base_dn, - filter: "(#{login_attribute}=#{username})", + filter: @user_filter ? "(&(#{login_attribute}=#{username})#{@user_filter})" : "(#{login_attribute}=#{username})", password: password ) @@ -179,6 +179,7 @@ class Ldap @uid_attribute = config[:uid_attribute] @filter = config[:filter] + @user_filter = config[:user_filter] end end end diff --git a/spec/lib/ldap/user_spec.rb b/spec/lib/ldap/user_spec.rb index 38bfe200b..8e2f1d16f 100644 --- a/spec/lib/ldap/user_spec.rb +++ b/spec/lib/ldap/user_spec.rb @@ -90,32 +90,48 @@ RSpec.describe Ldap::User do describe '#valid?' do + shared_examples 'validates credentials' do + it 'validates username and password' do + connection = double + allow(mocked_ldap).to receive(:connection).and_return(connection) + + build(:ldap_entry) + + allow(mocked_ldap).to receive(:base_dn) + allow(connection).to receive(:bind_as).and_return(true) + + expect(instance.valid?('example_username', 'password')).to be true + end + + it 'fails for invalid credentials' do + connection = double + allow(mocked_ldap).to receive(:connection).and_return(connection) + + build(:ldap_entry) + + allow(mocked_ldap).to receive(:base_dn) + allow(connection).to receive(:bind_as).and_return(false) + + expect(instance.valid?('example_username', 'wrong_password')).to be false + end + end + it 'responds to #valid?' do expect(instance).to respond_to(:valid?) end - it 'validates username and password' do - connection = double - allow(mocked_ldap).to receive(:connection).and_return(connection) + it_behaves_like 'validates credentials' - build(:ldap_entry) + context 'with a user_filter inside of the config' do + let(:initialization_config) do + { + uid_attribute: 'objectguid', + filter: '(objectClass=user)', + user_filter: '(cn=example)' + } + end - allow(mocked_ldap).to receive(:base_dn) - allow(connection).to receive(:bind_as).and_return(true) - - expect(instance.valid?('example_username', 'password')).to be true - end - - it 'fails for invalid credentials' do - connection = double - allow(mocked_ldap).to receive(:connection).and_return(connection) - - build(:ldap_entry) - - allow(mocked_ldap).to receive(:base_dn) - allow(connection).to receive(:bind_as).and_return(false) - - expect(instance.valid?('example_username', 'wrong_password')).to be false + it_behaves_like 'validates credentials' end end