Commit 395dbfa0 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'add-approval-status-field-lm' into 'master'

Extend License Compliance entity for Pipelines and MR view

See merge request gitlab-org/gitlab-ee!15957
parents 1567a6ee f55e46b7
...@@ -1240,9 +1240,9 @@ class MergeRequest < ApplicationRecord ...@@ -1240,9 +1240,9 @@ class MergeRequest < ApplicationRecord
compare_reports(Ci::CompareTestReportsService) compare_reports(Ci::CompareTestReportsService)
end end
def compare_reports(service_class) def compare_reports(service_class, current_user = nil)
with_reactive_cache(service_class.name) do |data| with_reactive_cache(service_class.name) do |data|
unless service_class.new(project) unless service_class.new(project, current_user)
.latest?(base_pipeline, actual_head_pipeline, data) .latest?(base_pipeline, actual_head_pipeline, data)
raise InvalidateReactiveCache raise InvalidateReactiveCache
end end
......
...@@ -48,7 +48,7 @@ module EE ...@@ -48,7 +48,7 @@ module EE
end end
def license_management_reports def license_management_reports
reports_response(merge_request.compare_license_management_reports) reports_response(merge_request.compare_license_management_reports(current_user))
end end
def container_scanning_reports def container_scanning_reports
......
...@@ -31,7 +31,8 @@ module EE ...@@ -31,7 +31,8 @@ module EE
if report_exists if report_exists
format.html { render_show } format.html { render_show }
format.json do format.json do
render json: LicenseManagementReportLicenseEntity.licenses_payload(pipeline.license_management_report), status: :ok data = LicenseManagementReportsSerializer.new(project: project, current_user: current_user).represent(pipeline&.license_management_report&.licenses)
render json: data, status: :ok
end end
else else
format.html { redirect_to pipeline_path(pipeline) } format.html { redirect_to pipeline_path(pipeline) }
......
...@@ -152,12 +152,12 @@ module EE ...@@ -152,12 +152,12 @@ module EE
compare_reports(::Ci::CompareSastReportsService) compare_reports(::Ci::CompareSastReportsService)
end end
def compare_license_management_reports def compare_license_management_reports(current_user)
unless has_license_management_reports? unless has_license_management_reports?
return { status: :error, status_reason: 'This merge request does not have license management reports' } return { status: :error, status_reason: 'This merge request does not have license management reports' }
end end
compare_reports(::Ci::CompareLicenseManagementReportsService) compare_reports(::Ci::CompareLicenseManagementReportsService, current_user)
end end
def has_metrics_reports? def has_metrics_reports?
......
# frozen_string_literal: true
class LicenseManagementReportsSerializer < BaseSerializer
entity LicenseManagementReportLicenseEntity
end
# frozen_string_literal: true # frozen_string_literal: true
class LicenseManagementReportLicenseEntity < Grape::Entity class LicenseManagementReportLicenseEntity < Grape::Entity
include RequestAwareEntity
expose :name expose :name
expose :classification
expose :dependencies, using: LicenseManagementReportDependencyEntity expose :dependencies, using: LicenseManagementReportDependencyEntity
expose :count do |license| expose :count
license.dependencies.size expose :url
end
def self.licenses_payload(report) def classification
report.licenses.empty? ? {} : self.represent(report.licenses).as_json default = { id: nil, name: value_for(:name), approval_status: 'unclassified' }
found = SoftwareLicensePoliciesFinder.new(request&.current_user, request&.project, name: value_for(:name)).find
ManagedLicenseEntity.represent(found || default)
end end
end end
...@@ -10,6 +10,10 @@ module Ci ...@@ -10,6 +10,10 @@ module Ci
LicenseManagementReportsComparerSerializer LicenseManagementReportsComparerSerializer
end end
def serializer_params
{ project: project, current_user: current_user }
end
def get_report(pipeline) def get_report(pipeline)
pipeline&.license_management_report pipeline&.license_management_report
end end
......
---
title: Extend License Compliance entity for Pipelines and MR view
merge_request: 15957
author:
type: changed
...@@ -18,9 +18,11 @@ module Gitlab ...@@ -18,9 +18,11 @@ module Gitlab
license_dependencies = root['dependencies'].select do |dependency| license_dependencies = root['dependencies'].select do |dependency|
uses_license?(dependency['license']['name'], license_name) uses_license?(dependency['license']['name'], license_name)
end end
license_dependencies.each do |dependency| license_dependencies.each do |dependency|
license_management_report.add_dependency(license_name, dependency['dependency']['name']) license_management_report.add_dependency(license_name,
license_hash['count'],
dependency['license']['url'],
dependency['dependency']['name'])
end end
end end
end end
......
...@@ -5,10 +5,12 @@ module Gitlab ...@@ -5,10 +5,12 @@ module Gitlab
module Reports module Reports
module LicenseManagement module LicenseManagement
class License class License
attr_reader :name, :status attr_reader :name, :url, :count
def initialize(name) def initialize(name, count, url)
@name = name @name = name
@count = count
@url = url
@dependencies = Set.new @dependencies = Set.new
end end
......
...@@ -5,22 +5,24 @@ module Gitlab ...@@ -5,22 +5,24 @@ module Gitlab
module Reports module Reports
module LicenseManagement module LicenseManagement
class Report class Report
attr_reader :found_licenses
def initialize def initialize
@found_licenses = {} @found_licenses = {}
end end
def licenses def licenses
@found_licenses.values found_licenses.values.sort_by { |license| license.name.downcase }
end end
def license_names def license_names
@found_licenses.values.map(&:name) found_licenses.values.map(&:name)
end end
def add_dependency(license_name, dependency_name) def add_dependency(license_name, license_count, license_url, dependency_name)
key = license_name.upcase key = license_name.upcase
@found_licenses[key] ||= ::Gitlab::Ci::Reports::LicenseManagement::License.new(license_name) found_licenses[key] ||= ::Gitlab::Ci::Reports::LicenseManagement::License.new(license_name, license_count, license_url)
@found_licenses[key].add_dependency(dependency_name) found_licenses[key].add_dependency(dependency_name)
end end
def violates?(software_license_policies) def violates?(software_license_policies)
......
...@@ -679,7 +679,7 @@ describe Projects::MergeRequestsController do ...@@ -679,7 +679,7 @@ describe Projects::MergeRequestsController do
before do before do
allow_any_instance_of(::MergeRequest).to receive(:compare_reports) allow_any_instance_of(::MergeRequest).to receive(:compare_reports)
.with(::Ci::CompareLicenseManagementReportsService).and_return(comparison_status) .with(::Ci::CompareLicenseManagementReportsService, project.users.first).and_return(comparison_status)
end end
context 'when comparison is being processed' do context 'when comparison is being processed' do
......
...@@ -256,6 +256,9 @@ describe Projects::PipelinesController do ...@@ -256,6 +256,9 @@ describe Projects::PipelinesController do
describe 'GET licenses' do describe 'GET licenses' do
let(:licenses_with_html) {get :licenses, format: :html, params: { namespace_id: project.namespace, project_id: project, id: pipeline }} let(:licenses_with_html) {get :licenses, format: :html, params: { namespace_id: project.namespace, project_id: project, id: pipeline }}
let(:licenses_with_json) {get :licenses, format: :json, params: { namespace_id: project.namespace, project_id: project, id: pipeline }} let(:licenses_with_json) {get :licenses, format: :json, params: { namespace_id: project.namespace, project_id: project, id: pipeline }}
let!(:mit_license) { create(:software_license, :mit) }
let!(:software_license_policy) { create(:software_license_policy, software_license: mit_license, project: project) }
let(:payload) { JSON.parse(licenses_with_json.body) } let(:payload) { JSON.parse(licenses_with_json.body) }
context 'with a license management artifact' do context 'with a license management artifact' do
...@@ -283,7 +286,19 @@ describe Projects::PipelinesController do ...@@ -283,7 +286,19 @@ describe Projects::PipelinesController do
it 'will return license management report in json format' do it 'will return license management report in json format' do
expect(payload.size).to eq(pipeline.license_management_report.licenses.size) expect(payload.size).to eq(pipeline.license_management_report.licenses.size)
expect(payload.first.keys).to eq(%w(name dependencies count)) expect(payload.first.keys).to eq(%w(name classification dependencies count url))
end
it 'will return mit license approved status' do
payload_mit = payload.find { |l| l['name'] == 'MIT' }
expect(payload_mit['count']).to eq(pipeline.license_management_report.found_licenses['MIT'].count)
expect(payload_mit['url']).to eq('http://opensource.org/licenses/mit-license')
expect(payload_mit['classification']['approval_status']).to eq('approved')
end
it 'will return sorted by name' do
expect(payload.first['name']).to eq('Apache 2.0')
expect(payload.last['name']).to eq('unknown')
end end
end end
......
...@@ -4,21 +4,21 @@ FactoryBot.define do ...@@ -4,21 +4,21 @@ FactoryBot.define do
factory :ci_reports_license_management_report, class: ::Gitlab::Ci::Reports::LicenseManagement::Report do factory :ci_reports_license_management_report, class: ::Gitlab::Ci::Reports::LicenseManagement::Report do
trait :report_1 do trait :report_1 do
after(:build) do |report, evaluator| after(:build) do |report, evaluator|
report.add_dependency('MIT', 'Library1') report.add_dependency('MIT', 1, 'https://opensource.org/licenses/mit', 'Library1')
report.add_dependency('WTFPL', 'Library2') report.add_dependency('WTFPL', 1, 'https://opensource.org/licenses/wtfpl', 'Library2')
end end
end end
trait :report_2 do trait :report_2 do
after(:build) do |report, evaluator| after(:build) do |report, evaluator|
report.add_dependency('MIT', 'Library1') report.add_dependency('MIT', 1, 'https://opensource.org/licenses/mit', 'Library1')
report.add_dependency('Apache 2.0', 'Library3') report.add_dependency('Apache 2.0', 1, 'https://opensource.org/licenses/apache', 'Library3')
end end
end end
trait :mit do trait :mit do
after(:build) do |report, evaluator| after(:build) do |report, evaluator|
report.add_dependency('MIT', 'rails') report.add_dependency('MIT', 1, 'https://opensource.org/licenses/mit', 'rails')
end end
end end
end end
......
...@@ -191,8 +191,8 @@ describe Ci::Build do ...@@ -191,8 +191,8 @@ describe Ci::Build do
expect { subject }.not_to raise_error expect { subject }.not_to raise_error
expect(license_management_report.licenses.count).to eq(4) expect(license_management_report.licenses.count).to eq(4)
expect(license_management_report.licenses[0].name).to eq('MIT') expect(license_management_report.found_licenses['MIT'].name).to eq('MIT')
expect(license_management_report.licenses[0].dependencies.count).to eq(52) expect(license_management_report.found_licenses['MIT'].dependencies.count).to eq(52)
end end
end end
......
...@@ -342,7 +342,7 @@ describe MergeRequest do ...@@ -342,7 +342,7 @@ describe MergeRequest do
end end
describe '#compare_license_management_reports' do describe '#compare_license_management_reports' do
subject { merge_request.compare_license_management_reports } subject { merge_request.compare_license_management_reports(project.users.first) }
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) } let(:merge_request) { create(:merge_request, source_project: project) }
......
...@@ -5,8 +5,16 @@ require 'spec_helper' ...@@ -5,8 +5,16 @@ require 'spec_helper'
describe LicenseManagementReportLicenseEntity do describe LicenseManagementReportLicenseEntity do
include LicenseManagementReportHelper include LicenseManagementReportHelper
let(:user) { build(:user) }
let(:project) { build(:project, :repository) }
let(:license) { create_license } let(:license) { create_license }
let(:entity) { described_class.new(license) } let(:request) { double('request') }
let(:entity) { described_class.new(license, request: request) }
before do
allow(request).to receive(:current_user).and_return(user)
allow(request).to receive(:project).and_return(project)
end
describe '#as_json' do describe '#as_json' do
subject { entity.as_json } subject { entity.as_json }
......
...@@ -5,8 +5,16 @@ require 'spec_helper' ...@@ -5,8 +5,16 @@ require 'spec_helper'
describe LicenseManagementReportsComparerEntity do describe LicenseManagementReportsComparerEntity do
include LicenseManagementReportHelper include LicenseManagementReportHelper
let(:user) { build(:user) }
let(:project) { build(:project, :repository) }
let(:request) { double('request') }
let(:comparer) { create_comparer } let(:comparer) { create_comparer }
let(:entity) { described_class.new(comparer) } let(:entity) { described_class.new(comparer, request: request) }
before do
allow(request).to receive(:current_user).and_return(user)
allow(request).to receive(:project).and_return(project)
end
describe '#as_json' do describe '#as_json' do
subject { entity.as_json } subject { entity.as_json }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
require 'spec_helper' require 'spec_helper'
describe Ci::CompareLicenseManagementReportsService do describe Ci::CompareLicenseManagementReportsService do
let(:service) { described_class.new(project) } let(:service) { described_class.new(project, project.users.take) }
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
before do before do
......
...@@ -5,7 +5,7 @@ module LicenseManagementReportHelper ...@@ -5,7 +5,7 @@ module LicenseManagementReportHelper
Gitlab::Ci::Reports::LicenseManagement::Report.new.tap do |report| Gitlab::Ci::Reports::LicenseManagement::Report.new.tap do |report|
dependencies.each do |license_name, dependencies| dependencies.each do |license_name, dependencies|
dependencies.each do |dependency_name| dependencies.each do |dependency_name|
report.add_dependency(license_name.to_s, dependency_name) report.add_dependency(license_name.to_s, 1, "https://opensource.org/licenses/license1", dependency_name)
end end
end end
end end
...@@ -32,7 +32,7 @@ module LicenseManagementReportHelper ...@@ -32,7 +32,7 @@ module LicenseManagementReportHelper
end end
def create_license def create_license
Gitlab::Ci::Reports::LicenseManagement::License.new('License1').tap do |license| Gitlab::Ci::Reports::LicenseManagement::License.new('License1', 1, "https://opensource.org/licenses/license1").tap do |license|
license.add_dependency('Dependency1') license.add_dependency('Dependency1')
license.add_dependency('Dependency2') license.add_dependency('Dependency2')
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