diff --git a/app/services/two_factor/destroy_service.rb b/app/services/two_factor/destroy_service.rb index b8bbe215d6e7d71022ff5adbae0ec792422ca37f..859012c21531c96dd0670f69bdebaced89dc3dd9 100644 --- a/app/services/two_factor/destroy_service.rb +++ b/app/services/two_factor/destroy_service.rb @@ -8,7 +8,7 @@ def execute result = disable_two_factor - notification_service.disabled_two_factor(user) if result[:status] == :success + notify_on_success(user) if result[:status] == :success result end @@ -20,5 +20,11 @@ def disable_two_factor user.disable_two_factor! end end + + def notify_on_success(user) + notification_service.disabled_two_factor(user) + end end end + +TwoFactor::DestroyService.prepend_mod_with('TwoFactor::DestroyService') diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md index 442f743f2c7744a9ca03a23725fab9a017157394..a329adbed22efd05ace8cac66aa8bf38aed5572f 100644 --- a/doc/administration/audit_events.md +++ b/doc/administration/audit_events.md @@ -234,6 +234,7 @@ The following user actions are recorded: - Administrator added or removed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/323905) in GitLab 14.1) - Removed SSH key ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/220127) in GitLab 14.1) - Added or removed GPG key ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/220127) in GitLab 14.1) +- A user's two-factor authentication was disabled ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238177) in GitLab 15.1) Instance events can also be accessed via the [Instance Audit Events API](../api/audit_events.md#instance-audit-events). diff --git a/ee/app/services/ee/two_factor/destroy_service.rb b/ee/app/services/ee/two_factor/destroy_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..da478a7cea077acd89e4ecc16b89bd827ae9cad4 --- /dev/null +++ b/ee/app/services/ee/two_factor/destroy_service.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module EE + module TwoFactor + module DestroyService + extend ::Gitlab::Utils::Override + + private + + override :notify_on_success + def notify_on_success(user) + audit_context = { + name: 'user_disable_two_factor', + author: current_user, + scope: user, + target: user, + message: 'Disabled two-factor authentication', + created_at: DateTime.current + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + + super + end + end + end +end diff --git a/ee/spec/services/ee/two_factor/destroy_service_spec.rb b/ee/spec/services/ee/two_factor/destroy_service_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..034fe8ebd5b16bb7f73a051b0e37771824cb8d32 --- /dev/null +++ b/ee/spec/services/ee/two_factor/destroy_service_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe TwoFactor::DestroyService do + let_it_be(:current_user) { create(:user, :two_factor) } + + subject(:disable_2fa) { described_class.new(current_user, user: current_user).execute } + + context 'when disabling two-factor authentication succeeds' do + it 'creates an audit event', :aggregate_failures do + expect { disable_2fa }.to change(AuditEvent, :count).by(1) + + expect(AuditEvent.last).to have_attributes( + author: current_user, + entity_id: current_user.id, + target_id: current_user.id, + target_type: current_user.class.name, + target_details: current_user.name, + details: include(custom_message: 'Disabled two-factor authentication') + ) + end + end + + context 'when disabling two-factor authentication fails' do + before do + allow_next_instance_of(Users::UpdateService) do |instance| + allow(instance).to receive(:execute) + .and_return({ status: :error }) + end + end + + it 'does not create an audit event' do + expect { subject }.not_to change(AuditEvent, :count) + end + end +end