Commit 512d82dc authored by Tetiana Chupryna's avatar Tetiana Chupryna Committed by Jan Provaznik

Add licenses to DL structure

Parse licenses for DL

Add tests for licenses wip

Check that licenses are added to hash

Add test for parsing licenses

Add changelog entry
parent 22c25d2d
...@@ -78,6 +78,10 @@ module EE ...@@ -78,6 +78,10 @@ module EE
each_report(::Ci::JobArtifact::DEPENDENCY_LIST_REPORT_FILE_TYPES) do |file_type, blob| each_report(::Ci::JobArtifact::DEPENDENCY_LIST_REPORT_FILE_TYPES) do |file_type, blob|
dependency_list.parse!(blob, dependency_list_report) dependency_list.parse!(blob, dependency_list_report)
end end
each_report(::Ci::JobArtifact::LICENSE_MANAGEMENT_REPORT_FILE_TYPES) do |file_type, blob|
dependency_list.parse_licenses!(blob, dependency_list_report)
end
end end
dependency_list_report dependency_list_report
......
---
title: Merge License info to Dependency List report
merge_request: 15157
author:
type: added
...@@ -10,7 +10,7 @@ module Gitlab ...@@ -10,7 +10,7 @@ module Gitlab
end end
def parse!(json_data, report) def parse!(json_data, report)
report_data = JSON.parse!(json_data) report_data = JSON.parse(json_data)
report_data.fetch('dependency_files', []).each do |file| report_data.fetch('dependency_files', []).each do |file|
file['dependencies'].each do |dependency| file['dependencies'].each do |dependency|
report.add_dependency(formatter.format(dependency, report.add_dependency(formatter.format(dependency,
...@@ -21,6 +21,13 @@ module Gitlab ...@@ -21,6 +21,13 @@ module Gitlab
end end
end end
def parse_licenses!(json_data, report)
licenses = JSON.parse(json_data, symbolize_names: true)
licenses[:dependencies].each do |license|
report.apply_license(license)
end
end
private private
attr_reader :formatter attr_reader :formatter
......
...@@ -20,7 +20,8 @@ module Gitlab ...@@ -20,7 +20,8 @@ module Gitlab
path: file_path path: file_path
}, },
version: dependency['version'], version: dependency['version'],
vulnerabilities: collect_vulnerabilities(vulnerabilities, dependency, file_path) vulnerabilities: collect_vulnerabilities(vulnerabilities, dependency, file_path),
licenses: []
} }
end end
......
...@@ -14,6 +14,14 @@ module Gitlab ...@@ -14,6 +14,14 @@ module Gitlab
def add_dependency(dependency) def add_dependency(dependency)
dependencies << dependency dependencies << dependency
end end
def apply_license(license)
dependencies.each do |dependency|
next unless dependency[:name] == license[:dependency][:name]
dependency[:licenses] << license[:license]
end
end
end end
end end
end end
......
...@@ -5,6 +5,7 @@ FactoryBot.define do ...@@ -5,6 +5,7 @@ FactoryBot.define do
name 'nokogiri' name 'nokogiri'
packager 'Ruby (Bundler)' packager 'Ruby (Bundler)'
version '1.8.0' version '1.8.0'
licenses { [] }
location do location do
{ {
blob_path: '/some_project/path/Gemfile.lock', blob_path: '/some_project/path/Gemfile.lock',
......
...@@ -6,10 +6,9 @@ describe Gitlab::Ci::Parsers::Security::DependencyList do ...@@ -6,10 +6,9 @@ describe Gitlab::Ci::Parsers::Security::DependencyList do
let(:parser) { described_class.new(project, sha) } let(:parser) { described_class.new(project, sha) }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:sha) { '4242424242424242' } let(:sha) { '4242424242424242' }
let(:report) { Gitlab::Ci::Reports::DependencyList::Report.new }
describe '#parse!' do describe '#parse!' do
let(:report) { Gitlab::Ci::Reports::DependencyList::Report.new }
before do before do
artifact.each_blob do |blob| artifact.each_blob do |blob|
parser.parse!(blob, report) parser.parse!(blob, report)
...@@ -53,4 +52,37 @@ describe Gitlab::Ci::Parsers::Security::DependencyList do ...@@ -53,4 +52,37 @@ describe Gitlab::Ci::Parsers::Security::DependencyList do
end end
end end
end end
describe '#parse_licenses!' do
let(:artifact) { create(:ee_ci_job_artifact, :license_management) }
let(:dependency_info) { build(:dependency, :with_vulnerabilities) }
before do
report.add_dependency(dependency)
artifact.each_blob do |blob|
parser.parse_licenses!(blob, report)
end
end
context 'with existing license' do
let(:dependency) { dependency_info }
it 'apply license to dependency' do
licenses = report.dependencies.last[:licenses]
expect(licenses.count).to eq(1)
expect(licenses[0][:name]).to eq('MIT')
expect(licenses[0][:url]).to eq('http://opensource.org/licenses/mit-license')
end
end
context 'without existing license' do
let(:dependency) { dependency_info.merge(name: 'irigokon') }
it 'does not apply any license if name mismatch' do
expect(report.dependencies.first[:licenses]).to be_empty
end
end
end
end end
...@@ -33,6 +33,7 @@ describe Gitlab::Ci::Parsers::Security::Formatters::DependencyList do ...@@ -33,6 +33,7 @@ describe Gitlab::Ci::Parsers::Security::Formatters::DependencyList do
expect(data[:location][:path]).to eq('rails/Gemfile.lock') expect(data[:location][:path]).to eq('rails/Gemfile.lock')
expect(data[:version]).to eq('2.2.0') expect(data[:version]).to eq('2.2.0')
expect(data[:vulnerabilities]).to be_empty expect(data[:vulnerabilities]).to be_empty
expect(data[:licenses]).to be_empty
end end
end end
......
...@@ -235,7 +235,8 @@ describe Ci::Build do ...@@ -235,7 +235,8 @@ describe Ci::Build do
end end
describe '#collect_dependency_list_reports!' do describe '#collect_dependency_list_reports!' do
let!(:artifact) { create(:ee_ci_job_artifact, :dependency_list, job: job, project: job.project) } let!(:dl_artifact) { create(:ee_ci_job_artifact, :dependency_list, job: job, project: job.project) }
let!(:lm_artifact) { create(:ee_ci_job_artifact, :license_management, job: job, project: job.project) }
let(:dependency_list_report) { Gitlab::Ci::Reports::DependencyList::Report.new } let(:dependency_list_report) { Gitlab::Ci::Reports::DependencyList::Report.new }
subject { job.collect_dependency_list_reports!(dependency_list_report) } subject { job.collect_dependency_list_reports!(dependency_list_report) }
...@@ -248,10 +249,13 @@ describe Ci::Build do ...@@ -248,10 +249,13 @@ describe Ci::Build do
it 'parses blobs and add the results to the report' do it 'parses blobs and add the results to the report' do
subject subject
blob_path = "/#{project.full_path}/blob/#{job.sha}/yarn/yarn.lock" blob_path = "/#{project.full_path}/blob/#{job.sha}/yarn/yarn.lock"
mini_portile2 = dependency_list_report.dependencies[0]
yarn = dependency_list_report.dependencies[20]
expect(dependency_list_report.dependencies.count).to eq(21) expect(dependency_list_report.dependencies.count).to eq(21)
expect(dependency_list_report.dependencies[0][:name]).to eq('mini_portile2') expect(mini_portile2[:name]).to eq('mini_portile2')
expect(dependency_list_report.dependencies[20][:location][:blob_path]).to eq(blob_path) expect(mini_portile2[:licenses][0][:name]).to eq('MIT')
expect(yarn[:location][:blob_path]).to eq(blob_path)
end end
end end
......
...@@ -23,12 +23,12 @@ describe DependencyEntity do ...@@ -23,12 +23,12 @@ describe DependencyEntity do
end end
it do it do
is_expected.to eq(dependency) is_expected.to eq(dependency.except(:licenses))
end end
end end
context 'with reporter' do context 'with reporter' do
let(:dependency_info) { build(:dependency) } let(:dependency_info) { build(:dependency).except(:licenses) }
before do before do
project.add_reporter(user) project.add_reporter(user)
......
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