From 119783d48d62e630aab210e24804721fc71ab6f6 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Wed, 17 Jan 2018 11:26:41 +0100 Subject: [PATCH] Fixed issue #1751 - Loss of LDAP group assignment is not reflected in Zammad role assignment. --- lib/sequencer/sequence.rb | 1 + lib/sequencer/sequence/import/ldap/user.rb | 1 + .../ldap/user/attributes/role_ids/signup.rb | 35 ++++ .../sequence/import/ldap/users_spec.rb | 194 ++++++++++++++++++ 4 files changed, 231 insertions(+) create mode 100644 lib/sequencer/unit/import/ldap/user/attributes/role_ids/signup.rb create mode 100644 spec/lib/sequencer/sequence/import/ldap/users_spec.rb diff --git a/lib/sequencer/sequence.rb b/lib/sequencer/sequence.rb index 906ee2ba3..7e4e32fdc 100644 --- a/lib/sequencer/sequence.rb +++ b/lib/sequencer/sequence.rb @@ -2,6 +2,7 @@ require 'sequencer/mixin/prefixed_constantize' class Sequencer class Sequence + include ::Mixin::RequiredSubPaths extend ::Sequencer::Mixin::PrefixedConstantize PREFIX = 'Sequencer::Sequence::'.freeze diff --git a/lib/sequencer/sequence/import/ldap/user.rb b/lib/sequencer/sequence/import/ldap/user.rb index 58a0f2ca3..9a3c0ad8f 100644 --- a/lib/sequencer/sequence/import/ldap/user.rb +++ b/lib/sequencer/sequence/import/ldap/user.rb @@ -22,6 +22,7 @@ class Sequencer 'Import::Ldap::User::Lookup::Attributes', 'Import::Ldap::User::Attributes::RoleIds::Dn', 'Import::Ldap::User::Attributes::RoleIds::Unassigned', + 'Import::Ldap::User::Attributes::RoleIds::Signup', 'Import::Common::Model::Associations::Extract', 'Import::Ldap::User::Attributes::Static', 'Import::Common::Model::Attributes::AddByIds', diff --git a/lib/sequencer/unit/import/ldap/user/attributes/role_ids/signup.rb b/lib/sequencer/unit/import/ldap/user/attributes/role_ids/signup.rb new file mode 100644 index 000000000..484c97a43 --- /dev/null +++ b/lib/sequencer/unit/import/ldap/user/attributes/role_ids/signup.rb @@ -0,0 +1,35 @@ +class Sequencer + class Unit + module Import + module Ldap + module User + module Attributes + module RoleIds + class Signup < Sequencer::Unit::Base + prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action + include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped + + skip_any_action + + uses :mapped + + def process + # return if a mapping entry was found + return if mapped[:role_ids].present? + + # LDAP is the leading source if + # a mapping entry is present + provide_mapped do + { + role_ids: Role.signup_roles.map(&:id) + } + end + end + end + end + end + end + end + end + end +end diff --git a/spec/lib/sequencer/sequence/import/ldap/users_spec.rb b/spec/lib/sequencer/sequence/import/ldap/users_spec.rb new file mode 100644 index 000000000..6e32ca609 --- /dev/null +++ b/spec/lib/sequencer/sequence/import/ldap/users_spec.rb @@ -0,0 +1,194 @@ +require 'rails_helper' + +RSpec.describe ::Sequencer::Sequence::Import::Ldap::Users, sequencer: :sequence do + + context 'lost group assignment' do + + context 'config "unassigned_users": "skip_sync"' do + + it 'disables user' do + + user_entry = build(:ldap_entry) + user_entry['objectguid'] = ['user1337'] + user_entry['samaccountname'] = ['login123'] + user_entry['first_name'] = ['Hans'] + + group_entry = build(:ldap_entry) + group_entry['member'] = [user_entry.dn] + + payload = { + ldap_config: { + user_filter: 'user=filter', + group_role_map: { + group_entry.dn => [1, 2] + }, + user_attributes: { + 'first_name' => 'firstname', + }, + user_uid: 'objectguid', + unassigned_users: 'skip_sync', + } + } + + import_job = build_stubbed(:import_job, name: 'Import::Ldap', payload: payload) + + connection = double( + host: 'example.com', + port: 1337, + ssl: true, + base_dn: 'test' + ) + + # LDAP::Group + expect(connection).to receive(:search).and_yield(group_entry) + expect(connection).to receive(:entries?).and_return(true) + + # Sequencer::Unit::Import::Ldap::Users::Total + expect(connection).to receive(:count).and_return(1) + + # Sequencer::Unit::Import::Ldap::Users::SubSequence + expect(connection).to receive(:search).and_yield(user_entry) + + expect do + process( + ldap_connection: connection, + import_job: import_job, + ) + end.to change { + User.count + }.by(1) + + imported_user = User.last + + expect(imported_user.active).to be true + + connection = double( + host: 'example.com', + port: 1337, + ssl: true, + base_dn: 'test' + ) + + group_entry['member'] = ['some.other.dn'] + + # LDAP::Group + expect(connection).to receive(:search).and_yield(group_entry) + expect(connection).to receive(:entries?).and_return(true) + + # Sequencer::Unit::Import::Ldap::Users::Total + # cached + # expect(connection).to receive(:count).and_return(1) + + # Sequencer::Unit::Import::Ldap::Users::SubSequence + expect(connection).to receive(:search).and_yield(user_entry) + + expect do + process( + ldap_connection: connection, + import_job: import_job, + ) + end.not_to change { + User.count + } + + imported_user.reload + + expect(imported_user.active).to be false + end + end + + context 'config "unassigned_users": nil / "sigup_roles"' do + + it 'assigns signup roles' do + + user_entry = build(:ldap_entry) + user_entry['objectguid'] = ['user1337'] + user_entry['samaccountname'] = ['login123'] + user_entry['first_name'] = ['Hans'] + + group_entry = build(:ldap_entry) + group_entry['member'] = [user_entry.dn] + + agent_admin_role_ids = [1, 2] + + payload = { + ldap_config: { + user_filter: 'user=filter', + group_role_map: { + group_entry.dn => agent_admin_role_ids + }, + user_attributes: { + 'first_name' => 'firstname', + }, + user_uid: 'objectguid', + } + } + + import_job = build_stubbed(:import_job, name: 'Import::Ldap', payload: payload) + + connection = double( + host: 'example.com', + port: 1337, + ssl: true, + base_dn: 'test' + ) + + # LDAP::Group + expect(connection).to receive(:search).and_yield(group_entry) + expect(connection).to receive(:entries?).and_return(true) + + # Sequencer::Unit::Import::Ldap::Users::Total + expect(connection).to receive(:count).and_return(1) + + # Sequencer::Unit::Import::Ldap::Users::SubSequence + expect(connection).to receive(:search).and_yield(user_entry) + + expect do + process( + ldap_connection: connection, + import_job: import_job, + ) + end.to change { + User.count + }.by(1) + + imported_user = User.last + + expect(imported_user.role_ids).to eq(agent_admin_role_ids) + + connection = double( + host: 'example.com', + port: 1337, + ssl: true, + base_dn: 'test' + ) + + group_entry['member'] = ['some.other.dn'] + + # LDAP::Group + expect(connection).to receive(:search).and_yield(group_entry) + expect(connection).to receive(:entries?).and_return(true) + + # Sequencer::Unit::Import::Ldap::Users::Total + # cached + # expect(connection).to receive(:count).and_return(1) + + # Sequencer::Unit::Import::Ldap::Users::SubSequence + expect(connection).to receive(:search).and_yield(user_entry) + + expect do + process( + ldap_connection: connection, + import_job: import_job, + ) + end.not_to change { + User.count + } + + imported_user.reload + + expect(imported_user.roles).to eq(Role.signup_roles) + end + end + end +end