Commit 12cc3fee authored by Philip Cunningham's avatar Philip Cunningham Committed by Dylan Griffith

Centralise feature flag checking of on-demand DAST

Switches feature flag over to new policy with additional checks.
parent 2bd832e5
......@@ -21,11 +21,10 @@ module Mutations
required: true,
description: 'ID of the site profile to be used for the scan.'
authorize :run_ondemand_dast_scan
authorize :create_on_demand_dast_scan
def resolve(full_path:, dast_site_profile_id:)
project = authorized_find!(full_path: full_path)
raise_resource_not_available_error! unless Feature.enabled?(:security_on_demand_scans_feature_flag, project, default_enabled: true)
dast_site_profile = find_dast_site_profile(project: project, dast_site_profile_id: dast_site_profile_id)
dast_site = dast_site_profile.dast_site
......
......@@ -27,11 +27,10 @@ module Mutations
required: false,
description: 'The maximum number of seconds allowed for the site under test to respond to a request.'
authorize :run_ondemand_dast_scan
authorize :create_on_demand_dast_scan
def resolve(full_path:, profile_name:, spider_timeout: nil, target_timeout: nil)
project = authorized_find!(full_path: full_path)
raise_resource_not_available_error! unless Feature.enabled?(:security_on_demand_scans_feature_flag, project, default_enabled: true)
service = ::DastScannerProfiles::CreateService.new(project, current_user)
result = service.execute(name: profile_name, spider_timeout: spider_timeout, target_timeout: target_timeout)
......
......@@ -23,11 +23,10 @@ module Mutations
required: false,
description: 'The URL of the target to be scanned.'
authorize :run_ondemand_dast_scan
authorize :create_on_demand_dast_scan
def resolve(full_path:, profile_name:, target_url: nil)
project = authorized_find!(full_path: full_path)
raise_resource_not_available_error! unless Feature.enabled?(:security_on_demand_scans_feature_flag, project, default_enabled: true)
service = ::DastSiteProfiles::CreateService.new(project, current_user)
result = service.execute(name: profile_name, target_url: target_url)
......
......@@ -15,13 +15,12 @@ module Mutations
required: true,
description: 'ID of the site profile to be deleted.'
authorize :run_ondemand_dast_scan
authorize :create_on_demand_dast_scan
def resolve(full_path:, id:)
project = authorized_find!(full_path: full_path)
raise_resource_not_available_error! unless Feature.enabled?(:security_on_demand_scans_feature_flag, project, default_enabled: true)
dast_site_profile = find_dast_site_profile(project: project, global_id: id)
return { errors: dast_site_profile.errors.full_messages } unless dast_site_profile.destroy
{ errors: [] }
......
......@@ -27,11 +27,10 @@ module Mutations
required: false,
description: 'The URL of the target to be scanned.'
authorize :run_ondemand_dast_scan
authorize :create_on_demand_dast_scan
def resolve(full_path:, **service_args)
project = authorized_find!(full_path: full_path)
raise_resource_not_available_error! unless Feature.enabled?(:security_on_demand_scans_feature_flag, project, default_enabled: true)
service = ::DastSiteProfiles::UpdateService.new(project, current_user)
result = service.execute(service_args)
......
......@@ -27,11 +27,10 @@ module Mutations
required: true,
description: 'The type of scan to be run.'
authorize :run_ondemand_dast_scan
authorize :create_on_demand_dast_scan
def resolve(project_path:, target_url:, branch:, scan_type:)
project = authorized_find!(full_path: project_path)
raise_resource_not_available_error! unless Feature.enabled?(:security_on_demand_scans_feature_flag, project, default_enabled: true)
service = Ci::RunDastScanService.new(project, current_user)
result = service.execute(branch: branch, target_url: target_url)
......
......@@ -5,7 +5,7 @@ module Types
graphql_name 'DastScannerProfile'
description 'Represents a DAST scanner profile.'
authorize :run_ondemand_dast_scan
authorize :create_on_demand_dast_scan
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the DAST scanner profile'
......
......@@ -219,7 +219,6 @@ module EE
enable :admin_feature_flag
enable :admin_feature_flags_user_lists
enable :read_ci_minutes_quota
enable :run_ondemand_dast_scan
end
rule { can?(:developer_access) & iterations_available }.policy do
......
......@@ -29,7 +29,7 @@ module Ci
private
def allowed?
Ability.allowed?(current_user, :run_ondemand_dast_scan, project)
Ability.allowed?(current_user, :create_on_demand_dast_scan, project)
end
def ci_yaml(target_url)
......
......@@ -19,7 +19,7 @@ module DastScannerProfiles
private
def allowed?
Ability.allowed?(current_user, :run_ondemand_dast_scan, project)
Ability.allowed?(current_user, :create_on_demand_dast_scan, project)
end
end
end
......@@ -20,7 +20,7 @@ module DastSiteProfiles
private
def allowed?
Ability.allowed?(current_user, :run_ondemand_dast_scan, project)
Ability.allowed?(current_user, :create_on_demand_dast_scan, project)
end
end
end
......@@ -25,7 +25,7 @@ module DastSiteProfiles
private
def allowed?
Ability.allowed?(current_user, :run_ondemand_dast_scan, project)
Ability.allowed?(current_user, :create_on_demand_dast_scan, project)
end
# rubocop: disable CodeReuse/ActiveRecord
......
......@@ -13,7 +13,7 @@ module DastSites
private
def allowed?
Ability.allowed?(current_user, :run_ondemand_dast_scan, project)
Ability.allowed?(current_user, :create_on_demand_dast_scan, project)
end
def find_or_create_by!(url)
......
......@@ -12,6 +12,10 @@ RSpec.describe Mutations::DastOnDemandScans::Create do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#resolve' do
subject do
mutation.resolve(
......@@ -105,6 +109,14 @@ RSpec.describe Mutations::DastOnDemandScans::Create do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when on demand scan licensed feature is not available' do
it 'raises an exception' do
stub_licensed_features(security_on_demand_scans: false)
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
end
end
......
......@@ -12,6 +12,10 @@ RSpec.describe Mutations::DastScannerProfiles::Create do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#resolve' do
subject do
mutation.resolve(
......@@ -75,6 +79,14 @@ RSpec.describe Mutations::DastScannerProfiles::Create do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when on demand scan licensed feature is not available' do
it 'raises an exception' do
stub_licensed_features(security_on_demand_scans: false)
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
end
end
......@@ -13,6 +13,10 @@ RSpec.describe Mutations::DastSiteProfiles::Create do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#resolve' do
subject do
mutation.resolve(
......@@ -22,17 +26,7 @@ RSpec.describe Mutations::DastSiteProfiles::Create do
)
end
context 'when on demand scan feature is not enabled' do
it 'raises an exception' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when on demand scan feature is enabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: true)
end
context 'when the project does not exist' do
let(:full_path) { SecureRandom.hex }
......@@ -63,7 +57,7 @@ RSpec.describe Mutations::DastSiteProfiles::Create do
end
end
context 'when the user is a developer' do
context 'when the user can run a dast scan' do
before do
project.add_developer(user)
end
......@@ -95,6 +89,22 @@ RSpec.describe Mutations::DastSiteProfiles::Create do
expect(response[:errors]).to include('Name has already been taken')
end
end
context 'when on demand scan feature is not enabled' do
it 'raises an exception' do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when on demand scan licensed feature is not available' do
it 'raises an exception' do
stub_licensed_features(security_on_demand_scans: false)
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
end
end
......
......@@ -11,6 +11,10 @@ RSpec.describe Mutations::DastSiteProfiles::Delete do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#resolve' do
subject do
mutation.resolve(
......@@ -100,6 +104,14 @@ RSpec.describe Mutations::DastSiteProfiles::Delete do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when on demand scan licensed feature is not available' do
it 'raises an exception' do
stub_licensed_features(security_on_demand_scans: false)
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
end
end
......
......@@ -14,6 +14,10 @@ RSpec.describe Mutations::DastSiteProfiles::Update do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#resolve' do
subject do
mutation.resolve(
......@@ -100,6 +104,14 @@ RSpec.describe Mutations::DastSiteProfiles::Update do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when on demand scan licensed feature is not available' do
it 'raises an exception' do
stub_licensed_features(security_on_demand_scans: false)
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
end
end
......
......@@ -13,6 +13,10 @@ RSpec.describe Mutations::Pipelines::RunDastScan do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#resolve' do
subject do
mutation.resolve(
......
......@@ -27,7 +27,7 @@ RSpec.describe GitlabSchema.types['DastScannerProfile'] do
end
specify { expect(described_class.graphql_name).to eq('DastScannerProfile') }
specify { expect(described_class).to require_graphql_authorizations(:run_ondemand_dast_scan) }
specify { expect(described_class).to require_graphql_authorizations(:create_on_demand_dast_scan) }
it { expect(described_class).to have_graphql_fields(fields) }
......
......@@ -5,44 +5,19 @@ require 'spec_helper'
RSpec.describe 'Running a DAST Scan' do
include GraphqlHelpers
let(:project) { create(:project, :repository, creator: current_user) }
let(:current_user) { create(:user) }
let(:full_path) { project.full_path }
let(:dast_site_profile) { create(:dast_site_profile, project: project) }
let(:mutation_name) { :dast_on_demand_scan_create }
let(:mutation) do
graphql_mutation(
:dast_on_demand_scan_create,
mutation_name,
full_path: full_path,
dast_site_profile_id: dast_site_profile.to_global_id.to_s
)
end
def mutation_response
graphql_mutation_response(:dast_on_demand_scan_create)
end
context 'when a user does not have access to the project' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
context 'when a user does not have access to run a dast scan on the project' do
before do
project.add_guest(current_user)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
"exist or you don't have permission to perform this action"]
end
context 'when a user has access to run a dast scan on the project' do
before do
project.add_developer(current_user)
end
it_behaves_like 'an on-demand scan mutation when user cannot run an on-demand scan'
it_behaves_like 'an on-demand scan mutation when user can run an on-demand scan' do
it 'returns a pipeline_url containing the correct path' do
post_graphql_mutation(mutation, current_user: current_user)
pipeline = Ci::Pipeline.last
......@@ -56,7 +31,7 @@ RSpec.describe 'Running a DAST Scan' do
context 'when wrong type of global id is passed' do
let(:mutation) do
graphql_mutation(
:dast_on_demand_scan_create,
mutation_name,
full_path: full_path,
dast_site_profile_id: dast_site_profile.dast_site.to_global_id.to_s
)
......@@ -81,15 +56,5 @@ RSpec.describe 'Running a DAST Scan' do
it_behaves_like 'a mutation that returns errors in the response', errors: ['error message']
end
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
"exist or you don't have permission to perform this action"]
end
end
end
......@@ -5,45 +5,20 @@ require 'spec_helper'
RSpec.describe 'Creating a DAST Scanner Profile' do
include GraphqlHelpers
let(:project) { create(:project, :repository, creator: current_user) }
let(:current_user) { create(:user) }
let(:full_path) { project.full_path }
let(:profile_name) { FFaker::Company.catch_phrase }
let(:dast_scanner_profile) { DastScannerProfile.find_by(project: project, name: profile_name) }
let(:mutation_name) { :dast_scanner_profile_create }
let(:mutation) do
graphql_mutation(
:dast_scanner_profile_create,
mutation_name,
full_path: full_path,
profile_name: profile_name
)
end
def mutation_response
graphql_mutation_response(:dast_scanner_profile_create)
end
context 'when a user does not have access to the project' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
"exist or you don't have permission to perform this action"]
end
context 'when a user does not have access to run a dast scan on the project' do
before do
project.add_guest(current_user)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
"exist or you don't have permission to perform this action"]
end
context 'when a user has access to run a DAST scan on the project' do
before do
project.add_developer(current_user)
end
it_behaves_like 'an on-demand scan mutation when user cannot run an on-demand scan'
it_behaves_like 'an on-demand scan mutation when user can run an on-demand scan' do
it 'returns the dast_scanner_profile id' do
post_graphql_mutation(mutation, current_user: current_user)
......@@ -61,15 +36,5 @@ RSpec.describe 'Creating a DAST Scanner Profile' do
expect(mutation_response["errors"]).to include('Name has already been taken')
end
end
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
"exist or you don't have permission to perform this action"]
end
end
end
......@@ -5,61 +5,34 @@ require 'spec_helper'
RSpec.describe 'Creating a DAST Site Profile' do
include GraphqlHelpers
let(:project) { create(:project, :repository, creator: current_user) }
let(:current_user) { create(:user) }
let(:full_path) { project.full_path }
let(:profile_name) { FFaker::Company.catch_phrase }
let(:target_url) { FFaker::Internet.uri(:https) }
let(:dast_site_profile) { DastSiteProfile.find_by(project: project, name: profile_name) }
let(:mutation_name) { :dast_site_profile_create }
let(:mutation) do
graphql_mutation(
:dast_site_profile_create,
mutation_name,
full_path: full_path,
profile_name: profile_name,
target_url: target_url
)
end
def mutation_response
graphql_mutation_response(:dast_site_profile_create)
end
context 'when on demand scan feature is not enabled' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
context 'when on demand scan feature is enabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: true)
end
it_behaves_like 'an on-demand scan mutation when user cannot run an on-demand scan'
it_behaves_like 'an on-demand scan mutation when user can run an on-demand scan' do
it 'returns the dast_site_profile id' do
subject
context 'when the user does not have permission to run a dast scan' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
expect(mutation_response["id"]).to eq(dast_site_profile.to_global_id.to_s)
end
context 'when the user can run a dast scan' do
context 'when an unknown error occurs' do
before do
project.add_developer(current_user)
allow(DastSiteProfile).to receive(:create!).and_raise(StandardError)
end
it 'returns the dast_site_profile id' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response["id"]).to eq(dast_site_profile.to_global_id.to_s)
end
context 'when an unknown error occurs' do
before do
allow(DastSiteProfile).to receive(:create!).and_raise(StandardError)
end
it_behaves_like 'a mutation that returns top-level errors', errors: ['Internal server error']
end
it_behaves_like 'a mutation that returns top-level errors', errors: ['Internal server error']
end
end
end
......@@ -5,52 +5,19 @@ require 'spec_helper'
RSpec.describe 'Creating a DAST Site Profile' do
include GraphqlHelpers
let(:project) { create(:project) }
let(:current_user) { create(:user) }
let(:full_path) { project.full_path }
let!(:dast_site_profile) { create(:dast_site_profile, project: project) }
let(:mutation_name) { :dast_site_profile_delete }
let(:mutation) do
graphql_mutation(
:dast_site_profile_delete,
mutation_name,
full_path: full_path,
id: dast_site_profile.to_global_id.to_s
)
end
def mutation_response
graphql_mutation_response(:dast_site_profile_delete)
end
subject { post_graphql_mutation(mutation, current_user: current_user) }
context 'when a user does not have access to the project' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
context 'when a user does not have access to run a dast scan on the project' do
before do
project.add_guest(current_user)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
context 'when a user has access to run a dast scan on the project' do
before do
project.add_developer(current_user)
end
it 'returns an empty errors array' do
subject
expect(mutation_response["errors"]).to be_empty
end
it_behaves_like 'an on-demand scan mutation when user cannot run an on-demand scan'
it_behaves_like 'an on-demand scan mutation when user can run an on-demand scan' do
it 'deletes the dast_site_profile' do
expect { subject }.to change { DastSiteProfile.count }.by(-1)
end
......@@ -77,41 +44,33 @@ RSpec.describe 'Creating a DAST Site Profile' do
context 'when wrong type of global id is passed' do
let(:mutation) do
graphql_mutation(
:dast_site_profile_delete,
mutation_name,
full_path: full_path,
id: dast_site_profile.dast_site.to_global_id.to_s
)
end
it 'returns a top-level error' do
subject
it_behaves_like 'a mutation that returns top-level errors' do
let(:match_errors) do
gid = dast_site_profile.dast_site.to_global_id
expect(graphql_errors.dig(0, 'message')).to include('does not represent an instance of DastSiteProfile')
eq(["Variable $dastSiteProfileDeleteInput of type DastSiteProfileDeleteInput! " \
"was provided invalid value for id (\"#{gid}\" does not represent an instance " \
"of DastSiteProfile)"])
end
end
end
context 'when the dast_site_profile belongs to a different project' do
let(:mutation) do
graphql_mutation(
:dast_site_profile_delete,
mutation_name,
full_path: create(:project).full_path,
id: dast_site_profile.to_global_id.to_s
)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
it_behaves_like 'a mutation that returns a top-level access error'
end
end
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
end
......@@ -5,17 +5,15 @@ require 'spec_helper'
RSpec.describe 'Creating a DAST Site Profile' do
include GraphqlHelpers
let(:project) { create(:project) }
let(:current_user) { create(:user) }
let(:full_path) { project.full_path }
let!(:dast_site_profile) { create(:dast_site_profile, project: project) }
let(:new_profile_name) { SecureRandom.hex }
let(:new_target_url) { FFaker::Internet.uri(:https) }
let(:mutation_name) { :dast_site_profile_update }
let(:mutation) do
graphql_mutation(
:dast_site_profile_update,
mutation_name,
full_path: full_path,
id: dast_site_profile.to_global_id.to_s,
profile_name: new_profile_name,
......@@ -24,38 +22,11 @@ RSpec.describe 'Creating a DAST Site Profile' do
end
def mutation_response
graphql_mutation_response(:dast_site_profile_update)
graphql_mutation_response(mutation_name)
end
subject { post_graphql_mutation(mutation, current_user: current_user) }
context 'when a user does not have access to the project' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
context 'when a user does not have access to run a dast scan on the project' do
before do
project.add_guest(current_user)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
context 'when a user has access to run a dast scan on the project' do
before do
project.add_developer(current_user)
end
it 'returns an empty errors array' do
subject
expect(mutation_response["errors"]).to be_empty
end
it_behaves_like 'an on-demand scan mutation when user cannot run an on-demand scan'
it_behaves_like 'an on-demand scan mutation when user can run an on-demand scan' do
it 'updates the dast_site_profile' do
subject
......@@ -84,7 +55,7 @@ RSpec.describe 'Creating a DAST Site Profile' do
context 'when wrong type of global id is passed' do
let(:mutation) do
graphql_mutation(
:dast_site_profile_update,
mutation_name,
full_path: full_path,
id: dast_site_profile.dast_site.to_global_id.to_s,
profile_name: new_profile_name,
......@@ -92,17 +63,21 @@ RSpec.describe 'Creating a DAST Site Profile' do
)
end
it 'returns a top-level error' do
subject
it_behaves_like 'a mutation that returns top-level errors' do
let(:match_errors) do
gid = dast_site_profile.dast_site.to_global_id
expect(graphql_errors.dig(0, 'message')).to include('does not represent an instance of DastSiteProfile')
eq(["Variable $dastSiteProfileUpdateInput of type DastSiteProfileUpdateInput! " \
"was provided invalid value for id (\"#{gid}\" does not represent an instance " \
"of DastSiteProfile)"])
end
end
end
context 'when the dast_site_profile belongs to a different project' do
let(:mutation) do
graphql_mutation(
:dast_site_profile_update,
mutation_name,
full_path: create(:project).full_path,
id: dast_site_profile.to_global_id.to_s,
profile_name: new_profile_name,
......@@ -110,19 +85,7 @@ RSpec.describe 'Creating a DAST Site Profile' do
)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
it_behaves_like 'a mutation that returns a top-level access error'
end
end
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
end
......@@ -26,6 +26,10 @@ RSpec.describe 'Running a DAST Scan' do
graphql_mutation_response(:run_dast_scan)
end
before do
stub_licensed_features(security_on_demand_scans: true)
end
context 'when on demand scan feature is not enabled' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
......
......@@ -40,7 +40,7 @@ RSpec.describe 'Query.project(fullPath).dastScannerProfiles' do
end
end
context 'when a user does not have access to run_ondemand_dast_scan' do
context 'when the user can run a dast scan' do
before do
project.add_guest(current_user)
end
......
......@@ -8,6 +8,10 @@ RSpec.describe Ci::RunDastScanService do
let(:branch) { project.default_branch }
let(:target_url) { FFaker::Internet.uri(:http) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '.ci_template' do
it 'builds a hash' do
expect(described_class.ci_template).to be_a(Hash)
......@@ -29,7 +33,7 @@ RSpec.describe Ci::RunDastScanService do
let(:pipeline) { subject.payload }
let(:message) { subject.message }
context 'when the user does not have permission to run a dast scan' do
context 'when a user does not have access to the project' do
it 'returns an error status' do
expect(status).to eq(:error)
end
......@@ -142,6 +146,34 @@ RSpec.describe Ci::RunDastScanService do
expect(message).to eq(full_error_messages)
end
end
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it 'returns an error status' do
expect(status).to eq(:error)
end
it 'populates message' do
expect(message).to eq('Insufficient permissions')
end
end
context 'when on demand scan licensed feature is not available' do
before do
stub_licensed_features(security_on_demand_scans: false)
end
it 'returns an error status' do
expect(status).to eq(:error)
end
it 'populates message' do
expect(message).to eq('Insufficient permissions')
end
end
end
end
end
......@@ -9,6 +9,10 @@ RSpec.describe DastScannerProfiles::CreateService do
let(:target_timeout) { 60 }
let(:spider_timeout) { 600 }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#execute' do
subject do
described_class.new(project, user).execute(
......@@ -83,6 +87,34 @@ RSpec.describe DastScannerProfiles::CreateService do
expect(message).to eq(['Name has already been taken'])
end
end
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it 'returns an error status' do
expect(status).to eq(:error)
end
it 'populates message' do
expect(message).to eq('Insufficient permissions')
end
end
context 'when on demand scan licensed feature is not available' do
before do
stub_licensed_features(security_on_demand_scans: false)
end
it 'returns an error status' do
expect(status).to eq(:error)
end
it 'populates message' do
expect(message).to eq('Insufficient permissions')
end
end
end
end
end
......@@ -8,6 +8,10 @@ RSpec.describe DastSiteProfiles::CreateService do
let(:name) { FFaker::Company.catch_phrase }
let(:target_url) { FFaker::Internet.uri(:http) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#execute' do
subject { described_class.new(project, user).execute(name: name, target_url: target_url) }
......@@ -16,7 +20,7 @@ RSpec.describe DastSiteProfiles::CreateService do
let(:errors) { subject.errors }
let(:payload) { subject.payload }
context 'when the user does not have permission to run a dast scan' do
context 'when a user does not have access to the project' do
it 'returns an error status' do
expect(status).to eq(:error)
end
......@@ -72,6 +76,34 @@ RSpec.describe DastSiteProfiles::CreateService do
expect(errors).to include('Url is blocked: Requests to localhost are not allowed')
end
end
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it 'returns an error status' do
expect(status).to eq(:error)
end
it 'populates message' do
expect(message).to eq('Insufficient permissions')
end
end
context 'when on demand scan licensed feature is not available' do
before do
stub_licensed_features(security_on_demand_scans: false)
end
it 'returns an error status' do
expect(status).to eq(:error)
end
it 'populates message' do
expect(message).to eq('Insufficient permissions')
end
end
end
end
end
......@@ -10,6 +10,10 @@ RSpec.describe DastSiteProfiles::UpdateService do
let(:new_profile_name) { SecureRandom.hex }
let(:new_target_url) { FFaker::Internet.uri(:https) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#execute' do
subject do
described_class.new(project, user).execute(
......@@ -24,7 +28,7 @@ RSpec.describe DastSiteProfiles::UpdateService do
let(:errors) { subject.errors }
let(:payload) { subject.payload }
context 'when the user does not have permission to run a dast scan' do
context 'when a user does not have access to the project' do
it 'returns an error status' do
expect(status).to eq(:error)
end
......@@ -81,6 +85,34 @@ RSpec.describe DastSiteProfiles::UpdateService do
expect(message).to eq('DastSiteProfile not found')
end
end
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it 'returns an error status' do
expect(status).to eq(:error)
end
it 'populates message' do
expect(message).to eq('Insufficient permissions')
end
end
context 'when on demand scan licensed feature is not available' do
before do
stub_licensed_features(security_on_demand_scans: false)
end
it 'returns an error status' do
expect(status).to eq(:error)
end
it 'populates message' do
expect(message).to eq('Insufficient permissions')
end
end
end
end
end
......@@ -7,10 +7,14 @@ RSpec.describe DastSites::FindOrCreateService do
let(:project) { create(:project, :repository, creator: user) }
let(:url) { FFaker::Internet.uri(:http) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#execute!' do
subject { described_class.new(project, user).execute!(url: url) }
context 'when the user does not have permission to run a dast scan' do
context 'when a user does not have access to the project' do
it 'raises an exception' do
expect { subject }.to raise_error(DastSites::FindOrCreateService::PermissionsError) do |err|
expect(err.message).to include('Insufficient permissions')
......@@ -54,6 +58,26 @@ RSpec.describe DastSites::FindOrCreateService do
end
end
end
context 'when on demand scan feature is disabled' do
it 'raises an exception' do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
expect { subject }.to raise_error(DastSites::FindOrCreateService::PermissionsError) do |err|
expect(err.message).to include('Insufficient permissions')
end
end
end
context 'when on demand scan licensed feature is not available' do
it 'raises an exception' do
stub_licensed_features(security_on_demand_scans: false)
expect { subject }.to raise_error(DastSites::FindOrCreateService::PermissionsError) do |err|
expect(err.message).to include('Insufficient permissions')
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
# There must be a method or let called `mutation` defined that executes
# the mutation and one called `mutation_name` that is the name of the
# mutation being executed.
RSpec.shared_examples 'an on-demand scan mutation when user can run an on-demand scan' do
let(:project) { create(:project, :repository, creator: current_user) }
let(:current_user) { create(:user) }
let(:full_path) { project.full_path }
def mutation_response
graphql_mutation_response(mutation_name)
end
subject { post_graphql_mutation(mutation, current_user: current_user) }
before do
stub_licensed_features(security_on_demand_scans: true)
project.add_developer(current_user)
end
it 'returns an empty errors array' do
subject
expect(mutation_response["errors"]).to be_empty
end
context 'when on demand scan feature is disabled' do
before do
stub_feature_flags(security_on_demand_scans_feature_flag: false)
end
it_behaves_like 'a mutation that returns a top-level access error'
end
context 'when on demand scan licensed feature is not available' do
before do
stub_licensed_features(security_on_demand_scans: false)
end
it_behaves_like 'a mutation that returns a top-level access error'
end
end
# frozen_string_literal: true
require 'spec_helper'
# There must be a method or let called `mutation` defined that executes
# the mutation and one called `mutation_name` that is the name of the
# mutation being executed.
RSpec.shared_examples 'an on-demand scan mutation when user cannot run an on-demand scan' do
let(:project) { create(:project, :repository, creator: current_user) }
let(:current_user) { create(:user) }
let(:full_path) { project.full_path }
before do
stub_licensed_features(security_on_demand_scans: true)
end
context 'when a user does not have access to the project' do
it_behaves_like 'a mutation that returns a top-level access error'
end
context 'when a user does not have access to run a dast scan on the project' do
before do
project.add_guest(current_user)
end
it_behaves_like 'a mutation that returns a top-level access error'
end
end
......@@ -19,6 +19,13 @@ RSpec.shared_examples 'a mutation that returns top-level errors' do |errors: []|
end
end
# There must be a method or let called `mutation` defined that executes
# the mutation.
RSpec.shared_examples 'a mutation that returns a top-level access error' do
include_examples 'a mutation that returns top-level errors',
errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
end
RSpec.shared_examples 'an invalid argument to the mutation' do |argument_name:|
it_behaves_like 'a mutation that returns top-level errors' do
let(:match_errors) do
......
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