Commit 910004e8 authored by James Lopez's avatar James Lopez

Merge branch 'auto-create-vulnerabilities' into 'master'

Auto-create Vulnerabilities from Findings

See merge request gitlab-org/gitlab!22725
parents c820b470 66fc1064
......@@ -36,13 +36,15 @@ module Security
end
def create_vulnerability_finding(occurrence)
vulnerability = create_or_find_vulnerability_finding(occurrence)
vulnerability_finding = create_or_find_vulnerability_finding(occurrence)
occurrence.identifiers.map do |identifier|
create_vulnerability_identifier_object(vulnerability, identifier)
create_vulnerability_identifier_object(vulnerability_finding, identifier)
end
create_vulnerability_pipeline_object(vulnerability, pipeline)
create_vulnerability_pipeline_object(vulnerability_finding, pipeline)
create_vulnerability(vulnerability_finding, pipeline)
end
# rubocop: disable CodeReuse/ActiveRecord
......@@ -67,17 +69,23 @@ module Security
end
# rubocop: enable CodeReuse/ActiveRecord
def create_vulnerability_identifier_object(vulnerability, identifier)
vulnerability.occurrence_identifiers.find_or_create_by!( # rubocop: disable CodeReuse/ActiveRecord
def create_vulnerability_identifier_object(vulnerability_finding, identifier)
vulnerability_finding.occurrence_identifiers.find_or_create_by!( # rubocop: disable CodeReuse/ActiveRecord
identifier: identifiers_objects[identifier.key])
rescue ActiveRecord::RecordNotUnique
end
def create_vulnerability_pipeline_object(vulnerability, pipeline)
vulnerability.occurrence_pipelines.find_or_create_by!(pipeline: pipeline) # rubocop: disable CodeReuse/ActiveRecord
def create_vulnerability_pipeline_object(vulnerability_finding, pipeline)
vulnerability_finding.occurrence_pipelines.find_or_create_by!(pipeline: pipeline) # rubocop: disable CodeReuse/ActiveRecord
rescue ActiveRecord::RecordNotUnique
end
def create_vulnerability(vulnerability_finding, pipeline)
return if vulnerability_finding.vulnerability_id
Vulnerabilities::CreateService.new(vulnerability_finding.project, pipeline.user, finding_id: vulnerability_finding.id).execute
end
def scanners_objects
strong_memoize(:scanners_objects) do
@report.scanners.map do |key, scanner|
......
......@@ -3,18 +3,24 @@
require 'spec_helper'
describe Security::StoreReportService, '#execute' do
let(:user) { create(:user) }
let(:artifact) { create(:ee_ci_job_artifact, report_type) }
let(:project) { artifact.project }
let(:pipeline) { artifact.job.pipeline }
let(:report) { pipeline.security_reports.get_report(report_type.to_s, artifact) }
before do
stub_licensed_features(sast: true, dependency_scanning: true, container_scanning: true)
stub_licensed_features(sast: true, dependency_scanning: true, container_scanning: true, security_dashboard: true)
end
subject { described_class.new(pipeline, report).execute }
context 'without existing data' do
before do
project.add_developer(user)
allow(pipeline).to receive(:user).and_return(user)
end
using RSpec::Parameterized::TableSyntax
where(:case_name, :report_type, :scanners, :identifiers, :occurrences, :occurrence_identifiers, :occurrence_pipelines) do
......@@ -43,6 +49,10 @@ describe Security::StoreReportService, '#execute' do
it 'inserts all occurrence pipelines (join model)' do
expect { subject }.to change { Vulnerabilities::OccurrencePipeline.count }.by(occurrence_pipelines)
end
it 'inserts all vulnerabilties' do
expect { subject }.to change { Vulnerability.count }.by(occurrences)
end
end
end
......@@ -65,6 +75,11 @@ describe Security::StoreReportService, '#execute' do
location_fingerprint: 'd869ba3f0b3347eb2749135a437dc07c8ae0f420')
end
before do
project.add_developer(user)
allow(new_pipeline).to receive(:user).and_return(user)
end
subject { described_class.new(new_pipeline, new_report).execute }
it 'inserts only new scanners and reuse existing ones' do
......
......@@ -3,6 +3,7 @@
require 'spec_helper'
describe Security::StoreReportsService do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :public, namespace: group) }
let(:pipeline) { create(:ci_pipeline, project: project) }
......@@ -12,10 +13,12 @@ describe Security::StoreReportsService do
context 'when there are reports' do
before do
stub_licensed_features(sast: true, dependency_scanning: true, container_scanning: true)
stub_licensed_features(sast: true, dependency_scanning: true, container_scanning: true, security_dashboard: true)
create(:ee_ci_build, :sast, pipeline: pipeline)
create(:ee_ci_build, :dependency_scanning, pipeline: pipeline)
create(:ee_ci_build, :container_scanning, pipeline: pipeline)
project.add_developer(user)
allow(pipeline).to receive(:user).and_return(user)
end
it 'initializes and execute a StoreReportService for each report' 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