Commit c4338646 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Merge branch 'store_dast_scanner_profiles_229729' into 'master'

Implement saving the DAST scanner profiles

See merge request gitlab-org/gitlab!38023
parents 6e515e1a b1232904
......@@ -33,8 +33,14 @@ module Mutations
project = authorized_find!(full_path: full_path)
raise_resource_not_available_error! unless Feature.enabled?(:security_on_demand_scans_feature_flag, project)
response = ServiceResponse.error(message: 'Not implemented')
{ errors: response.errors }
service = ::DastScannerProfiles::CreateService.new(project, current_user)
result = service.execute(name: profile_name, spider_timeout: spider_timeout, target_timeout: target_timeout)
if result.success?
{ id: result.payload.to_global_id, errors: [] }
else
{ errors: result.errors }
end
end
private
......
# frozen_string_literal: true
module DastScannerProfiles
class CreateService < BaseService
def execute(name:, target_timeout:, spider_timeout:)
return ServiceResponse.error(message: 'Insufficient permissions') unless allowed?
dast_scanner_profile = DastScannerProfile.create(
project: project,
name: name,
target_timeout: target_timeout,
spider_timeout: spider_timeout
)
return ServiceResponse.success(payload: dast_scanner_profile) if dast_scanner_profile.valid?
ServiceResponse.error(message: dast_scanner_profile.errors.full_messages)
end
private
def allowed?
Ability.allowed?(current_user, :run_ondemand_dast_scan, project)
end
end
end
......@@ -8,6 +8,7 @@ RSpec.describe Mutations::DastScannerProfiles::Create do
let(:user) { create(:user) }
let(:full_path) { project.full_path }
let(:profile_name) { SecureRandom.hex }
let(:dast_scanner_profile) { DastScannerProfile.find_by(project: project, name: profile_name) }
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
......@@ -38,8 +39,31 @@ RSpec.describe Mutations::DastScannerProfiles::Create do
group.add_owner(user)
end
it 'stubs out the response' do
expect(subject[:errors]).to eq(['Not implemented'])
it 'returns the dast_scanner_profile id' do
expect(subject[:id]).to eq(dast_scanner_profile.to_global_id)
end
it 'calls the dast_scanner_profile creation service' do
service = double(described_class)
result = double('result', success?: false, errors: [])
expect(DastScannerProfiles::CreateService).to receive(:new).and_return(service)
expect(service).to receive(:execute).with(name: profile_name, spider_timeout: nil, target_timeout: nil).and_return(result)
subject
end
context 'when the dast_scanner_profile already exists' do
it 'returns an error' do
subject
response = mutation.resolve(
full_path: full_path,
profile_name: profile_name
)
expect(response[:errors]).to include('Name has already been taken')
end
end
context 'when security_on_demand_scans_feature_flag is disabled' do
......
......@@ -9,6 +9,7 @@ RSpec.describe 'Creating a DAST Scanner Profile' do
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) do
graphql_mutation(
......@@ -43,7 +44,23 @@ RSpec.describe 'Creating a DAST Scanner Profile' do
project.add_developer(current_user)
end
it_behaves_like 'a mutation that returns errors in the response', errors: ['Not implemented']
it 'returns the dast_scanner_profile id' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response["id"]).to eq(dast_scanner_profile.to_global_id.to_s)
end
context 'when dast_scanner_profile exists' do
before do
DastScannerProfile.create!(project: project, name: profile_name)
end
it 'returns errors' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response["errors"]).to include('Name has already been taken')
end
end
context 'when on demand scan feature is disabled' do
before do
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe DastScannerProfiles::CreateService do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, creator: user) }
let(:name) { FFaker::Company.catch_phrase }
let(:target_timeout) { 60 }
let(:spider_timeout) { 600 }
describe '#execute' do
subject do
described_class.new(project, user).execute(
name: name,
target_timeout: target_timeout,
spider_timeout: spider_timeout
)
end
let(:status) { subject.status }
let(:message) { subject.message }
let(:errors) { subject.errors }
let(:payload) { subject.payload }
context 'when a user does not have access to a project' do
let(:project) { create(:project) }
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 the user does not have permission to run a dast scan' do
before do
project.add_guest(user)
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 the user can run a dast scan' do
before do
project.add_developer(user)
end
it 'returns a success status' do
expect(status).to eq(:success)
end
it 'creates a dast_scanner_profile' do
expect { subject }.to change(DastScannerProfile, :count).by(1)
end
it 'returns a dast_scanner_profile payload' do
expect(payload).to be_a(DastScannerProfile)
end
context 'when the dast_scanner_profile name exists' do
before do
create(:dast_scanner_profile, project: project, name: name)
end
it 'does not create a new dast_scanner_profile' do
expect { subject }.not_to change(DastScannerProfile, :count)
end
it 'returns an error status' do
expect(status).to eq(:error)
end
it 'populates message' do
expect(message).to eq(['Name has already been taken'])
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