diff --git a/ee/lib/audit/group_push_rules_changes_auditor.rb b/ee/lib/audit/group_push_rules_changes_auditor.rb index a82a0fe525ecf92738902164ff1bde1394408fdf..708cd996c5162d2980073f9644540df0667e1264 100644 --- a/ee/lib/audit/group_push_rules_changes_auditor.rb +++ b/ee/lib/audit/group_push_rules_changes_auditor.rb @@ -7,11 +7,23 @@ class GroupPushRulesChangesAuditor < BaseChangesAuditor :file_name_regex, :max_file_size ].freeze + EVENT_TYPE_PER_ATTR = { + max_file_size: 'group_push_rules_max_file_size_updated', + file_name_regex: 'group_push_rules_file_name_regex_updated', + author_email_regex: 'group_push_rules_author_email_regex_updated', + commit_message_negative_regex: 'group_push_rules_commit_message_negative_regex_updated', + commit_message_regex: 'group_push_rules_commit_message_regex_updated', + branch_name_regex: 'group_push_rules_branch_name_regex_updated' + }.freeze + def execute return if model.blank? || model.group.nil? ::PushRule::AUDIT_LOG_ALLOWLIST.each do |attr, desc| - audit_changes(attr, as: desc, entity: model.group, model: model) + event_name = EVENT_TYPE_PER_ATTR[attr] || 'audit_operation' + + audit_changes(attr, as: desc, entity: model.group, model: model, + event_type: event_name) end end diff --git a/ee/spec/lib/audit/group_push_rules_changes_auditor_spec.rb b/ee/spec/lib/audit/group_push_rules_changes_auditor_spec.rb index ddcaed8747e8b62cf8941f96acb07ed0b20bf7ff..4511a62aa5954f20c7ed13b879bd056f2806ad0b 100644 --- a/ee/spec/lib/audit/group_push_rules_changes_auditor_spec.rb +++ b/ee/spec/lib/audit/group_push_rules_changes_auditor_spec.rb @@ -10,53 +10,67 @@ before do group.add_owner(current_user) + stub_licensed_features(audit_events: true, external_audit_events: true) + group.external_audit_event_destinations.create!(destination_url: 'http://example.com') end subject { described_class.new(current_user, push_rule) } - context 'auditing group-level changes' do + context 'when auditing group-level changes in push rules' do using RSpec::Parameterized::TableSyntax - where(:key, :old_value, :new_value) do - :commit_committer_check | false | true - :commit_committer_check | true | false - :reject_unsigned_commits | false | true - :reject_unsigned_commits | true | false - :deny_delete_tag | false | true - :deny_delete_tag | true | false - :member_check | false | true - :member_check | true | false - :prevent_secrets | false | true - :prevent_secrets | true | false - :branch_name_regex | nil | "\\Asecurity-.*\\z" - :branch_name_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" - :commit_message_regex | nil | "\\Asecurity-.*\\z" - :commit_message_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" - :commit_message_negative_regex | nil | "\\Asecurity-.*\\z" - :commit_message_negative_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" - :author_email_regex | nil | "\\Asecurity-.*\\z" - :author_email_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" - :file_name_regex | nil | "\\Asecurity-.*\\z" - :file_name_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" - :max_file_size | 0 | 132 - :max_file_size | 12 | 42 + # rubocop:disable Layout/LineLength + where(:key, :old_value, :new_value, :event_name) do + :commit_committer_check | false | true | 'audit_operation' + :commit_committer_check | true | false | 'audit_operation' + :reject_unsigned_commits | false | true | 'audit_operation' + :reject_unsigned_commits | true | false | 'audit_operation' + :deny_delete_tag | false | true | 'audit_operation' + :deny_delete_tag | true | false | 'audit_operation' + :member_check | false | true | 'audit_operation' + :member_check | true | false | 'audit_operation' + :prevent_secrets | false | true | 'audit_operation' + :prevent_secrets | true | false | 'audit_operation' + :branch_name_regex | nil | "\\Asecurity-.*\\z" | 'group_push_rules_branch_name_regex_updated' + :branch_name_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" | 'group_push_rules_branch_name_regex_updated' + :commit_message_regex | nil | "\\Asecurity-.*\\z" | 'group_push_rules_commit_message_regex_updated' + :commit_message_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" | 'group_push_rules_commit_message_regex_updated' + :commit_message_negative_regex | nil | "\\Asecurity-.*\\z" | 'group_push_rules_commit_message_negative_regex_updated' + :commit_message_negative_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" | 'group_push_rules_commit_message_negative_regex_updated' + :author_email_regex | nil | "\\Asecurity-.*\\z" | 'group_push_rules_author_email_regex_updated' + :author_email_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" | 'group_push_rules_author_email_regex_updated' + :file_name_regex | nil | "\\Asecurity-.*\\z" | 'group_push_rules_file_name_regex_updated' + :file_name_regex | ".*\\w{2}" | "\\Asecurity-.*\\z" | 'group_push_rules_file_name_regex_updated' + :max_file_size | 0 | 132 | 'group_push_rules_max_file_size_updated' + :max_file_size | 12 | 42 | 'group_push_rules_max_file_size_updated' end + # rubocop:enable Layout/LineLength with_them do - it 'audits the change in push rule correctly', :aggregate_failures do + before do push_rule.update!(key => old_value) + push_rule.update!(key => new_value) + end + + it 'audits the change in push rule correctly', :aggregate_failures do expect do - push_rule.update!(key => new_value) subject.execute end.to change { AuditEvent.count }.by(1) event = AuditEvent.last + expect(event.author).to eq(current_user) expect(event.details[:change]).to eq(::PushRule::AUDIT_LOG_ALLOWLIST[key]) expect(event.details[:from]).to eq(old_value) expect(event.details[:to]).to eq(new_value) expect(event.entity).to eq(group) end + + it 'streams correct audit event', :aggregate_failures do + expect(AuditEvents::AuditEventStreamingWorker).to receive(:perform_async) + .with(event_name, anything, anything) + subject.execute + end end end end