Commit 7d7c9a05 authored by Alper Akgun's avatar Alper Akgun

Merge branch 'sk/344687-scan-type-filter' into 'master'

Add scan action filter to scanExecutionPolicies graphql query

See merge request gitlab-org/gitlab!74393
parents ae86eeac 606e5427
......@@ -12855,7 +12855,6 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectrequestaccessenabled"></a>`requestAccessEnabled` | [`Boolean`](#boolean) | Indicates if users can request member access to the project. |
| <a id="projectrequirementstatescount"></a>`requirementStatesCount` | [`RequirementStatesCount`](#requirementstatescount) | Number of requirements for the project by their state. |
| <a id="projectsastciconfiguration"></a>`sastCiConfiguration` | [`SastCiConfiguration`](#sastciconfiguration) | SAST CI configuration for the project. |
| <a id="projectscanexecutionpolicies"></a>`scanExecutionPolicies` | [`ScanExecutionPolicyConnection`](#scanexecutionpolicyconnection) | Scan Execution Policies of the project. (see [Connections](#connections)) |
| <a id="projectsecuritydashboardpath"></a>`securityDashboardPath` | [`String`](#string) | Path to project's security dashboard. |
| <a id="projectsecurityscanners"></a>`securityScanners` | [`SecurityScanners`](#securityscanners) | Information about security analyzers used in the project. |
| <a id="projectsentryerrors"></a>`sentryErrors` | [`SentryErrorCollection`](#sentryerrorcollection) | Paginated collection of Sentry errors on the project. |
......@@ -13589,6 +13588,22 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectrequirementssort"></a>`sort` | [`Sort`](#sort) | List requirements by sort order. |
| <a id="projectrequirementsstate"></a>`state` | [`RequirementState`](#requirementstate) | Filter requirements by state. |
##### `Project.scanExecutionPolicies`
Scan Execution Policies of the project.
Returns [`ScanExecutionPolicyConnection`](#scanexecutionpolicyconnection).
This field returns a [connection](#connections). It accepts the
four standard [pagination arguments](#connection-pagination-arguments):
`before: String`, `after: String`, `first: Int`, `last: Int`.
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectscanexecutionpoliciesactionscantypes"></a>`actionScanTypes` | [`[SecurityReportTypeEnum!]`](#securityreporttypeenum) | Filters policies by the action scan type. Only these scan types are supported: `dast`, `secret_detection`, `cluster_image_scanning`, `container_scanning`. |
##### `Project.sentryDetailedError`
Detailed version of a Sentry error on the project.
......@@ -9,12 +9,20 @@ module Resolvers
alias_method :project, :object
argument :action_scan_types, [::Types::Security::ReportTypeEnum],
description: "Filters policies by the action scan type. "\
"Only these scan types are supported: #{Security::ScanExecutionPolicy::SCAN_TYPES.map { |type| "`#{type}`" }.join(', ')}.",
required: false
def resolve(**args)
return [] unless valid?
authorize!
policy_configuration.scan_execution_policy.map do |policy|
policies = policy_configuration.scan_execution_policy
policies = filter_scan_types(policies, args[:action_scan_types]) if args[:action_scan_types]
policies.map do |policy|
{
name: policy[:name],
description: policy[:description],
......@@ -37,6 +45,13 @@ module Resolvers
@policy_configuration ||= project.security_orchestration_policy_configuration
end
def filter_scan_types(policies, scan_types)
policies.filter do |policy|
policy_scan_types = policy[:actions].map { |action| action[:scan].to_sym }
(scan_types & policy_scan_types).present?
end
end
def valid?
policy_configuration.present? && policy_configuration.policy_configuration_valid?
end
......
......@@ -15,9 +15,10 @@ RSpec.describe Resolvers::ScanExecutionPolicyResolver do
let(:policy_yaml) { build(:orchestration_policy_yaml, scan_execution_policy: [policy]) }
let(:repository) { instance_double(Repository, root_ref: 'master', empty?: false) }
let(:args) { {} }
describe '#resolve' do
subject(:resolve_scan_policies) { resolve(described_class, obj: project, ctx: { current_user: user }) }
subject(:resolve_scan_policies) { resolve(described_class, obj: project, args: args, ctx: { current_user: user }) }
before do
commit = create(:commit)
......@@ -62,6 +63,43 @@ RSpec.describe Resolvers::ScanExecutionPolicyResolver do
expect { resolve_scan_policies }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when action_scan_types is given' do
context 'when there are multiple policies' do
let(:secret_detection_policy) do
build(
:scan_execution_policy,
name: 'Run secret detection in every pipeline',
description: 'Secret detection',
actions: [{ scan: 'secret_detection' }]
)
end
let(:policy_yaml) { build(:orchestration_policy_yaml, scan_execution_policy: [policy, secret_detection_policy]) }
let(:args) { { action_scan_types: [::Types::Security::ReportTypeEnum.values['DAST'].value] } }
it 'returns policy matching the given scan type' do
expected_resolved = [
{
name: 'Run DAST in every pipeline',
description: 'This policy enforces to run DAST for every pipeline within the project',
enabled: true,
yaml: YAML.dump(policy.deep_stringify_keys),
updated_at: policy_last_updated_at
}
]
expect(resolve_scan_policies).to eq(expected_resolved)
end
end
context 'when there are no matching policies' do
let(:args) { { action_scan_types: [::Types::Security::ReportTypeEnum.values['CONTAINER_SCANNING'].value] } }
it 'returns empty response' do
expect(resolve_scan_policies).to be_empty
end
end
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