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
with_license.where(SoftwareLicense.arel_table[:name].lower.in(Array(license_name).map(&:downcase)))
end
scope :by_spdx, -> (spdx_identifier) do
with_license.where(software_licenses: { spdx_identifier: spdx_identifier })
end
delegate :name, to: :software_license
end
---
title: Check for software license violations using SPDX identifiers
merge_request: 18300
author:
type: changed
......@@ -34,7 +34,9 @@ module Gitlab
end
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
def diff_with(other_report)
......
......@@ -5,11 +5,13 @@ FactoryBot.define do
sequence(:name) { |n| "SOFTWARE-LICENSE-2.7/example_#{n}" }
trait :mit do
spdx_identifier { 'MIT' }
name { 'MIT' }
end
trait :apache_2_0 do
name { 'Apache 2.0' }
spdx_identifier { 'Apache-2.0' }
name { 'Apache 2.0 License' }
end
end
end
......@@ -7,38 +7,91 @@ describe Gitlab::Ci::Reports::LicenseScanning::Report do
describe '#violates?' do
let(:project) { create(:project) }
let(:mit_license) { build(:software_license, :mit) }
let(:apache_license) { build(:software_license, :apache_2_0) }
context 'when a blacklisted license is found in the report' do
let(:mit_blacklist) { build(:software_license_policy, :blacklist, software_license: mit_license) }
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
project.software_license_policies << mit_blacklist
subject
.add_license(id: nil, name: 'MIT')
.add_dependency('rails')
end
it { expect(subject.violates?(project.software_license_policies)).to be(true) }
end
context 'when a blacklisted license is found in the report' do
let(:mit_blacklist) { build(:software_license_policy, :blacklist, software_license: mit_license) }
context 'when a blacklisted license is discovered with a different casing for the name' do
let(:mit_blacklist) { build(:software_license_policy, :blacklist, software_license: mit_license) }
before do
project.software_license_policies << mit_blacklist
end
before do
mit_license.update!(name: 'mit')
project.software_license_policies << mit_blacklist
specify { expect(subject.violates?(project.software_license_policies)).to be(true) }
end
context 'when a blacklisted license is discovered with a different casing for the name' do
let(:mit_blacklist) { build(:software_license_policy, :blacklist, software_license: mit_license) }
before do
mit_license.update!(name: 'mit')
project.software_license_policies << mit_blacklist
end
specify { expect(subject.violates?(project.software_license_policies)).to be(true) }
end
it { expect(subject.violates?(project.software_license_policies)).to be(true) }
context 'when none of the licenses discovered in the report violate the blacklist policy' do
let(:apache_blacklist) { build(:software_license_policy, :blacklist, software_license: apache_license) }
before do
project.software_license_policies << apache_blacklist
end
specify { expect(subject.violates?(project.software_license_policies)).to be(false) }
end
end
context 'when none of the licenses discovered in the report violate the blacklist policy' do
let(:apache_blacklist) { build(:software_license_policy, :blacklist, software_license: apache_license) }
context "when checking for violations using the v2 license scan reports" do
subject { build(:license_scan_report) }
before do
project.software_license_policies << apache_blacklist
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
it { expect(subject.violates?(project.software_license_policies)).to be(false) }
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
......
......@@ -33,6 +33,17 @@ describe SoftwareLicensePolicy do
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
specify { expect(subject.name).to eql(subject.software_license.name) }
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