Commit f55e46b7 authored by Can Eldem's avatar Can Eldem Committed by Rémy Coutable

Extend License Compliance entity for Pipelines and MR view

Change json payload
Sort licenses alphabetically
parent 1567a6ee
...@@ -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