Commit b1232904 authored by Craig Smith's avatar Craig Smith

Implement saving the DAST scanner profiles

To allow dast users to save their scanner profiles
this commit implements the DastScannerProfiles
mutation
parent fead6db4
......@@ -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