Commit b9c32590 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'sort-severity-then-confidence' into 'master'

Sort all vulnerabilities by Severity then Confidence for dashboard and Pipeline views

See merge request gitlab-org/gitlab!18675
parents c4750b40 a744cde1
---
title: Sort vulnerabilities by severity then confidence for dashboard and pipeline views
merge_request: 18675
author:
type: changed
...@@ -24,7 +24,11 @@ module Security ...@@ -24,7 +24,11 @@ module Security
end end
def execute def execute
pipeline_reports&.each_with_object([]) do |(type, report), occurrences| reports = pipeline_reports
return [] if reports.nil?
occurrences = reports.each_with_object([]) do |(type, report), occurrences|
next unless requested_type?(type) next unless requested_type?(type)
raise ParseError, 'JSON parsing failed' if report.error.is_a?(Gitlab::Ci::Parsers::Security::Common::SecurityReportParserError) raise ParseError, 'JSON parsing failed' if report.error.is_a?(Gitlab::Ci::Parsers::Security::Common::SecurityReportParserError)
...@@ -34,6 +38,8 @@ module Security ...@@ -34,6 +38,8 @@ module Security
occurrences.concat(filtered_occurrences) occurrences.concat(filtered_occurrences)
end end
occurrences.sort_by { |x| [x.severity, x.confidence] }
end end
private private
......
...@@ -77,7 +77,7 @@ module Vulnerabilities ...@@ -77,7 +77,7 @@ module Vulnerabilities
validates :raw_metadata, presence: true validates :raw_metadata, presence: true
scope :report_type, -> (type) { where(report_type: report_types[type]) } scope :report_type, -> (type) { where(report_type: report_types[type]) }
scope :ordered, -> { order("severity desc", :id) } scope :ordered, -> { order(severity: :desc, confidence: :desc, id: :asc) }
scope :by_report_types, -> (values) { where(report_type: values) } scope :by_report_types, -> (values) { where(report_type: values) }
scope :by_projects, -> (values) { where(project_id: values) } scope :by_projects, -> (values) { where(project_id: values) }
......
...@@ -52,6 +52,20 @@ describe Security::PipelineVulnerabilitiesFinder do ...@@ -52,6 +52,20 @@ describe Security::PipelineVulnerabilitiesFinder do
subject { described_class.new(pipeline: pipeline, params: params).execute } subject { described_class.new(pipeline: pipeline, params: params).execute }
context 'by order' do
let(:params) { { report_type: %w[sast] } }
let!(:occurrence1) { build(:vulnerabilities_occurrence, confidence: Vulnerabilities::Occurrence::CONFIDENCE_LEVELS[:high], severity: Vulnerabilities::Occurrence::SEVERITY_LEVELS[:high]) }
let!(:occurrence2) { build(:vulnerabilities_occurrence, confidence: Vulnerabilities::Occurrence::CONFIDENCE_LEVELS[:medium], severity: Vulnerabilities::Occurrence::SEVERITY_LEVELS[:critical]) }
let!(:occurrence3) { build(:vulnerabilities_occurrence, confidence: Vulnerabilities::Occurrence::CONFIDENCE_LEVELS[:high], severity: Vulnerabilities::Occurrence::SEVERITY_LEVELS[:critical]) }
let!(:res) { [occurrence3, occurrence2, occurrence1] }
it 'orders by severity and confidence' do
allow_any_instance_of(described_class).to receive(:filter).and_return(res)
expect(subject).to eq([occurrence3, occurrence2, occurrence1])
end
end
context 'by report type' do context 'by report type' do
context 'when sast' do context 'when sast' do
let(:params) { { report_type: %w[sast] } } let(:params) { { report_type: %w[sast] } }
......
...@@ -61,6 +61,16 @@ describe Vulnerabilities::Occurrence do ...@@ -61,6 +61,16 @@ describe Vulnerabilities::Occurrence do
end end
end end
context 'order' do
let!(:occurrence1) { create(:vulnerabilities_occurrence, confidence: described_class::CONFIDENCE_LEVELS[:high], severity: described_class::SEVERITY_LEVELS[:high]) }
let!(:occurrence2) { create(:vulnerabilities_occurrence, confidence: described_class::CONFIDENCE_LEVELS[:medium], severity: described_class::SEVERITY_LEVELS[:critical]) }
let!(:occurrence3) { create(:vulnerabilities_occurrence, confidence: described_class::CONFIDENCE_LEVELS[:high], severity: described_class::SEVERITY_LEVELS[:critical]) }
it 'orders by severity and confidence' do
expect(described_class.all.ordered).to eq([occurrence3, occurrence2, occurrence1])
end
end
describe '.report_type' do describe '.report_type' do
let(:report_type) { :sast } let(:report_type) { :sast }
......
...@@ -125,7 +125,7 @@ shared_examples 'getting list of vulnerability findings' do ...@@ -125,7 +125,7 @@ shared_examples 'getting list of vulnerability findings' do
# occurrences are implicitly sorted by Security::MergeReportsService, # occurrences are implicitly sorted by Security::MergeReportsService,
# occurrences order differs from what is present in fixture file # occurrences order differs from what is present in fixture file
expect(json_response.first['name']).to eq 'ECB mode is insecure' expect(json_response.first['name']).to eq 'Consider possible security implications associated with Popen module.'
end end
it 'returns vulnerabilities with dependency_scanning report_type' do it 'returns vulnerabilities with dependency_scanning report_type' do
......
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