Add license column to group-level dependencies listing
What does this MR do and why?
It adds license information to the group-level dependencies app.
Note: This will be behind a feature flag and the backend data is not yet serving the license data. There are setup-instructions below that will add some mock data, so the UI can be tested.
Screenshots or screen recordings
Before | After |
---|---|
How to set up and validate locally
Apply this patch, so the API returns mock licenses:
diff --git a/ee/app/controllers/groups/dependencies_controller.rb b/ee/app/controllers/groups/dependencies_controller.rb
index 5965328eab6d..8c97e00077c2 100644
--- a/ee/app/controllers/groups/dependencies_controller.rb
+++ b/ee/app/controllers/groups/dependencies_controller.rb
@@ -25,13 +25,39 @@ def index
render status: :ok
end
format.json do
- render json: serialized_dependencies
+ render json: DependencyListSerializer
+ .new(project: nil, user: current_user)
+ .with_pagination(request, response)
+ .represent(
+ ::Sbom::DependenciesFinder.new(
+ group,
+ params: params.permit(
+ :package_managers,
+ :sort,
+ :sort_by,
+ component_names: [],
+ package_managers: []
+ )
+ ).execute
+ )
end
end
end
+ def licenses
+ render json: [
+ { name: 'Apache-2.0', url: 'https://spdx.org/licenses/Apache-2.0.json' },
+ { name: 'MIT', url: 'https://spdx.org/licenses/MIT.json' }
+ ]
+ end
+
def locations
- render json: locations_info
+ render json: ::Sbom::DependencyLocationListEntity.represent(
+ ::Sbom::DependencyLocationsFinder.new(
+ namespace: group,
+ params: params.permit(:search, :component_id)
+ ).execute
+ )
end
private
@@ -42,20 +68,6 @@ def authorize_read_dependency_list!
render_not_authorized
end
- def dependency_list_params
- params.permit(:sort_by, :sort, :component_id, :search, package_managers: [])
- end
-
- def collect_dependencies
- @collect_dependencies ||= ::Sbom::DependenciesFinder.new(group, params: dependency_list_params).execute
- end
-
- def serialized_dependencies
- DependencyListSerializer.new(
- project: nil,
- user: current_user).with_pagination(request, response).represent(collect_dependencies)
- end
-
def render_not_authorized
respond_to do |format|
format.html do
@@ -67,16 +79,6 @@ def render_not_authorized
end
end
- def locations_info
- ::Sbom::DependencyLocationListEntity.represent(dependency_locations)
- end
-
- def dependency_locations
- Sbom::DependencyLocationsFinder
- .new(namespace: group, params: dependency_list_params.slice(:component_id, :search))
- .execute
- end
-
def set_enable_project_search
@enable_project_search = group.count_within_namespaces <= GROUP_COUNT_LIMIT
end
diff --git a/ee/app/models/sbom/occurrence.rb b/ee/app/models/sbom/occurrence.rb
index 0ab7e2b4ba31..c5cd5156d122 100644
--- a/ee/app/models/sbom/occurrence.rb
+++ b/ee/app/models/sbom/occurrence.rb
@@ -59,6 +59,19 @@ def location
}
end
+ def licenses
+ [
+ {
+ name: 'Apache-2.0',
+ url: 'https://spdx.org/licenses/Apache-2.0.json'
+ },
+ {
+ name: 'MIT',
+ url: 'https://spdx.org/licenses/MIT.json'
+ }
+ ]
+ end
+
private
def input_file_blob_path
diff --git a/ee/app/serializers/dependency_entity.rb b/ee/app/serializers/dependency_entity.rb
index 6e68a1b7d742..f7a2568e6179 100644
--- a/ee/app/serializers/dependency_entity.rb
+++ b/ee/app/serializers/dependency_entity.rb
@@ -27,7 +27,7 @@ class ProjectEntity < Grape::Entity
expose :name, :packager, :version
expose :location, using: LocationEntity
expose :vulnerabilities, using: VulnerabilityEntity, if: ->(_) { can_read_vulnerabilities? }
- expose :licenses, using: LicenseEntity, if: ->(_) { can_read_licenses? }
+ expose :licenses, using: LicenseEntity # , if: ->(_) { can_read_licenses? }
expose :project, using: ProjectEntity, if: ->(_) { !has_project? }
expose :project_count, :occurrence_count, :component_id, if: ->(_) { !has_project? }
diff --git a/ee/config/routes/group.rb b/ee/config/routes/group.rb
index df6d6f2643f2..e0863ae9de07 100644
--- a/ee/config/routes/group.rb
+++ b/ee/config/routes/group.rb
@@ -197,6 +197,7 @@
resources :dependencies, only: [:index] do
collection do
+ get :licenses, format: :json
get :locations, format: :json
end
end
diff --git a/ee/spec/requests/groups/dependencies_controller_spec.rb b/ee/spec/requests/groups/dependencies_controller_spec.rb
index 78cce7865766..b3d557953b83 100644
--- a/ee/spec/requests/groups/dependencies_controller_spec.rb
+++ b/ee/spec/requests/groups/dependencies_controller_spec.rb
@@ -139,6 +139,12 @@
'location' => sbom_occurrence_npm.location.as_json,
'name' => sbom_occurrence_npm.name,
'packager' => sbom_occurrence_npm.packager,
+ 'licenses' => [
+ {
+ 'name' => 'MIT',
+ 'url' => 'https://spdx.org/licenses/MIT.json'
+ }
+ ],
'version' => sbom_occurrence_npm.version,
'occurrence_count' => 1,
'project_count' => 1,
@@ -150,6 +156,16 @@
'name' => sbom_occurrence_bundler.name,
'packager' => sbom_occurrence_bundler.packager,
'version' => sbom_occurrence_bundler.version,
+ 'licenses' => [
+ {
+ 'name' => 'Apache-2.0',
+ 'url' => 'https://spdx.org/licenses/Apache-2.0.json'
+ },
+ {
+ 'name' => 'MIT',
+ 'url' => 'https://spdx.org/licenses/MIT.json'
+ }
+ ],
'occurrence_count' => 1,
'project_count' => 1,
"project" => { "full_path" => project.full_path, "name" => project.name },
@@ -349,4 +365,29 @@
end
end
end
+
+ describe "GET #licenses" do
+ let_it_be(:project) { create(:project, namespace: group) }
+ let_it_be(:component) { create(:sbom_component) }
+
+ subject { get licenses_group_dependencies_path(group_id: group.full_path), as: :json }
+
+ context 'when is the best time to go to the dentist?' do
+ before do
+ stub_licensed_features(security_dashboard: true)
+ stub_feature_flags(group_level_dependencies: true)
+ group.add_developer(user)
+ end
+
+ it '02:30 (tooth hurty)' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq([
+ { 'name' => 'Apache-2.0', 'url' => 'https://spdx.org/licenses/Apache-2.0.json' },
+ { 'name' => 'MIT', 'url' => 'https://spdx.org/licenses/MIT.json' }
+ ])
+ end
+ end
+ end
end
- Enable the feature flag that controls the group-level dependencies app:
echo "Feature.enable(:group_level_dependencies)" | rails c
- Go to a group and then navigate to
Secure
->Dependency list
- Verify that the license column is not being displayed
- Enable the feature flag that controls the license rendering:
echo "Feature.disable(:group_level_licenses)" | rails c
- Verify that the license column is now showing up and matching the screenshots above
- Go to a project
- Verify that the license column is showing up (this should also be the case with the feature flag disabled)
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Related to #422351 (closed)
Edited by David Pisek