diff --git a/app/services/projects/archive_service.rb b/app/services/projects/archive_service.rb index 09094a842f4d1d8cc5be55d60bd0776e4fc7f36d..f53fe6b50bd79f41499b41fbd929423195386b2e 100644 --- a/app/services/projects/archive_service.rb +++ b/app/services/projects/archive_service.rb @@ -39,3 +39,5 @@ def after_archive end end end + +Projects::ArchiveService.prepend_mod diff --git a/app/services/projects/unarchive_service.rb b/app/services/projects/unarchive_service.rb index cf3f4a41af1bcee433b7b548729e94044da68ec9..f113de9bd317466ea30ca176e07feee3002ff40b 100644 --- a/app/services/projects/unarchive_service.rb +++ b/app/services/projects/unarchive_service.rb @@ -37,3 +37,5 @@ def after_unarchive end end end + +Projects::UnarchiveService.prepend_mod diff --git a/ee/app/controllers/ee/projects_controller.rb b/ee/app/controllers/ee/projects_controller.rb index 1f75cbaa3b3188d643769da8cb028fdc7b8570ef..3496bf5301efc67e3afb176ce9e2151cbd7d21ae 100644 --- a/ee/app/controllers/ee/projects_controller.rb +++ b/ee/app/controllers/ee/projects_controller.rb @@ -10,8 +10,6 @@ module ProjectsController include GitlabSubscriptions::SeatCountAlert before_action :log_download_export_audit_event, only: [:download_export] - before_action :log_archive_audit_event, only: [:archive] - before_action :log_unarchive_audit_event, only: [:unarchive] before_action only: :show do @seat_count_data = generate_seat_count_alert_data(@project) @@ -179,13 +177,5 @@ def log_download_export_audit_event log_audit_event(message: 'Export file download started', event_type: 'project_export_file_download_started') end - - def log_archive_audit_event - log_audit_event(message: 'Project archived', event_type: 'project_archived') - end - - def log_unarchive_audit_event - log_audit_event(message: 'Project unarchived', event_type: 'project_unarchived') - end end end diff --git a/ee/app/services/ee/projects/archive_service.rb b/ee/app/services/ee/projects/archive_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..23fc2915329d3a4b4e37bdfb424aede547ef0482 --- /dev/null +++ b/ee/app/services/ee/projects/archive_service.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module EE + module Projects + module ArchiveService + extend ::Gitlab::Utils::Override + + private + + override :after_archive + def after_archive + super + + log_audit_event + end + + def log_audit_event + audit_context = { + name: 'project_archived', + author: current_user, + target: project, + scope: project, + message: 'Project archived' + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + end + end +end diff --git a/ee/app/services/ee/projects/unarchive_service.rb b/ee/app/services/ee/projects/unarchive_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..242044ae4cb0d3a091b2c0fc880c0cd46b6c0e3d --- /dev/null +++ b/ee/app/services/ee/projects/unarchive_service.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module EE + module Projects + module UnarchiveService + extend ::Gitlab::Utils::Override + + private + + override :after_unarchive + def after_unarchive + super + + log_audit_event + end + + def log_audit_event + audit_context = { + name: 'project_unarchived', + author: current_user, + target: project, + scope: project, + message: 'Project unarchived' + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + end + end +end diff --git a/ee/spec/requests/api/projects_spec.rb b/ee/spec/requests/api/projects_spec.rb index f9ebd8b5df0b13e635da844a3ac43c68714cd7ab..a3a98bb447bf65550a9e0b11118dc1e4f1a33dd8 100644 --- a/ee/spec/requests/api/projects_spec.rb +++ b/ee/spec/requests/api/projects_spec.rb @@ -2308,4 +2308,36 @@ end end end + + describe 'POST /projects/:id/archive' do + let(:path) { "/projects/#{project.id}/archive" } + + context 'when project archiving fails' do + it 'does not log an audit event' do + expect { post api(path, another_user) }.not_to change { AuditEvent.count } + end + end + + context 'when project archiving succeeds' do + it 'logs an audit event' do + expect { post api(path, user) }.to change { AuditEvent.count }.by(1) + end + end + end + + describe 'POST /projects/:id/unarchive' do + let(:path) { "/projects/#{project.id}/unarchive" } + + context 'when project unarchiving fails' do + it 'does not log an audit event' do + expect { post api(path, another_user) }.not_to change { AuditEvent.count } + end + end + + context 'when project unarchiving succeeds' do + it 'logs an audit event' do + expect { post api(path, user) }.to change { AuditEvent.count }.by(1) + end + end + end end diff --git a/ee/spec/services/ee/projects/archive_service_spec.rb b/ee/spec/services/ee/projects/archive_service_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..9e4acf2ec5cc0cb04ea0604c2564e69008524e8d --- /dev/null +++ b/ee/spec/services/ee/projects/archive_service_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::ArchiveService, feature_category: :groups_and_projects do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } + + let(:service) { described_class.new(project: project, current_user: user) } + + describe '#execute' do + context 'when project archiving fails' do + it 'does not log an audit event' do + expect { service.execute }.not_to change { AuditEvent.count } + end + end + + context 'when project archiving succeeds' do + before_all do + project.add_owner(user) + end + + it 'logs an audit event' do + expect { service.execute }.to change { AuditEvent.count }.by(1) + + audit_event = AuditEvent.last + expect(audit_event).to have_attributes( + author_id: user.id, + entity_type: 'Project', + target_type: "Project", + author_name: user.name + ) + expect(audit_event.details).to include( + event_name: "project_archived", + author_name: user.name, + author_class: "User", + target_type: "Project", + custom_message: "Project archived" + ) + end + end + end +end diff --git a/ee/spec/services/ee/projects/unarchive_service_spec.rb b/ee/spec/services/ee/projects/unarchive_service_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..b032d9d7acdfae271c24f457ab8071dfd17eb498 --- /dev/null +++ b/ee/spec/services/ee/projects/unarchive_service_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::UnarchiveService, feature_category: :groups_and_projects do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, archived: true) } + + let(:service) { described_class.new(project: project, current_user: user) } + + describe '#execute' do + context 'when project unarchiving fails' do + it 'does not log an audit event' do + expect { service.execute }.not_to change { AuditEvent.count } + end + end + + context 'when project unarchiving succeeds' do + before_all do + project.add_owner(user) + end + + it 'logs an audit event' do + expect { service.execute }.to change { AuditEvent.count }.by(1) + + audit_event = AuditEvent.last + expect(audit_event).to have_attributes( + author_id: user.id, + entity_type: 'Project', + target_type: "Project", + author_name: user.name + ) + expect(audit_event.details).to include( + event_name: "project_unarchived", + author_name: user.name, + author_class: "User", + target_type: "Project", + custom_message: "Project unarchived" + ) + end + end + end +end