From 77d672bb1177b59c7b62a41a49b018ac5048c9be Mon Sep 17 00:00:00 2001 From: Max Woolf Date: Thu, 11 Nov 2021 11:58:39 +0000 Subject: [PATCH] Audit changes to compliance frameworks Stores audit event logs of changes to, creations of, and deletetions of compliance frameworks at a group level. Changelog: added EE: true --- doc/administration/audit_events.md | 1 + .../frameworks/create_service.rb | 13 +++++++++++++ .../frameworks/destroy_service.rb | 13 +++++++++++++ .../frameworks/update_service.rb | 15 +++++++++++++++ .../frameworks/create_service_spec.rb | 4 ++++ .../frameworks/destroy_service_spec.rb | 4 ++++ .../frameworks/update_service_spec.rb | 12 ++++++++++++ 7 files changed, 62 insertions(+) diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md index 8fbf06343a59f8..03f0699f7768da 100644 --- a/doc/administration/audit_events.md +++ b/doc/administration/audit_events.md @@ -86,6 +86,7 @@ From there, you can see the following actions: - 2FA enforcement or grace period changed. - Roles allowed to create project changed. - Group CI/CD variable added, removed, or protected status changed. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30857) in GitLab 13.3. +- Compliance framework created, updated, or deleted. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340649) in GitLab 14.6. Group events can also be accessed via the [Group Audit Events API](../api/audit_events.md#group-audit-events) diff --git a/ee/app/services/compliance_management/frameworks/create_service.rb b/ee/app/services/compliance_management/frameworks/create_service.rb index 24632b4aa74c4e..fc5ce6a17ecffa 100644 --- a/ee/app/services/compliance_management/frameworks/create_service.rb +++ b/ee/app/services/compliance_management/frameworks/create_service.rb @@ -36,9 +36,22 @@ def permitted? end def success + audit_create ServiceResponse.success(payload: { framework: framework }) end + def audit_create + audit_context = { + name: 'create_compliance_framework', + author: current_user, + scope: framework.namespace, + target: framework, + message: "Created compliance framework #{framework.name}" + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + def error ServiceResponse.error(message: _('Failed to create framework'), payload: framework.errors ) end diff --git a/ee/app/services/compliance_management/frameworks/destroy_service.rb b/ee/app/services/compliance_management/frameworks/destroy_service.rb index 713d92b9701dce..18e00416c68089 100644 --- a/ee/app/services/compliance_management/frameworks/destroy_service.rb +++ b/ee/app/services/compliance_management/frameworks/destroy_service.rb @@ -23,12 +23,25 @@ def permitted? end def success + audit_destroy ServiceResponse.success(message: _('Framework successfully deleted')) end def error ServiceResponse.error(message: _('Failed to create framework'), payload: framework.errors ) end + + def audit_destroy + audit_context = { + name: 'destroy_compliance_framework', + author: current_user, + scope: framework.namespace, + target: framework, + message: "Destroyed compliance framework #{framework.name}" + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end end end end diff --git a/ee/app/services/compliance_management/frameworks/update_service.rb b/ee/app/services/compliance_management/frameworks/update_service.rb index 737fa607e9daf5..92df82adf64143 100644 --- a/ee/app/services/compliance_management/frameworks/update_service.rb +++ b/ee/app/services/compliance_management/frameworks/update_service.rb @@ -25,6 +25,7 @@ def execute end def success + audit_changes ServiceResponse.success(payload: { framework: framework }) end @@ -34,6 +35,20 @@ def error private + def audit_changes + framework.previous_changes.each do |attribute, changes| + audit_context = { + name: 'update_compliance_framework', + author: current_user, + scope: framework.namespace, + target: framework, + message: "Changed compliance framework's #{attribute} from #{changes[0]} to #{changes[1]}" + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + end + def permitted? can? current_user, :manage_compliance_framework, framework end diff --git a/ee/spec/services/compliance_management/frameworks/create_service_spec.rb b/ee/spec/services/compliance_management/frameworks/create_service_spec.rb index 5021ac96aed5d5..9b74a3a6cb2a1b 100644 --- a/ee/spec/services/compliance_management/frameworks/create_service_spec.rb +++ b/ee/spec/services/compliance_management/frameworks/create_service_spec.rb @@ -97,6 +97,10 @@ context 'when using parameters for a valid compliance framework' do subject { described_class.new(namespace: namespace, params: params, current_user: namespace.owner) } + it 'audits the changes' do + expect { subject.execute }.to change { AuditEvent.count }.by(1) + end + it 'creates a new compliance framework' do expect { subject.execute }.to change { ComplianceManagement::Framework.count }.by(1) end diff --git a/ee/spec/services/compliance_management/frameworks/destroy_service_spec.rb b/ee/spec/services/compliance_management/frameworks/destroy_service_spec.rb index 68307f3468c3f0..fffc9d5e91820f 100644 --- a/ee/spec/services/compliance_management/frameworks/destroy_service_spec.rb +++ b/ee/spec/services/compliance_management/frameworks/destroy_service_spec.rb @@ -37,6 +37,10 @@ it 'is successful' do expect(subject.execute.success?).to be true end + + it 'audits the destruction' do + expect { subject.execute }.to change { AuditEvent.count }.by(1) + end end context 'when current user is not the namespace owner' do diff --git a/ee/spec/services/compliance_management/frameworks/update_service_spec.rb b/ee/spec/services/compliance_management/frameworks/update_service_spec.rb index 48788799f7ddc9..f7c0177e498116 100644 --- a/ee/spec/services/compliance_management/frameworks/update_service_spec.rb +++ b/ee/spec/services/compliance_management/frameworks/update_service_spec.rb @@ -66,6 +66,18 @@ it 'is successful' do expect(subject.execute.success?).to be true end + + it 'audits the changes' do + expect { subject.execute }.to change { AuditEvent.count }.by(3) + + messages = AuditEvent.last(3).map { |e| e.details[:custom_message] } + + expect(messages).to contain_exactly( + 'Changed compliance framework\'s name from GDPR to New Name', + 'Changed compliance framework\'s color from #004494 to #000001', + 'Changed compliance framework\'s description from The General Data Protection Regulation (GDPR) is a regulation in EU law on data protection and privacy in the European Union (EU) and the European Economic Area (EEA). to New Description' + ) + end end end end -- GitLab