Skip to content
Snippets Groups Projects
Commit 0cf1ed23 authored by Zamir Martins's avatar Zamir Martins :speech_balloon:
Browse files

Merge branch 'add_routes_controller_view_to_group_dependencies' into 'master'

Draft: Add routes, controller and view to group level dependencies

See merge request gitlab-org/gitlab!120489



Merged-by: default avatarZamir Martins <zfilho@gitlab.com>
parents b287d389 07a157ab
No related branches found
No related tags found
No related merge requests found
# frozen_string_literal: true
module Groups
class DependenciesController < Groups::ApplicationController
before_action :authorize_read_dependency_list!
feature_category :dependency_management
urgency :low
def index
respond_to do |format|
format.html do
render status: :ok
end
format.json do
render json: serializer.represent(dependencies)
end
end
end
private
def authorize_read_dependency_list!
return if can?(current_user, :read_dependencies, group) && Feature.enabled?(:group_level_dependencies, group)
render_not_authorized
end
def dependency_list_params
params.permit(:sort_by, :sort, :package_names)
end
def collect_dependencies
return [] unless can?(current_user, :read_security_resource, group)
::Sbom::DependenciesFinder.new(group, params: dependency_list_params).execute
end
def dependencies
@dependencies ||= ::Gitlab::ItemsCollection.new(collect_dependencies)
end
def serializer
::DependencyListSerializer.new(group: group, user: current_user).with_pagination(request, response)
end
def render_not_authorized
respond_to do |format|
format.html do
render_404
end
format.json do
render_403
end
end
end
end
end
...@@ -431,6 +431,7 @@ module GroupPolicy ...@@ -431,6 +431,7 @@ module GroupPolicy
rule { can?(:read_group_security_dashboard) }.policy do rule { can?(:read_group_security_dashboard) }.policy do
enable :create_vulnerability_export enable :create_vulnerability_export
enable :read_security_resource enable :read_security_resource
enable :read_dependencies
end end
rule { admin | owner }.policy do rule { admin | owner }.policy do
......
...@@ -28,10 +28,14 @@ class LicenseEntity < Grape::Entity ...@@ -28,10 +28,14 @@ class LicenseEntity < Grape::Entity
private private
def can_read_vulnerabilities? def can_read_vulnerabilities?
can?(request.user, :read_security_resource, request.project) return can?(request.user, :read_security_resource, request.project) if request.respond_to?(:project)
false
end end
def can_read_licenses? def can_read_licenses?
can?(request.user, :read_licenses, request.project) return can?(request.user, :read_licenses, request.project) if request.respond_to?(:project)
false
end end
end end
- breadcrumb_title _('Dependency list')
- page_title _('Dependency list')
#js-dependencies-app{
data: {
endpoint: group_dependencies_path(@group, format: :json),
documentation_path: help_page_path('user/application_security/dependency_list/index'),
support_documentation_path: help_page_path('user/application_security/dependency_scanning/index', anchor: 'supported-languages-and-package-managers'),
empty_state_svg_path: image_path('illustrations/Dependency-list-empty-state.svg')
}
}
---
name: group_level_dependencies
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120489
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/411257
milestone: '16.0'
type: development
group: group::threat insights
default_enabled: false
...@@ -195,6 +195,8 @@ ...@@ -195,6 +195,8 @@
resources :compliance_framework_reports, only: [:index], constraints: { format: :csv } resources :compliance_framework_reports, only: [:index], constraints: { format: :csv }
end end
resources :dependencies, only: [:index]
resource :push_rules, only: [:update] resource :push_rules, only: [:update]
resources :protected_branches, only: [:create, :update, :destroy] resources :protected_branches, only: [:create, :update, :destroy]
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Groups::DependenciesController, feature_category: :dependency_management do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
before do
sign_in(user)
end
describe 'GET index' do
context 'with HTML format' do
subject { get :index, params: { group_id: group.to_param } }
context 'when security dashboard feature is enabled' do
before do
stub_licensed_features(security_dashboard: true)
stub_feature_flags(group_level_dependencies: true)
end
context 'and user is allowed to access group level dependencies' do
render_views
before do
group.add_developer(user)
end
it { is_expected.to have_gitlab_http_status(:ok) }
it 'returns the correct template' do
subject
expect(assigns(:group)).to eq(group)
expect(response).to render_template(:index)
expect(response.body).to include('data-documentation-path')
expect(response.body).to include('data-empty-state-svg-path')
expect(response.body).to include('data-endpoint')
expect(response.body).to include('data-support-documentation-path')
end
context 'when feature flag group_level_dependencies is disabled' do
before do
stub_feature_flags(group_level_dependencies: false)
end
it { is_expected.to have_gitlab_http_status(:not_found) }
end
end
context 'when user is not allowed to access group level dependencies' do
it { is_expected.to have_gitlab_http_status(:not_found) }
end
end
context 'when security dashboard feature is disabled' do
it { is_expected.to have_gitlab_http_status(:not_found) }
end
end
context 'with JSON format' do
subject { get :index, params: { group_id: group.to_param }, format: :json }
context 'when security dashboard feature is enabled' do
before do
stub_licensed_features(security_dashboard: true)
stub_feature_flags(group_level_dependencies: true)
end
context 'and user is allowed to access group level dependencies' do
render_views
let(:expected_response) do
{
'report' => {
'status' => 'job_not_set_up'
},
'dependencies' => []
}
end
before do
group.add_developer(user)
end
it { is_expected.to have_gitlab_http_status(:ok) }
it 'returns the expected data' do
subject
expect(json_response).to eq(expected_response)
end
context 'with existing dependencies' do
let_it_be(:project) { create(:project, group: group) }
let_it_be(:sbom_occurrences) { create_list(:sbom_occurrence, 2, project: project) }
let(:expected_response) do
{
'report' => {
'status' => 'job_not_set_up'
},
'dependencies' => [
{
'location' => {
'ancestors' => nil,
'blob_path' => "/group1/project-1/-/blob/b83d6e391c22777fca1e" \
"d3012fce84f633d7fed0/subproject-1/package-lock.json",
'path' => 'subproject-1/package-lock.json',
'top_level' => false
},
'name' => 'component-1',
'packager' => 'npm',
'version' => 'v0.0.1'
},
{
'location' => {
'ancestors' => nil,
'blob_path' => "/group1/project-1/-/blob/b83d6e391c22777fca1ed" \
"3012fce84f633d7fed0/subproject-2/package-lock.json",
'path' => 'subproject-2/package-lock.json',
'top_level' => false
},
'name' => 'component-2',
'packager' => 'npm',
'version' => 'v0.0.2'
}
]
}
end
it 'returns the expected data' do
subject
expect(json_response).to eq(expected_response)
end
end
context 'when feature flag group_level_dependencies is disabled' do
before do
stub_feature_flags(group_level_dependencies: false)
end
it { is_expected.to have_gitlab_http_status(:forbidden) }
end
end
context 'when user is not allowed to access group level dependencies' do
it { is_expected.to have_gitlab_http_status(:forbidden) }
end
end
context 'when security dashboard feature is disabled' do
it { is_expected.to have_gitlab_http_status(:forbidden) }
end
end
end
end
...@@ -1499,7 +1499,7 @@ def stub_group_saml_config(enabled) ...@@ -1499,7 +1499,7 @@ def stub_group_saml_config(enabled)
describe 'read_group_security_dashboard & create_vulnerability_export' do describe 'read_group_security_dashboard & create_vulnerability_export' do
let(:abilities) do let(:abilities) do
%i[read_group_security_dashboard create_vulnerability_export read_security_resource] %i[read_group_security_dashboard create_vulnerability_export read_security_resource read_dependencies]
end end
before do before do
......
...@@ -32,6 +32,16 @@ ...@@ -32,6 +32,16 @@
it 'includes license info and vulnerabilities' do it 'includes license info and vulnerabilities' do
is_expected.to eq(dependency.except(:package_manager, :iid)) is_expected.to eq(dependency.except(:package_manager, :iid))
end end
context 'with relation to group instead project' do
before do
allow(request).to receive(:project).and_return(nil)
end
it 'does not include license and vulnerabilities info' do
is_expected.to eq(dependency.except(:licenses, :vulnerabilities, :package_manager, :iid))
end
end
end end
context 'with reporter' do context 'with reporter' do
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment