Commit d81af6e9 authored by Matthias Käppler's avatar Matthias Käppler

Merge branch '329362-2-audit-event-on-framework-change' into 'master'

Adds audit event when compliance framework changed

See merge request gitlab-org/gitlab!65343
parents 4c8d720f 6f7186c5
...@@ -122,6 +122,7 @@ From there, you can see the following actions: ...@@ -122,6 +122,7 @@ From there, you can see the following actions:
- When default branch changes for a project ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/52339) in GitLab 13.9) - When default branch changes for a project ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/52339) in GitLab 13.9)
- Created, updated, or deleted DAST profiles, DAST scanner profiles, and DAST site profiles - Created, updated, or deleted DAST profiles, DAST scanner profiles, and DAST site profiles
([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217872) in GitLab 14.1) ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217872) in GitLab 14.1)
- Changed a project's compliance framework ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/329362) in GitLab 14.1)
Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events). Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events).
......
...@@ -16,6 +16,8 @@ module ComplianceManagement ...@@ -16,6 +16,8 @@ module ComplianceManagement
belongs_to :compliance_management_framework, class_name: "ComplianceManagement::Framework", foreign_key: :framework_id belongs_to :compliance_management_framework, class_name: "ComplianceManagement::Framework", foreign_key: :framework_id
validates :project, presence: true validates :project, presence: true
delegate :full_path, to: :project
end end
end end
end end
...@@ -15,14 +15,46 @@ module EE ...@@ -15,14 +15,46 @@ module EE
audit_changes(:merge_requests_disable_committers_approval, as: 'prevent merge request approval from reviewers', model: model) audit_changes(:merge_requests_disable_committers_approval, as: 'prevent merge request approval from reviewers', model: model)
audit_project_feature_changes audit_project_feature_changes
audit_compliance_framework_changes
end end
private private
def audit_compliance_framework_changes
setting = model.compliance_framework_setting
return if setting.blank?
if setting.destroyed?
audit_context = {
author: @current_user,
scope: model,
target: model,
message: "Unassigned project compliance framework"
}
::Gitlab::Audit::Auditor.audit(audit_context)
else
audit_changes(:framework_id, as: 'compliance framework', model: model.compliance_framework_setting, entity: model)
end
end
def audit_project_feature_changes def audit_project_feature_changes
::EE::Audit::ProjectFeatureChangesAuditor.new(@current_user, model.project_feature, model).execute ::EE::Audit::ProjectFeatureChangesAuditor.new(@current_user, model.project_feature, model).execute
end end
def framework_changes
model.previous_changes["framework_id"]
end
def old_framework_name
ComplianceManagement::Framework.find_by_id(framework_changes.first)&.name || "None"
end
def new_framework_name
ComplianceManagement::Framework.find_by_id(framework_changes.last)&.name || "None"
end
def attributes_from_auditable_model(column) def attributes_from_auditable_model(column)
case column case column
when :name when :name
...@@ -50,6 +82,11 @@ module EE ...@@ -50,6 +82,11 @@ module EE
from: !model.previous_changes[column].first, from: !model.previous_changes[column].first,
to: !model.previous_changes[column].last to: !model.previous_changes[column].last
} }
when :framework_id
{
from: old_framework_name,
to: new_framework_name
}
else else
{ {
from: model.previous_changes[column].first, from: model.previous_changes[column].first,
......
...@@ -33,6 +33,65 @@ RSpec.describe EE::Audit::ProjectChangesAuditor do ...@@ -33,6 +33,65 @@ RSpec.describe EE::Audit::ProjectChangesAuditor do
end end
end end
describe 'auditing compliance framework changes' do
context 'when a project has no compliance framework' do
context 'when the framework is changed' do
let_it_be(:framework) { create(:compliance_framework) }
before do
project.update!(compliance_management_framework: framework)
end
it 'adds an audit event' do
expect { foo_instance.execute }.to change { AuditEvent.count }.by(1)
expect(AuditEvent.last.details).to include({
change: 'compliance framework',
from: 'None',
to: 'GDPR'
})
end
context 'when the framework is removed' do
before do
project.update!(compliance_management_framework: nil)
end
it 'adds an audit event' do
expect { foo_instance.execute }.to change { AuditEvent.count }.by(1)
expect(AuditEvent.last.details).to include({
custom_message: "Unassigned project compliance framework"
})
end
end
context 'when the framework is changed again' do
before do
project.update!(compliance_management_framework: create(:compliance_framework, namespace: project.namespace, name: 'SOX'))
end
it 'adds an audit event' do
expect { foo_instance.execute }.to change { AuditEvent.count }.by(1)
expect(AuditEvent.last.details).to include({
change: 'compliance framework',
from: 'GDPR',
to: 'SOX'
})
end
end
end
context 'when the framework is not changed' do
before do
project.update!(description: 'This is a description of a project')
end
it 'does not add an audit event' do
expect { foo_instance.execute }.not_to change { AuditEvent.count }
end
end
end
end
describe 'audit changes' do describe 'audit changes' do
it 'creates an event when the visibility change' do it 'creates an event when the visibility change' do
project.update!(visibility_level: 20) project.update!(visibility_level: 20)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment