Commit 97838e65 authored by Gabriel Mazetto's avatar Gabriel Mazetto

Merge branch '212322-create-generatefindinguuidservice' into 'master'

Calculate UUIDv5 for Vulnerabilities::Findings

See merge request gitlab-org/gitlab!43881
parents 36982a7b 839a34f3
...@@ -74,10 +74,15 @@ module Security ...@@ -74,10 +74,15 @@ module Security
} }
begin begin
project vulnerability_finding = project
.vulnerability_findings .vulnerability_findings
.create_with(create_params) .create_with(create_params)
.find_or_create_by!(find_params) .find_or_initialize_by(find_params)
vulnerability_finding.uuid = calculcate_uuid_v5(vulnerability_finding, find_params)
vulnerability_finding.save!
vulnerability_finding
rescue ActiveRecord::RecordNotUnique rescue ActiveRecord::RecordNotUnique
project.vulnerability_findings.find_by!(find_params) project.vulnerability_findings.find_by!(find_params)
rescue ActiveRecord::RecordInvalid => e rescue ActiveRecord::RecordInvalid => e
...@@ -85,6 +90,23 @@ module Security ...@@ -85,6 +90,23 @@ module Security
end end
end end
def calculcate_uuid_v5(vulnerability_finding, finding_params)
uuid_v5_name_components = {
report_type: vulnerability_finding.report_type,
primary_identifier_fingerprint: vulnerability_finding.primary_identifier&.fingerprint || finding_params.dig(:primary_identifier, :fingerprint),
location_fingerprint: vulnerability_finding.location_fingerprint,
project_id: project.id
}
if uuid_v5_name_components.values.any?(&:nil?)
Gitlab::AppLogger.warn(message: "One or more UUID name components are nil", components: uuid_v5_name_components)
end
name = uuid_v5_name_components.values.join('-')
Gitlab::Vulnerabilities::CalculateFindingUUID.call(name)
end
def update_vulnerability_scanner(finding) def update_vulnerability_scanner(finding)
scanner = scanners_objects[finding.scanner.key] scanner = scanners_objects[finding.scanner.key]
scanner.update!(finding.scanner.to_hash) scanner.update!(finding.scanner.to_hash)
......
# frozen_string_literal: true
module Gitlab
module Vulnerabilities
class CalculateFindingUUID
FINDING_NAMESPACES_IDS = {
development: "a143e9e2-41b3-47bc-9a19-081d089229f4",
test: "a143e9e2-41b3-47bc-9a19-081d089229f4",
staging: "a6930898-a1b2-4365-ab18-12aa474d9b26",
production: "58dc0f06-936c-43b3-93bb-71693f1b6570"
}.freeze
NAMESPACE_REGEX = /(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})/.freeze
PACK_PATTERN = "NnnnnN".freeze
def self.call(value)
Digest::UUID.uuid_v5(namespace_id, value)
end
def self.namespace_id
namespace_uuid = FINDING_NAMESPACES_IDS.fetch(Rails.env.to_sym)
# Digest::UUID is broken when using an UUID in namespace_id
# https://github.com/rails/rails/issues/37681#issue-520718028
namespace_uuid.scan(NAMESPACE_REGEX).flatten.map { |s| s.to_i(16) }.pack(PACK_PATTERN)
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Vulnerabilities::CalculateFindingUUID do
let_it_be(:value) { "GitLab" }
subject { described_class.call(value) }
context 'in development' do
let_it_be(:development_proper_uuid) { "5b593e54-90f5-504b-8805-5394a4d14b94" }
before do
allow(Rails).to receive(:env).and_return(:development)
end
it { is_expected.to eq(development_proper_uuid) }
end
context 'in test' do
let_it_be(:test_proper_uuid) { "5b593e54-90f5-504b-8805-5394a4d14b94" }
it { is_expected.to eq(test_proper_uuid) }
end
context 'in staging' do
let_it_be(:staging_proper_uuid) { "dd190b37-7754-5c7c-80a0-85621a5823ad" }
before do
allow(Rails).to receive(:env).and_return(:staging)
end
it { is_expected.to eq(staging_proper_uuid) }
end
context 'in production' do
let_it_be(:production_proper_uuid) { "4961388b-9d8e-5da0-a499-3ef5da58daf0" }
before do
allow(Rails).to receive(:env).and_return(:production)
end
it { is_expected.to eq(production_proper_uuid) }
end
end
...@@ -55,6 +55,10 @@ RSpec.describe Security::StoreReportService, '#execute' do ...@@ -55,6 +55,10 @@ RSpec.describe Security::StoreReportService, '#execute' do
it 'inserts all vulnerabilties' do it 'inserts all vulnerabilties' do
expect { subject }.to change { Vulnerability.count }.by(findings) expect { subject }.to change { Vulnerability.count }.by(findings)
end end
it 'calculates UUIDv5 for all findings' do
expect(Vulnerabilities::Finding.pluck(:uuid)).to all(be_a(String))
end
end end
context 'invalid data' do context 'invalid data' do
...@@ -120,6 +124,10 @@ RSpec.describe Security::StoreReportService, '#execute' do ...@@ -120,6 +124,10 @@ RSpec.describe Security::StoreReportService, '#execute' do
expect { subject }.to change { Vulnerabilities::Finding.count }.by(32) expect { subject }.to change { Vulnerabilities::Finding.count }.by(32)
end end
it 'calculates UUIDv5 for all findings' do
expect(Vulnerabilities::Finding.pluck(:uuid)).to all(be_a(String))
end
it 'inserts all finding pipelines (join model) for this new pipeline' do it 'inserts all finding pipelines (join model) for this new pipeline' do
expect { subject }.to change { Vulnerabilities::FindingPipeline.where(pipeline: new_pipeline).count }.by(33) expect { subject }.to change { Vulnerabilities::FindingPipeline.where(pipeline: new_pipeline).count }.by(33)
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