Commit f6a74737 authored by ap4y's avatar ap4y

Expose commit sha on Vulnerabilities::Occurrence

Presenter for Vulnerabilities::Occurrence doesn't generate blob_path
if sha is missing. For some cases sha is dynamically added via joined
table, for pipeline reports sha is completely missing. To make
behavior more consistent we will introduce sha related accessors and
will populate it from either reports or joined queries.
parent c35b2264
...@@ -87,6 +87,7 @@ module Security ...@@ -87,6 +87,7 @@ module Security
occurrence.vulnerability = vulnerabilities[occurrence.project_fingerprint] occurrence.vulnerability = vulnerabilities[occurrence.project_fingerprint]
occurrence.project = pipeline.project occurrence.project = pipeline.project
occurrence.sha = pipeline.sha
occurrence.build_scanner(report_occurrence.scanner.to_hash) occurrence.build_scanner(report_occurrence.scanner.to_hash)
occurrence.identifiers = report_occurrence.identifiers.map do |identifier| occurrence.identifiers = report_occurrence.identifiers.map do |identifier|
Vulnerabilities::Identifier.new(identifier.to_hash) Vulnerabilities::Identifier.new(identifier.to_hash)
......
...@@ -25,6 +25,8 @@ module Vulnerabilities ...@@ -25,6 +25,8 @@ module Vulnerabilities
has_many :occurrence_pipelines, class_name: 'Vulnerabilities::OccurrencePipeline' has_many :occurrence_pipelines, class_name: 'Vulnerabilities::OccurrencePipeline'
has_many :pipelines, through: :occurrence_pipelines, class_name: 'Ci::Pipeline' has_many :pipelines, through: :occurrence_pipelines, class_name: 'Ci::Pipeline'
attr_writer :sha
CONFIDENCE_LEVELS = { CONFIDENCE_LEVELS = {
undefined: 0, undefined: 0,
ignore: 1, ignore: 1,
...@@ -127,6 +129,11 @@ module Vulnerabilities ...@@ -127,6 +129,11 @@ module Vulnerabilities
'vulnerabilities.id, vulnerabilities.state') # fetching only required attributes 'vulnerabilities.id, vulnerabilities.state') # fetching only required attributes
end end
# sha can be sourced from a joined pipeline or set from the report
def sha
self[:sha] || @sha
end
def state def state
return 'dismissed' if dismissal_feedback.present? return 'dismissed' if dismissal_feedback.present?
......
...@@ -5,7 +5,7 @@ module Vulnerabilities ...@@ -5,7 +5,7 @@ module Vulnerabilities
presents :occurrence presents :occurrence
def blob_path def blob_path
return '' unless respond_to?(:sha) return '' unless sha.present?
return '' unless location.present? && location['file'].present? return '' unless location.present? && location['file'].present?
add_line_numbers(location['start_line'], location['end_line']) add_line_numbers(location['start_line'], location['end_line'])
......
---
title: Expose commit sha on Vulnerabilities::Occurrence
merge_request: 19668
author:
type: fixed
...@@ -22,6 +22,7 @@ describe Security::PipelineVulnerabilitiesFinder do ...@@ -22,6 +22,7 @@ describe Security::PipelineVulnerabilitiesFinder do
describe '#execute' do describe '#execute' do
set(:project) { create(:project, :repository) } set(:project) { create(:project, :repository) }
set(:pipeline) { create(:ci_pipeline, :success, project: project) } set(:pipeline) { create(:ci_pipeline, :success, project: project) }
let(:params) { {} }
set(:build_cs) { create(:ci_build, :success, name: 'cs_job', pipeline: pipeline, project: project) } set(:build_cs) { create(:ci_build, :success, name: 'cs_job', pipeline: pipeline, project: project) }
set(:build_dast) { create(:ci_build, :success, name: 'dast_job', pipeline: pipeline, project: project) } set(:build_dast) { create(:ci_build, :success, name: 'dast_job', pipeline: pipeline, project: project) }
...@@ -52,6 +53,10 @@ describe Security::PipelineVulnerabilitiesFinder do ...@@ -52,6 +53,10 @@ describe Security::PipelineVulnerabilitiesFinder do
subject { described_class.new(pipeline: pipeline, params: params).execute } subject { described_class.new(pipeline: pipeline, params: params).execute }
it 'assigns commit sha to findings' do
expect(subject.map(&:sha).uniq).to eq [pipeline.sha]
end
context 'by order' do context 'by order' do
let(:params) { { report_type: %w[sast] } } let(:params) { { report_type: %w[sast] } }
let!(:high_high) { build(:vulnerabilities_occurrence, confidence: :high, severity: :high) } let!(:high_high) { build(:vulnerabilities_occurrence, confidence: :high, severity: :high) }
......
...@@ -15,10 +15,11 @@ describe Vulnerabilities::OccurrencePresenter do ...@@ -15,10 +15,11 @@ describe Vulnerabilities::OccurrencePresenter do
context 'with a sha' do context 'with a sha' do
before do before do
allow_any_instance_of(Vulnerabilities::Occurrence).to receive(:sha) occurrence.sha = 'abc'
.and_return('abc')
end end
it { is_expected.to include(occurrence.sha) }
context 'without start_line or end_line' do context 'without start_line or end_line' do
before do before do
allow(presenter).to receive(:location) allow(presenter).to receive(:location)
......
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