Commit 3d8b0ab7 authored by Nick Thomas's avatar Nick Thomas

Merge branch '13083-blacklist-violation-check' into 'master'

Check for software license violations using SPDX identifiers

See merge request gitlab-org/gitlab!18300
parents 6f4b324b 9ce2bbfb
...@@ -38,5 +38,9 @@ class SoftwareLicensePolicy < ApplicationRecord ...@@ -38,5 +38,9 @@ class SoftwareLicensePolicy < ApplicationRecord
with_license.where(SoftwareLicense.arel_table[:name].lower.in(Array(license_name).map(&:downcase))) with_license.where(SoftwareLicense.arel_table[:name].lower.in(Array(license_name).map(&:downcase)))
end end
scope :by_spdx, -> (spdx_identifier) do
with_license.where(software_licenses: { spdx_identifier: spdx_identifier })
end
delegate :name, to: :software_license delegate :name, to: :software_license
end end
---
title: Check for software license violations using SPDX identifiers
merge_request: 18300
author:
type: changed
...@@ -34,7 +34,9 @@ module Gitlab ...@@ -34,7 +34,9 @@ module Gitlab
end end
def violates?(software_license_policies) def violates?(software_license_policies)
software_license_policies.blacklisted.with_license_by_name(license_names).exists? policies_with_matching_license_name = software_license_policies.blacklisted.with_license_by_name(license_names)
policies_with_matching_spdx_id = software_license_policies.blacklisted.by_spdx(licenses.map(&:id).compact)
policies_with_matching_spdx_id.or(policies_with_matching_license_name).exists?
end end
def diff_with(other_report) def diff_with(other_report)
......
...@@ -5,11 +5,13 @@ FactoryBot.define do ...@@ -5,11 +5,13 @@ FactoryBot.define do
sequence(:name) { |n| "SOFTWARE-LICENSE-2.7/example_#{n}" } sequence(:name) { |n| "SOFTWARE-LICENSE-2.7/example_#{n}" }
trait :mit do trait :mit do
spdx_identifier { 'MIT' }
name { 'MIT' } name { 'MIT' }
end end
trait :apache_2_0 do trait :apache_2_0 do
name { 'Apache 2.0' } spdx_identifier { 'Apache-2.0' }
name { 'Apache 2.0 License' }
end end
end end
end end
...@@ -7,8 +7,18 @@ describe Gitlab::Ci::Reports::LicenseScanning::Report do ...@@ -7,8 +7,18 @@ describe Gitlab::Ci::Reports::LicenseScanning::Report do
describe '#violates?' do describe '#violates?' do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:mit_license) { build(:software_license, :mit) }
let(:apache_license) { build(:software_license, :apache_2_0) } context "when checking for violations using v1 license scan report" do
subject { build(:license_scan_report) }
let(:mit_license) { build(:software_license, :mit, spdx_identifier: nil) }
let(:apache_license) { build(:software_license, :apache_2_0, spdx_identifier: nil) }
before do
subject
.add_license(id: nil, name: 'MIT')
.add_dependency('rails')
end
context 'when a blacklisted license is found in the report' do context 'when a blacklisted license is found in the report' do
let(:mit_blacklist) { build(:software_license_policy, :blacklist, software_license: mit_license) } let(:mit_blacklist) { build(:software_license_policy, :blacklist, software_license: mit_license) }
...@@ -17,7 +27,7 @@ describe Gitlab::Ci::Reports::LicenseScanning::Report do ...@@ -17,7 +27,7 @@ describe Gitlab::Ci::Reports::LicenseScanning::Report do
project.software_license_policies << mit_blacklist project.software_license_policies << mit_blacklist
end end
it { expect(subject.violates?(project.software_license_policies)).to be(true) } specify { expect(subject.violates?(project.software_license_policies)).to be(true) }
end end
context 'when a blacklisted license is discovered with a different casing for the name' do context 'when a blacklisted license is discovered with a different casing for the name' do
...@@ -28,7 +38,7 @@ describe Gitlab::Ci::Reports::LicenseScanning::Report do ...@@ -28,7 +38,7 @@ describe Gitlab::Ci::Reports::LicenseScanning::Report do
project.software_license_policies << mit_blacklist project.software_license_policies << mit_blacklist
end end
it { expect(subject.violates?(project.software_license_policies)).to be(true) } specify { expect(subject.violates?(project.software_license_policies)).to be(true) }
end end
context 'when none of the licenses discovered in the report violate the blacklist policy' do context 'when none of the licenses discovered in the report violate the blacklist policy' do
...@@ -38,7 +48,50 @@ describe Gitlab::Ci::Reports::LicenseScanning::Report do ...@@ -38,7 +48,50 @@ describe Gitlab::Ci::Reports::LicenseScanning::Report do
project.software_license_policies << apache_blacklist project.software_license_policies << apache_blacklist
end end
it { expect(subject.violates?(project.software_license_policies)).to be(false) } specify { expect(subject.violates?(project.software_license_policies)).to be(false) }
end
end
context "when checking for violations using the v2 license scan reports" do
subject { build(:license_scan_report) }
context "when a blacklisted license with a SPDX identifier is also in the report" do
let(:mit_spdx_id) { 'MIT' }
let(:mit_license) { build(:software_license, :mit, spdx_identifier: mit_spdx_id) }
let(:mit_policy) { build(:software_license_policy, :blacklist, software_license: mit_license) }
before do
subject.add_license(id: mit_spdx_id, name: 'MIT License')
project.software_license_policies << mit_policy
end
specify { expect(subject.violates?(project.software_license_policies)).to be(true) }
end
context "when a blacklisted license does not have an SPDX identifier because it was provided by an end user" do
let(:custom_license) { build(:software_license, name: 'custom', spdx_identifier: nil) }
let(:custom_policy) { build(:software_license_policy, :blacklist, software_license: custom_license) }
before do
subject.add_license(id: nil, name: 'Custom')
project.software_license_policies << custom_policy
end
specify { expect(subject.violates?(project.software_license_policies)).to be(true) }
end
context "when none of the licenses discovered match any of the blacklisted software policies" do
let(:apache_license) { build(:software_license, :apache_2_0, spdx_identifier: 'Apache-2.0') }
let(:apache_policy) { build(:software_license_policy, :blacklist, software_license: apache_license) }
before do
subject.add_license(id: nil, name: 'Custom')
subject.add_license(id: 'MIT', name: 'MIT License')
project.software_license_policies << apache_policy
end
specify { expect(subject.violates?(project.software_license_policies)).to be(false) }
end
end end
end end
......
...@@ -33,6 +33,17 @@ describe SoftwareLicensePolicy do ...@@ -33,6 +33,17 @@ describe SoftwareLicensePolicy do
end end
end end
describe ".by_spdx" do
let_it_be(:mit) { create(:software_license, :mit) }
let_it_be(:mit_policy) { create(:software_license_policy, software_license: mit) }
let_it_be(:apache) { create(:software_license, :apache_2_0) }
let_it_be(:apache_policy) { create(:software_license_policy, software_license: apache) }
it { expect(described_class.by_spdx(mit.spdx_identifier)).to match_array([mit_policy]) }
it { expect(described_class.by_spdx([mit.spdx_identifier, apache.spdx_identifier])).to match_array([mit_policy, apache_policy]) }
it { expect(described_class.by_spdx(SecureRandom.uuid)).to be_empty }
end
describe "#name" do describe "#name" do
specify { expect(subject.name).to eql(subject.software_license.name) } specify { expect(subject.name).to eql(subject.software_license.name) }
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