Commit 5aec1a52 authored by Saikat Sarkar's avatar Saikat Sarkar

Add false-positive for pipeline finding in GraphQL query

parent 3186628d
......@@ -11600,6 +11600,7 @@ Represents vulnerability finding of a security report on the pipeline.
| ---- | ---- | ----------- |
| <a id="pipelinesecurityreportfindingconfidence"></a>`confidence` | [`String`](#string) | Type of the security report that found the vulnerability. |
| <a id="pipelinesecurityreportfindingdescription"></a>`description` | [`String`](#string) | Description of the vulnerability finding. |
| <a id="pipelinesecurityreportfindingfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. Available only when feature flag `vulnerability_flags` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
| <a id="pipelinesecurityreportfindingidentifiers"></a>`identifiers` | [`[VulnerabilityIdentifier!]!`](#vulnerabilityidentifier) | Identifiers of the vulnerabilit finding. |
| <a id="pipelinesecurityreportfindinglocation"></a>`location` | [`VulnerabilityLocation`](#vulnerabilitylocation) | Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability. |
| <a id="pipelinesecurityreportfindingname"></a>`name` | [`String`](#string) | Name of the vulnerability finding. |
......
......@@ -27,6 +27,13 @@ module Types
null: true,
description: 'Type of the security report that found the vulnerability.'
field :false_positive,
type: GraphQL::Types::Boolean,
null: true,
description: 'Indicates whether the vulnerability is a false positive.',
resolver_method: :false_positive?,
feature_flag: :vulnerability_flags
field :scanner,
type: VulnerabilityScannerType,
null: true,
......@@ -78,6 +85,12 @@ module Types
def location
object.location&.merge(report_type: object.report_type)
end
def false_positive?
return unless object.project.licensed_feature_available?(:sast_fp_reduction)
object.vulnerability_flags.any?(&:false_positive?)
end
end
# rubocop: enable Graphql/AuthorizeTypes
end
......@@ -3,7 +3,11 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['PipelineSecurityReportFinding'] do
let_it_be(:fields) do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:pipeline) { create(:ci_pipeline, :with_sast_report, project: project) }
let(:fields) do
%i[report_type
name
severity
......@@ -15,11 +19,84 @@ RSpec.describe GitlabSchema.types['PipelineSecurityReportFinding'] do
project
description
location
falsePositive
solution
state]
end
before do
stub_licensed_features(sast: true, security_dashboard: true, sast_fp_reduction: true)
project.add_developer(user)
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
specify { expect(described_class.graphql_name).to eq('PipelineSecurityReportFinding') }
it { expect(described_class).to have_graphql_fields(fields) }
describe 'false_positive' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
falsePositive
}
}
}
}
}
)
end
context 'when the vulnerability has a false-positive flag' do
before do
security_finding = pipeline.security_reports.reports['sast'].findings.first
vulnerability_finding = create(:vulnerabilities_finding, uuid: security_finding.uuid, pipelines: [pipeline], project: pipeline.project)
create(:vulnerabilities_flag, finding: vulnerability_finding)
end
it 'returns false-positive value' do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
expect(vulnerabilities.first['falsePositive']).to be(true)
expect(vulnerabilities.last['falsePositive']).to be(false)
end
end
context 'when the vulnerability does not have any false-positive flag' do
it 'returns false for false-positive field' do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
expect(vulnerabilities.first['falsePositive']).to be(false)
end
end
context 'when there exists no license' do
before do
stub_licensed_features(sast: true, security_dashboard: true, sast_fp_reduction: false)
end
it 'returns nil for false-positive field' do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
expect(vulnerabilities.first['falsePositive']).to be_nil
end
end
context 'when vulnerability_flags FF has been disabled' do
before do
stub_feature_flags(vulnerability_flags: false)
end
it 'exposes an error message' do
error_msg = subject.dig('errors').first['message']
expect(error_msg).to eql("Field 'falsePositive' doesn't exist on type 'PipelineSecurityReportFinding'")
end
end
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