From 2d54e12be9b49b267687e3ac3fee05fd22c11a73 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Tue, 22 Nov 2022 16:14:38 -0600 Subject: [PATCH] Audit Group SAML extern_uid changes We recently added the ability of Group SAML sign-in to update a user's extern_uid if it changes in the IdP. This adds auditing to that process. Changelog: added EE: true --- .../gitlab/auth/group_saml/identity_linker.rb | 28 ++++++++++++++++--- .../auth/group_saml/identity_linker_spec.rb | 10 ++++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/ee/lib/gitlab/auth/group_saml/identity_linker.rb b/ee/lib/gitlab/auth/group_saml/identity_linker.rb index fc608a71743e38..c5d6bd293a6618 100644 --- a/ee/lib/gitlab/auth/group_saml/identity_linker.rb +++ b/ee/lib/gitlab/auth/group_saml/identity_linker.rb @@ -33,7 +33,7 @@ def error_message s_('GroupSAML|SAML Name ID and email address do not match your user account. Contact an administrator.') end - protected + private # rubocop: disable CodeReuse/ActiveRecord override :identity @@ -52,10 +52,16 @@ def update_group_membership end def update_extern_uid - return unless update_extern_uid_allowed? + existing_extern_uid = identity.extern_uid - identity.extern_uid = uid.to_s - save + success = if update_extern_uid_allowed? + identity.extern_uid = uid.to_s + save + else + false + end + + audit(success, existing_extern_uid, uid.to_s) end # When the current extern_uid doesn't match the @@ -76,6 +82,20 @@ def update_extern_uid_allowed? def update_extern_uid_failed? extern_uid_update_required? && !update_extern_uid_allowed? end + + def audit(success, old_uid, new_uid) + action = success ? "Updated" : "Failed to update" + + audit_context = { + name: 'update_mismatched_group_saml_extern_uid', + author: current_user, + scope: current_user, + target: current_user, + message: "#{action} extern_uid from #{old_uid} to #{new_uid}" + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end end end end diff --git a/ee/spec/lib/gitlab/auth/group_saml/identity_linker_spec.rb b/ee/spec/lib/gitlab/auth/group_saml/identity_linker_spec.rb index 7a4d1c36f607fd..c24090f719c9c8 100644 --- a/ee/spec/lib/gitlab/auth/group_saml/identity_linker_spec.rb +++ b/ee/spec/lib/gitlab/auth/group_saml/identity_linker_spec.rb @@ -43,7 +43,12 @@ end context 'when the extern_uid does not match' do - let(:extern_uid) { 'ioKaiph5' } + let(:audit_event) { AuditEvent.last.details[:custom_message] } + let_it_be(:extern_uid) { 'ioKaiph5' } + + before do + stub_licensed_features(admin_audit_log: true) + end it 'updates the identity when the email address matches' do expect(identity.extern_uid).to eq(extern_uid) @@ -53,6 +58,7 @@ expect(identity.reload.extern_uid).to eq(uid) expect(identity_linker.failed?).to eq(false) expect(identity_linker.error_message).to be_empty + expect(audit_event).to eq("Updated extern_uid from #{extern_uid} to #{uid}") end it 'does not update the identity when the email address does not match', :aggregate_failures do @@ -66,6 +72,7 @@ .to eq( s_('GroupSAML|SAML Name ID and email address do not match your user account. Contact an administrator.') ) + expect(audit_event).to eq("Failed to update extern_uid from #{extern_uid} to #{uid}") end context 'when the extern_uid is already taken' do @@ -79,6 +86,7 @@ expect(identity.reload.extern_uid).to eq(extern_uid) expect(identity_linker.failed?).to eq(true) expect(identity_linker.error_message).to eq('Extern uid has already been taken') + expect(audit_event).to eq("Failed to update extern_uid from #{extern_uid} to #{uid}") end end end -- GitLab