Commit 195dcebf authored by can eldem's avatar can eldem

Sort DS analysers according to scanner id

parent 1e39f6f5
......@@ -2,6 +2,15 @@
module Security
class MergeReportsService
ANALYZER_ORDER = {
"bundler_audit" => 1,
"retire.js" => 2,
"gemnasium" => 3,
"gemnasium-maven" => 3,
"gemnasium-python" => 3,
"unknown" => 999
}.freeze
IdentifierKey = Struct.new(:location_sha, :identifier_type, :identifier_value) do
def ==(other)
location_sha == other.location_sha &&
......@@ -18,6 +27,8 @@ module Security
def initialize(*source_reports)
@source_reports = source_reports
# temporary sort https://gitlab.com/gitlab-org/gitlab/-/issues/213839
sort_by_ds_analyzers!
@target_report = ::Gitlab::Ci::Reports::Security::Report.new(
@source_reports.first.type,
@source_reports.first.commit_sha,
......@@ -110,5 +121,19 @@ module Security
@occurrences.each { |occurrence| @target_report.add_occurrence(occurrence) }
end
def sort_by_ds_analyzers!
return if @source_reports.any? { |x| x.type != :dependency_scanning }
@source_reports.sort! do |a, b|
a_scanner_id, b_scanner_id = a.scanners.values[0].external_id, b.scanners.values[0].external_id
# for custom analyzers
a_scanner_id = "unknown" if ANALYZER_ORDER[a_scanner_id].nil?
b_scanner_id = "unknown" if ANALYZER_ORDER[b_scanner_id].nil?
ANALYZER_ORDER[a_scanner_id] <=> ANALYZER_ORDER[b_scanner_id]
end
end
end
end
---
title: Sort dependency scanning reports before merging
merge_request: 30190
author:
type: fixed
......@@ -147,4 +147,74 @@ describe Security::MergeReportsService, '#execute' do
])
)
end
context 'ordering reports for dependency scanning analyzers' do
let(:gemnasium_scanner) { build(:ci_reports_security_scanner, external_id: 'gemnasium', name: 'gemnasium') }
let(:retire_js_scaner) { build(:ci_reports_security_scanner, external_id: 'retire.js', name: 'Retire.js') }
let(:bundler_audit_scanner) { build(:ci_reports_security_scanner, external_id: 'bundler_audit', name: 'bundler-audit') }
let(:identifier_gemnasium) { build(:ci_reports_security_identifier, external_id: 'Gemnasium-b1794c1', external_type: 'gemnasium') }
let(:identifier_cve) { build(:ci_reports_security_identifier, external_id: 'CVE-2019-123', external_type: 'cve') }
let(:identifier_npm) { build(:ci_reports_security_identifier, external_id: 'NPM-13', external_type: 'npm') }
let(:occurrence_id_1) { build(:ci_reports_security_occurrence, identifiers: [identifier_gemnasium, identifier_cve, identifier_npm], scanner: gemnasium_scanner, report_type: :dependency_scanning) }
let(:occurrence_id_2) { build(:ci_reports_security_occurrence, identifiers: [identifier_cve], scanner: bundler_audit_scanner, report_type: :dependency_scanning) }
let(:occurrence_id_3) { build(:ci_reports_security_occurrence, identifiers: [identifier_npm], scanner: retire_js_scaner, report_type: :dependency_scanning ) }
let(:gemnasium_report) do
build( :ci_reports_security_report,
type: :dependency_scanning,
scanners: [gemnasium_scanner],
occurrences: [occurrence_id_1],
identifiers: occurrence_id_1.identifiers
)
end
let(:bundler_audit_report) do
build(
:ci_reports_security_report,
type: :dependency_scanning,
scanners: [bundler_audit_scanner],
occurrences: [occurrence_id_2],
identifiers: occurrence_id_2.identifiers
)
end
let(:retirejs_report) do
build(
:ci_reports_security_report,
type: :dependency_scanning,
scanners: [retire_js_scaner],
occurrences: [occurrence_id_3],
identifiers: occurrence_id_3.identifiers
)
end
let(:custom_analyzer_report) do
build(
:ci_reports_security_report,
type: :dependency_scanning,
scanners: [scanner_2],
occurrences: [occurrence_id_2_loc_1],
identifiers: occurrence_id_2_loc_1.identifiers
)
end
context 'when reports are gathered in an unprioritized order' do
subject { described_class.new(gemnasium_report, retirejs_report, bundler_audit_report).execute }
specify { expect(subject.scanners.values).to eql([bundler_audit_scanner, retire_js_scaner, gemnasium_scanner]) }
specify { expect(subject.occurrences.count).to eq(2) }
specify { expect(subject.occurrences.first.identifiers).to contain_exactly(identifier_cve) }
specify { expect(subject.occurrences.last.identifiers).to contain_exactly(identifier_npm) }
end
context 'when a custom analyzer is completed before the known analyzers' do
subject { described_class.new(custom_analyzer_report, retirejs_report, bundler_audit_report).execute }
specify { expect(subject.scanners.values).to eql([bundler_audit_scanner, retire_js_scaner, scanner_2]) }
specify { expect(subject.occurrences.count).to eq(3) }
specify { expect(subject.occurrences.last.identifiers).to match_array(occurrence_id_2_loc_1.identifiers) }
end
end
end
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