Commit d95e99f4 authored by Daniel Tian's avatar Daniel Tian Committed by Olena Horal-Koretska

Add scanner data to vulnerability pages

parent 4d0ca52e
......@@ -14,54 +14,81 @@ export default (el, dashboardType) => {
return null;
}
if (el.dataset.isUnavailable) {
const {
isUnavailable,
dashboardDocumentation,
emptyStateSvgPath,
noVulnerabilitiesSvgPath,
notEnabledScannersHelpPath,
noPipelineRunScannersHelpPath,
hasVulnerabilities,
scanners,
securityDashboardHelpPath,
projectAddEndpoint,
projectListEndpoint,
vulnerabilitiesExportEndpoint,
projectFullPath,
autoFixDocumentation,
autoFixMrsPath,
groupFullPath,
instanceDashboardSettingsPath,
pipelineCreatedAt,
pipelineId,
pipelinePath,
pipelineSecurityBuildsFailedCount,
pipelineSecurityBuildsFailedPath,
} = el.dataset;
if (isUnavailable) {
return new Vue({
el,
render(createElement) {
return createElement(UnavailableState, {
props: {
link: el.dataset.dashboardDocumentation,
svgPath: el.dataset.emptyStateSvgPath,
link: dashboardDocumentation,
svgPath: emptyStateSvgPath,
},
});
},
});
}
const provide = {};
const provide = {
dashboardDocumentation,
noVulnerabilitiesSvgPath,
emptyStateSvgPath,
notEnabledScannersHelpPath,
noPipelineRunScannersHelpPath,
hasVulnerabilities: parseBoolean(hasVulnerabilities),
scanners: scanners ? JSON.parse(scanners) : [],
};
const props = {
securityDashboardHelpPath: el.dataset.securityDashboardHelpPath,
projectAddEndpoint: el.dataset.projectAddEndpoint,
projectListEndpoint: el.dataset.projectListEndpoint,
vulnerabilitiesExportEndpoint: el.dataset.vulnerabilitiesExportEndpoint,
securityDashboardHelpPath,
projectAddEndpoint,
projectListEndpoint,
vulnerabilitiesExportEndpoint,
};
let component;
if (dashboardType === DASHBOARD_TYPES.PROJECT) {
component = FirstClassProjectSecurityDashboard;
const {
pipelineCreatedAt: createdAt,
pipelineId: id,
pipelinePath: path,
pipelineSecurityBuildsFailedCount: securityBuildsFailedCount,
pipelineSecurityBuildsFailedPath: securityBuildsFailedPath,
} = el.dataset;
props.pipeline = {
createdAt,
id,
path,
securityBuildsFailedCount: Number(securityBuildsFailedCount),
securityBuildsFailedPath,
createdAt: pipelineCreatedAt,
id: pipelineId,
path: pipelinePath,
securityBuildsFailedCount: Number(pipelineSecurityBuildsFailedCount),
securityBuildsFailedPath: pipelineSecurityBuildsFailedPath,
};
provide.projectFullPath = el.dataset.projectFullPath;
provide.autoFixDocumentation = el.dataset.autoFixDocumentation;
provide.autoFixMrsPath = el.dataset.autoFixMrsPath;
provide.projectFullPath = projectFullPath;
provide.autoFixDocumentation = autoFixDocumentation;
provide.autoFixMrsPath = autoFixMrsPath;
} else if (dashboardType === DASHBOARD_TYPES.GROUP) {
component = FirstClassGroupSecurityDashboard;
props.groupFullPath = el.dataset.groupFullPath;
props.groupFullPath = groupFullPath;
} else if (dashboardType === DASHBOARD_TYPES.INSTANCE) {
provide.instanceDashboardSettingsPath = el.dataset.instanceDashboardSettingsPath;
provide.instanceDashboardSettingsPath = instanceDashboardSettingsPath;
component = FirstClassInstanceSecurityDashboard;
}
......@@ -73,15 +100,7 @@ export default (el, dashboardType) => {
store,
router,
apolloProvider,
provide: () => ({
dashboardDocumentation: el.dataset.dashboardDocumentation,
noVulnerabilitiesSvgPath: el.dataset.noVulnerabilitiesSvgPath,
emptyStateSvgPath: el.dataset.emptyStateSvgPath,
notEnabledScannersHelpPath: el.dataset.notEnabledScannersHelpPath,
noPipelineRunScannersHelpPath: el.dataset.noPipelineRunScannersHelpPath,
hasVulnerabilities: parseBoolean(el.dataset.hasVulnerabilities),
...provide,
}),
provide,
render(createElement) {
return createElement(component, { props });
},
......
......@@ -253,7 +253,8 @@ module EE
no_pipeline_run_scanners_help_path: new_project_pipeline_path(project),
security_dashboard_help_path: help_page_path('user/application_security/security_dashboard/index'),
auto_fix_documentation: help_page_path('user/application_security/index', anchor: 'auto-fix-merge-requests'),
auto_fix_mrs_path: project_merge_requests_path(@project, label_name: 'GitLab-auto-fix')
auto_fix_mrs_path: project_merge_requests_path(@project, label_name: 'GitLab-auto-fix'),
scanners: VulnerabilityScanners::ListService.new(project).execute.to_json
}.merge!(security_dashboard_pipeline_data(project))
end
end
......
......@@ -44,7 +44,8 @@ module Groups::SecurityFeaturesHelper
no_vulnerabilities_svg_path: image_path('illustrations/issues.svg'),
empty_state_svg_path: image_path('illustrations/security-dashboard-empty-state.svg'),
dashboard_documentation: help_page_path('user/application_security/security_dashboard/index'),
vulnerabilities_export_endpoint: expose_path(api_v4_security_groups_vulnerability_exports_path(id: group.id))
vulnerabilities_export_endpoint: expose_path(api_v4_security_groups_vulnerability_exports_path(id: group.id)),
scanners: VulnerabilityScanners::ListService.new(group).execute.to_json
}
end
end
......@@ -10,7 +10,8 @@ module SecurityHelper
project_add_endpoint: security_projects_path,
project_list_endpoint: security_projects_path,
instance_dashboard_settings_path: settings_security_dashboard_path,
vulnerabilities_export_endpoint: expose_path(api_v4_security_vulnerability_exports_path)
vulnerabilities_export_endpoint: expose_path(api_v4_security_vulnerability_exports_path),
scanners: VulnerabilityScanners::ListService.new(InstanceSecurityDashboard.new(current_user)).execute.to_json
}
end
......
# frozen_string_literal: true
module VulnerabilityScanners
class ListService < BaseService
def initialize(vulnerable)
@vulnerable = vulnerable
end
def execute
@vulnerable
.vulnerability_scanners
.with_report_type
.map do |scanner|
{
external_id: scanner.external_id,
vendor: scanner.vendor,
report_type: ::Enums::Vulnerability.report_types.key(scanner.report_type).upcase
}
end
end
end
end
......@@ -161,7 +161,8 @@ RSpec.describe Groups::SecurityFeaturesHelper do
no_vulnerabilities_svg_path: '/images/illustrations/issues.svg',
empty_state_svg_path: '/images/illustrations/security-dashboard-empty-state.svg',
dashboard_documentation: '/help/user/application_security/security_dashboard/index',
vulnerabilities_export_endpoint: "/api/v4/security/groups/#{group.id}/vulnerability_exports"
vulnerabilities_export_endpoint: "/api/v4/security/groups/#{group.id}/vulnerability_exports",
scanners: '[]'
}
end
......
......@@ -155,12 +155,15 @@ RSpec.describe ProjectsHelper do
not_enabled_scanners_help_path: help_page_path('user/application_security/index', anchor: 'quick-start'),
no_pipeline_run_scanners_help_path: "/#{project.full_path}/-/pipelines/new",
auto_fix_documentation: help_page_path('user/application_security/index', anchor: 'auto-fix-merge-requests'),
auto_fix_mrs_path: end_with('/merge_requests?label_name=GitLab-auto-fix')
auto_fix_mrs_path: end_with('/merge_requests?label_name=GitLab-auto-fix'),
scanners: '[{"external_id":"security_vendor","vendor":"Security Vendor","report_type":"SAST"}]'
}
end
before do
create(:vulnerability, project: project)
scanner = create(:vulnerabilities_scanner, project: project, external_id: 'security_vendor')
create(:vulnerabilities_finding, project: project, scanner: scanner)
end
context 'without pipeline' do
......
......@@ -6,6 +6,8 @@ RSpec.describe SecurityHelper do
describe '#instance_security_dashboard_data' do
subject { instance_security_dashboard_data }
let_it_be(:current_user) { create(:user) }
it 'returns vulnerability, project, feedback, asset, and docs paths for the instance security dashboard' do
is_expected.to eq({
dashboard_documentation: help_page_path('user/application_security/security_dashboard/index', anchor: 'instance-security-dashboard'),
......@@ -15,7 +17,8 @@ RSpec.describe SecurityHelper do
project_add_endpoint: security_projects_path,
project_list_endpoint: security_projects_path,
instance_dashboard_settings_path: settings_security_dashboard_path,
vulnerabilities_export_endpoint: api_v4_security_vulnerability_exports_path
vulnerabilities_export_endpoint: api_v4_security_vulnerability_exports_path,
scanners: '[]'
})
end
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe VulnerabilityScanners::ListService do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) }
let_it_be(:vulnerability_scanner) { create(:vulnerabilities_scanner, project: project, external_id: 'external_vendor') }
let_it_be(:vulnerability_finding) { create(:vulnerabilities_finding, project: project, scanner: vulnerability_scanner) }
let(:service) { described_class.new(vulnerable) }
subject(:scanner_list) { service.execute }
context 'when looking for scanners for group' do
let(:vulnerable) { group }
it { is_expected.to eq([{ external_id: "external_vendor", vendor: "Security Vendor", report_type: "SAST" }]) }
end
context 'when looking for scanners for project' do
let(:vulnerable) { project }
it { is_expected.to eq([{ external_id: "external_vendor", vendor: "Security Vendor", report_type: "SAST" }]) }
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