Prevent LDAP sync from needlessly deactivating inactive users (fixes #2256)
This commit is contained in:
parent
bfccecc012
commit
58a8c047bb
4 changed files with 115 additions and 5 deletions
|
@ -27,7 +27,7 @@ class Sequencer
|
||||||
|
|
||||||
# always returns true
|
# always returns true
|
||||||
def log_associations_error
|
def log_associations_error
|
||||||
return true if %i[failed deactivated].include?(action)
|
return true if %i[skipped failed deactivated].include?(action)
|
||||||
|
|
||||||
logger.error { 'associations cannot be nil' } if associations.nil?
|
logger.error { 'associations cannot be nil' } if associations.nil?
|
||||||
true
|
true
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Sequencer
|
||||||
|
|
||||||
skip_any_action
|
skip_any_action
|
||||||
|
|
||||||
uses :resource, :dn_roles, :ldap_config, :mapped
|
uses :dn_roles, :ldap_config, :mapped, :instance
|
||||||
provides :action
|
provides :action
|
||||||
|
|
||||||
def process
|
def process
|
||||||
|
@ -25,9 +25,7 @@ class Sequencer
|
||||||
# if unassigned users should not get skipped
|
# if unassigned users should not get skipped
|
||||||
return if ldap_config[:unassigned_users] != 'skip_sync'
|
return if ldap_config[:unassigned_users] != 'skip_sync'
|
||||||
|
|
||||||
instance = state.optional(:instance)
|
if instance&.active
|
||||||
|
|
||||||
if instance.present?
|
|
||||||
# deactivate instance if role assignment is lost
|
# deactivate instance if role assignment is lost
|
||||||
instance.update!(active: false)
|
instance.update!(active: false)
|
||||||
state.provide(:action, :deactivated)
|
state.provide(:action, :deactivated)
|
||||||
|
|
|
@ -56,6 +56,20 @@ RSpec.describe Sequencer::Unit::Import::Common::Model::Associations::Assign, seq
|
||||||
let(:instance) { create(:user) }
|
let(:instance) { create(:user) }
|
||||||
let(:associations) { nil }
|
let(:associations) { nil }
|
||||||
|
|
||||||
|
context 'and `action == :skipped`' do
|
||||||
|
let(:action) { :skipped }
|
||||||
|
|
||||||
|
it 'makes no changes' do
|
||||||
|
allow(Rails.logger).to receive(:error).and_call_original
|
||||||
|
|
||||||
|
provided = process(parameters)
|
||||||
|
|
||||||
|
expect(Rails.logger).not_to have_received(:error)
|
||||||
|
expect(provided).to include(action: action)
|
||||||
|
expect(instance.changed?).to be(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'and `action == :failed`' do
|
context 'and `action == :failed`' do
|
||||||
let(:action) { :failed }
|
let(:action) { :failed }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Sequencer::Unit::Import::Ldap::User::Attributes::RoleIds::Unassigned, sequencer: :unit do
|
||||||
|
let(:subject) { process(parameters) }
|
||||||
|
|
||||||
|
let(:parameters) do
|
||||||
|
{ resource: resource,
|
||||||
|
dn_roles: dn_roles,
|
||||||
|
ldap_config: ldap_config,
|
||||||
|
mapped: mapped,
|
||||||
|
instance: instance }
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:resource) do
|
||||||
|
{ dn: 'uid=jane,ou=People,dc=example,dc=org',
|
||||||
|
uid: 'jane_doe',
|
||||||
|
sn: 'Doe',
|
||||||
|
givenname: 'Jane' }.with_indifferent_access
|
||||||
|
end
|
||||||
|
|
||||||
|
# this sequencer unit only runs when this parameter is PRESENT
|
||||||
|
let(:dn_roles) do
|
||||||
|
{ 'uid=john,ou=people,dc=example,dc=org' => [1] }.with_indifferent_access
|
||||||
|
end
|
||||||
|
|
||||||
|
# this sequencer unit only runs when this parameter's "unassigned_users" key is "skip_sync"
|
||||||
|
let(:ldap_config) do
|
||||||
|
{ unassigned_users: 'skip_sync' }.with_indifferent_access
|
||||||
|
end
|
||||||
|
|
||||||
|
# this sequencer unit only runs when this parameter's "role_ids" key is BLANK
|
||||||
|
let(:mapped) do
|
||||||
|
{ firstname: 'Jane',
|
||||||
|
lastname: 'Doe',
|
||||||
|
login: 'jane_doe' }.with_indifferent_access
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:instance) { create(:agent_user, mapped) }
|
||||||
|
|
||||||
|
context 'when user exists from previous import' do
|
||||||
|
context 'and is active' do
|
||||||
|
before { instance.update(active: true) }
|
||||||
|
|
||||||
|
it 'deactivates user (with action: :deactivated)' do
|
||||||
|
expect(subject).to include(action: :deactivated)
|
||||||
|
expect(instance.reload.active).to be(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and is inactive' do
|
||||||
|
before { instance.update(active: false) }
|
||||||
|
|
||||||
|
it 'skips user (with action: :skipped)' do
|
||||||
|
expect(subject).to include(action: :skipped)
|
||||||
|
expect(instance.reload.active).to be(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user has not been imported yet' do
|
||||||
|
let(:instance) { nil }
|
||||||
|
|
||||||
|
it 'skips user (with action: :skipped)' do
|
||||||
|
expect(subject).to include(action: :skipped)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'parameters' do
|
||||||
|
before { allow(instance).to receive(:update).and_call_original }
|
||||||
|
|
||||||
|
context 'without :dn_roles (hash map of LDAP DNs ↔ Zammad role IDs for ALL USERS)' do
|
||||||
|
before { parameters[:dn_roles].clear }
|
||||||
|
|
||||||
|
it 'skips user (with NO action)' do
|
||||||
|
expect(subject).to include(action: nil)
|
||||||
|
expect(instance).not_to have_received(:update)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with :mapped[:role_ids] (hash map of LDAP attributes ↔ Zammad attributes for GIVEN USER)' do
|
||||||
|
before { parameters[:mapped].merge!(role_ids: [2]) }
|
||||||
|
|
||||||
|
it 'skips user (with NO action)' do
|
||||||
|
expect(subject).to include(action: nil)
|
||||||
|
expect(instance).not_to have_received(:update)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when :ldap_config[:unassigned_users] != "skip_sync"' do
|
||||||
|
before { parameters[:ldap_config].merge!(unassigned_users: 'sigup_roles') }
|
||||||
|
|
||||||
|
it 'skips user (with NO action)' do
|
||||||
|
expect(subject).to include(action: nil)
|
||||||
|
expect(instance).not_to have_received(:update)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue