Commit 168adf9f authored by Dylan Griffith's avatar Dylan Griffith

Merge branch 'parse-new-scan-object' into 'master'

Parse new scan object

See merge request gitlab-org/gitlab!43736
parents 55084497 417ccb03
......@@ -47,7 +47,7 @@ module Security
return
end
vulnerability_params = finding.to_hash.except(:compare_key, :identifiers, :location, :scanner)
vulnerability_params = finding.to_hash.except(:compare_key, :identifiers, :location, :scanner, :scan)
vulnerability_finding = create_or_find_vulnerability_finding(finding, vulnerability_params)
update_vulnerability_scanner(finding)
......
......@@ -12,6 +12,7 @@ module Gitlab
raise SecurityReportParserError, "Invalid report format" unless report_data.is_a?(Hash)
create_scanner(report, report_data.dig('scan', 'scanner'))
create_scan(report, report_data.dig('scan'))
collate_remediations(report_data).each do |vulnerability|
create_vulnerability(report, vulnerability, report_data["version"])
......@@ -53,7 +54,6 @@ module Gitlab
end
def create_vulnerability(report, data, version)
scanner = create_scanner(report, data['scanner'])
identifiers = create_identifiers(report, data['identifiers'])
report.add_finding(
::Gitlab::Ci::Reports::Security::Finding.new(
......@@ -64,12 +64,19 @@ module Gitlab
location: create_location(data['location'] || {}),
severity: parse_severity_level(data['severity']&.downcase),
confidence: parse_confidence_level(data['confidence']&.downcase),
scanner: scanner,
scanner: create_scanner(report, data['scanner']),
scan: report&.scan,
identifiers: identifiers,
raw_metadata: data.to_json,
metadata_version: version))
end
def create_scan(report, scan_data)
return unless scan_data.is_a?(Hash)
report.scan = ::Gitlab::Ci::Reports::Security::Scan.new(scan_data)
end
def create_scanner(report, scanner)
return unless scanner.is_a?(Hash)
......
......@@ -18,12 +18,13 @@ module Gitlab
attr_reader :raw_metadata
attr_reader :report_type
attr_reader :scanner
attr_reader :scan
attr_reader :severity
attr_reader :uuid
delegate :file_path, :start_line, :end_line, to: :location
def initialize(compare_key:, identifiers:, location:, metadata_version:, name:, raw_metadata:, report_type:, scanner:, uuid:, confidence: nil, severity: nil) # rubocop:disable Metrics/ParameterLists
def initialize(compare_key:, identifiers:, location:, metadata_version:, name:, raw_metadata:, report_type:, scanner:, scan:, uuid:, confidence: nil, severity: nil) # rubocop:disable Metrics/ParameterLists
@compare_key = compare_key
@confidence = confidence
@identifiers = identifiers
......@@ -33,6 +34,7 @@ module Gitlab
@raw_metadata = raw_metadata
@report_type = report_type
@scanner = scanner
@scan = scan
@severity = severity
@uuid = uuid
......
......@@ -12,6 +12,7 @@ module Gitlab
attr_reader :scanners
attr_reader :identifiers
attr_accessor :scan
attr_accessor :scanned_resources
attr_accessor :error
......
# frozen_string_literal: true
module Gitlab
module Ci
module Reports
module Security
class Scan
attr_accessor :type, :status, :start_time, :end_time
def initialize(params = {})
@type = params.dig('type')
@status = params.dig('status')
@start_time = params.dig('start_time')
@end_time = params.dig('end_time')
end
def to_hash
{
type: type,
status: status,
start_time: start_time,
end_time: end_time
}.compact
end
end
end
end
end
end
......@@ -30,6 +30,7 @@ FactoryBot.define do
end
scanner factory: :ci_reports_security_scanner
severity { :high }
scan factory: :ci_reports_security_scan
sequence(:uuid) { generate(:vulnerability_finding_uuid) }
skip_create
......
......@@ -12,4 +12,17 @@ FactoryBot.define do
::Gitlab::Ci::Reports::Security::Scanner.new(**attributes)
end
end
factory :ci_reports_security_scan, class: '::Gitlab::Ci::Reports::Security::Scan' do
status { 'success' }
type { 'sast' }
start_time { 'placeholder' }
end_time { 'placeholder' }
skip_create
initialize_with do
::Gitlab::Ci::Reports::Security::Scan.new(attributes)
end
end
end
......@@ -57,5 +57,26 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
end
end
end
context 'parsing scan' do
it 'returns scan object for each finding' do
scans = report.findings.map(&:scan)
expect(scans.map(&:status).all?('success')).to be(true)
expect(scans.map(&:type).all?('dependency_scanning')).to be(true)
expect(scans.map(&:start_time).all?('placeholder-value')).to be(true)
expect(scans.map(&:end_time).all?('placeholder-value')).to be(true)
expect(scans.size).to eq(3)
expect(scans.first).to be_a(::Gitlab::Ci::Reports::Security::Scan)
end
it 'returns nil when scan is not a hash' do
parser = described_class.new
empty_report = Gitlab::Ci::Reports::Security::Report.new(artifact.file_type, pipeline, 2.weeks.ago)
parser.parse!({}.to_json, empty_report)
expect(empty_report.scan).to be(nil)
end
end
end
end
......@@ -24,6 +24,7 @@ RSpec.describe Gitlab::Ci::Reports::Security::Finding do
raw_metadata: 'I am a stringified json object',
report_type: :sast,
scanner: scanner,
scan: nil,
severity: :high,
uuid: 'cadf8cf0a8228fa92a0f4897a0314083bb38'
}
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Ci::Reports::Security::Scan do
describe '#initialize' do
subject { described_class.new(params.with_indifferent_access) }
let(:params) do
{
status: 'success',
type: 'dependency-scanning',
start_time: 'placeholer',
end_time: 'placholder'
}
end
context 'when all params are given' do
it 'initializes an instance' do
expect { subject }.not_to raise_error
expect(subject).to have_attributes(
status: 'success',
type: 'dependency-scanning',
start_time: 'placeholer',
end_time: 'placholder'
)
end
end
describe '#to_hash' do
subject { described_class.new(params.with_indifferent_access).to_hash }
it 'returns expected hash' do
is_expected.to eq(
{
status: 'success',
type: 'dependency-scanning',
start_time: 'placeholer',
end_time: 'placholder'
}
)
end
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