Commit 7d8a62ab authored by Alexander Turinske's avatar Alexander Turinske Committed by Natalia Tepluhina

Add finding information to vulnerability

- original the vulnerability didn't have the description and name
- get that information from the finding and append it to the
  vulnerability
- add only what is necessary from the occurrence data to the
  post body
- Add tests for vulnerabilities app component
parent be62d061
...@@ -122,6 +122,7 @@ export default { ...@@ -122,6 +122,7 @@ export default {
project_fingerprint: this.projectFingerprint, project_fingerprint: this.projectFingerprint,
vulnerability_data: { vulnerability_data: {
...this.vulnerability, ...this.vulnerability,
...this.finding,
category: this.vulnerability.report_type, category: this.vulnerability.report_type,
vulnerability_id: this.vulnerability.id, vulnerability_id: this.vulnerability.id,
}, },
......
...@@ -239,7 +239,7 @@ module Vulnerabilities ...@@ -239,7 +239,7 @@ module Vulnerabilities
end end
def solution def solution
metadata.dig('solution') metadata.dig('solution') || remediations&.first&.dig('summary')
end end
def location def location
......
...@@ -5,6 +5,25 @@ FactoryBot.define do ...@@ -5,6 +5,25 @@ FactoryBot.define do
SecureRandom.uuid SecureRandom.uuid
end end
factory :vulnerabilities_occurrence_with_remediation, parent: :vulnerabilities_occurrence do
transient do
summary { nil }
end
after(:build) do |finding, evaluator|
if evaluator.summary
raw_metadata = JSON.parse(finding.raw_metadata)
raw_metadata.delete("solution")
raw_metadata["remediations"] = [
{
summary: evaluator.summary
}
]
finding.raw_metadata = raw_metadata.to_json
end
end
end
factory :vulnerabilities_occurrence, class: 'Vulnerabilities::Occurrence', aliases: [:vulnerabilities_finding] do factory :vulnerabilities_occurrence, class: 'Vulnerabilities::Occurrence', aliases: [:vulnerabilities_finding] do
name { 'Cipher with no integrity' } name { 'Cipher with no integrity' }
project project
......
...@@ -26,7 +26,7 @@ describe('Vulnerability management app', () => { ...@@ -26,7 +26,7 @@ describe('Vulnerability management app', () => {
state: 'detected', state: 'detected',
}; };
const defaultFinding = { const findingWithIssue = {
description: 'description', description: 'description',
identifiers: 'identifiers', identifiers: 'identifiers',
links: 'links', links: 'links',
...@@ -37,6 +37,14 @@ describe('Vulnerability management app', () => { ...@@ -37,6 +37,14 @@ describe('Vulnerability management app', () => {
}, },
}; };
const findingWithoutIssue = {
description: 'description',
identifiers: 'identifiers',
links: 'links',
location: 'location',
name: 'name',
};
const dataset = { const dataset = {
createIssueUrl: 'create_issue_url', createIssueUrl: 'create_issue_url',
projectFingerprint: 'abc123', projectFingerprint: 'abc123',
...@@ -60,7 +68,7 @@ describe('Vulnerability management app', () => { ...@@ -60,7 +68,7 @@ describe('Vulnerability management app', () => {
const findResolutionAlert = () => wrapper.find(ResolutionAlert); const findResolutionAlert = () => wrapper.find(ResolutionAlert);
const findStatusDescription = () => wrapper.find(StatusDescription); const findStatusDescription = () => wrapper.find(StatusDescription);
const createWrapper = (vulnerability = {}, finding = {}) => { const createWrapper = (vulnerability = {}, finding = findingWithoutIssue) => {
wrapper = shallowMount(App, { wrapper = shallowMount(App, {
propsData: { propsData: {
...dataset, ...dataset,
...@@ -115,7 +123,7 @@ describe('Vulnerability management app', () => { ...@@ -115,7 +123,7 @@ describe('Vulnerability management app', () => {
}); });
it('does not display if there is an issue already created', () => { it('does not display if there is an issue already created', () => {
createWrapper({}, defaultFinding); createWrapper({}, findingWithIssue);
expect(findCreateIssueButton().exists()).toBe(false); expect(findCreateIssueButton().exists()).toBe(false);
}); });
...@@ -137,6 +145,7 @@ describe('Vulnerability management app', () => { ...@@ -137,6 +145,7 @@ describe('Vulnerability management app', () => {
project_fingerprint: dataset.projectFingerprint, project_fingerprint: dataset.projectFingerprint,
vulnerability_data: { vulnerability_data: {
...defaultVulnerability, ...defaultVulnerability,
...findingWithoutIssue,
category: defaultVulnerability.report_type, category: defaultVulnerability.report_type,
vulnerability_id: defaultVulnerability.id, vulnerability_id: defaultVulnerability.id,
}, },
......
...@@ -91,34 +91,21 @@ describe VulnerabilitiesHelper do ...@@ -91,34 +91,21 @@ describe VulnerabilitiesHelper do
end end
describe '#vulnerability_finding_data' do describe '#vulnerability_finding_data' do
let(:finding) { build(:vulnerabilities_occurrence) }
subject { helper.vulnerability_finding_data(finding) } subject { helper.vulnerability_finding_data(finding) }
it "returns finding information" do it 'returns finding information' do
expect(subject).to include( expect(subject).to match(
description: finding.description, description: finding.description,
identifiers: finding.identifiers, identifiers: kind_of(Array),
issue_feedback: anything,
links: finding.links, links: finding.links,
location: finding.location, location: finding.location,
name: finding.name, name: finding.name,
issue_feedback: anything, project: kind_of(Grape::Entity::Exposure::NestingExposure::OutputBuilder),
project: anything solution: kind_of(String)
) )
end end
context "when finding has a remediations key" do
let(:finding) { vulnerability.findings.select { |finding| finding.raw_metadata.include?("remediations") }.first }
it "uses the first remediation summary" do
expect(subject[:solution]).to start_with "Use GCM mode"
end
end
context "when finding has a solution key" do
let(:finding) { vulnerability.findings.select { |finding| finding.raw_metadata.include?("solution") }.first }
it "uses the solution key" do
expect(subject[:solution]).to start_with "GCM mode"
end
end
end end
end end
...@@ -550,4 +550,22 @@ describe Vulnerabilities::Occurrence do ...@@ -550,4 +550,22 @@ describe Vulnerabilities::Occurrence do
it { is_expected.to eq(vulnerabilities_occurrence.scanner.name) } it { is_expected.to eq(vulnerabilities_occurrence.scanner.name) }
end end
describe '#solution' do
subject { vulnerabilities_occurrence.solution }
context 'when solution metadata key is present' do
let(:vulnerabilities_occurrence) { build(:vulnerabilities_occurrence) }
it { is_expected.to eq(vulnerabilities_occurrence.metadata['solution']) }
end
context 'when remediations key is present' do
let(:vulnerabilities_occurrence) do
build(:vulnerabilities_occurrence_with_remediation, summary: "Test remediation")
end
it { is_expected.to eq(vulnerabilities_occurrence.remediations.dig(0, 'summary')) }
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