Commit 62680390 authored by Philip Cunningham's avatar Philip Cunningham

Associate successful DAST validations with sites

- Amends service to associate with existing validations
- Updates specs to be easier to understand

Changelog: changed
MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70140
EE: true
parent 550065c4
...@@ -38,7 +38,7 @@ module Mutations ...@@ -38,7 +38,7 @@ module Mutations
dast_site_token = dast_site_token_id.find dast_site_token = dast_site_token_id.find
response = ::DastSiteValidations::CreateService.new( response = ::DastSiteValidations::FindOrCreateService.new(
container: project, container: project,
current_user: current_user, current_user: current_user,
params: { params: {
......
# frozen_string_literal: true # frozen_string_literal: true
module DastSiteValidations module DastSiteValidations
class CreateService < BaseContainerService class FindOrCreateService < BaseContainerService
def execute def execute
return ServiceResponse.error(message: 'Insufficient permissions') unless allowed? return ServiceResponse.error(message: 'Insufficient permissions') unless allowed?
return ServiceResponse.success(payload: existing_validation) if existing_validation
dast_site_validation = create_validation! dast_site_validation = existing_successful_validation || create_validation!
return ServiceResponse.error(message: 'Site does not exist for profile') unless dast_site_validation.dast_site return ServiceResponse.error(message: 'Site does not exist for profile') unless dast_site_validation.dast_site
associate_dast_site!(dast_site_validation) associate_dast_site!(dast_site_validation)
return ServiceResponse.success(payload: dast_site_validation) if dast_site_validation.passed?
perform_runner_validation(dast_site_validation) perform_runner_validation(dast_site_validation)
rescue ActiveRecord::RecordInvalid => err rescue ActiveRecord::RecordInvalid => err
ServiceResponse.error(message: err.record.errors.full_messages) ServiceResponse.error(message: err.record.errors.full_messages)
...@@ -38,8 +39,8 @@ module DastSiteValidations ...@@ -38,8 +39,8 @@ module DastSiteValidations
@validation_strategy ||= params.fetch(:validation_strategy) @validation_strategy ||= params.fetch(:validation_strategy)
end end
def existing_validation def existing_successful_validation
@existing_validation ||= find_latest_successful_dast_site_validation @existing_successful_validation ||= find_latest_successful_dast_site_validation
end end
def url_base def url_base
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe DastSiteValidations::CreateService do RSpec.describe DastSiteValidations::FindOrCreateService do
let_it_be(:project) { create(:project, :repository) } let_it_be(:project) { create(:project, :repository) }
let_it_be(:developer) { create(:user, developer_projects: [project]) } let_it_be(:developer) { create(:user, developer_projects: [project]) }
let_it_be(:dast_site) { create(:dast_site, project: project) } let_it_be(:dast_site) { create(:dast_site, project: project) }
...@@ -12,7 +12,8 @@ RSpec.describe DastSiteValidations::CreateService do ...@@ -12,7 +12,8 @@ RSpec.describe DastSiteValidations::CreateService do
subject { described_class.new(container: project, current_user: developer, params: params).execute } subject { described_class.new(container: project, current_user: developer, params: params).execute }
shared_examples 'the licensed feature is not available' do describe 'execute', :clean_gitlab_redis_shared_state do
context 'when the licensed feature is available' do
it 'communicates failure' do it 'communicates failure' do
stub_licensed_features(security_on_demand_scans: false) stub_licensed_features(security_on_demand_scans: false)
...@@ -23,7 +24,7 @@ RSpec.describe DastSiteValidations::CreateService do ...@@ -23,7 +24,7 @@ RSpec.describe DastSiteValidations::CreateService do
end end
end end
shared_examples 'the licensed feature is available' do context 'when the licensed feature is available' do
before do before do
stub_licensed_features(security_on_demand_scans: true) stub_licensed_features(security_on_demand_scans: true)
end end
...@@ -40,6 +41,14 @@ RSpec.describe DastSiteValidations::CreateService do ...@@ -40,6 +41,14 @@ RSpec.describe DastSiteValidations::CreateService do
expect(subject.payload).to eq(dast_site.reload.dast_site_validation) expect(subject.payload).to eq(dast_site.reload.dast_site_validation)
end end
it 'attempts to validate' do
expected_args = { project: project, current_user: developer, params: { dast_site_validation: instance_of(DastSiteValidation) } }
expect(AppSec::Dast::SiteValidations::RunnerService).to receive(:new).with(expected_args).and_call_original
subject
end
context 'when a param is missing' do context 'when a param is missing' do
let(:params) { { dast_site_token: dast_site_token, validation_strategy: :text_file } } let(:params) { { dast_site_token: dast_site_token, validation_strategy: :text_file } }
...@@ -72,38 +81,27 @@ RSpec.describe DastSiteValidations::CreateService do ...@@ -72,38 +81,27 @@ RSpec.describe DastSiteValidations::CreateService do
end end
end end
end end
end
shared_examples 'a dast_site_validation already exists' do context 'when the site has already passed validation' do
let!(:dast_site_validation) { create(:dast_site_validation, dast_site_token: dast_site_token, state: :passed) } let_it_be(:dast_site_validation) { create(:dast_site_validation, dast_site_token: dast_site_token, state: :passed) }
it 'returns the existing successful dast_site_validation' do it 'returns the existing dast_site_validation' do
expect(subject.payload).to eq(dast_site_validation) expect(subject.payload).to eq(dast_site_validation)
end end
it 'does not create a new record in the database' do it 'does not create a new record in the database' do
expect { subject }.not_to change { DastSiteValidation.count } expect { subject }.not_to change { DastSiteValidation.count }
end end
end
describe 'execute', :clean_gitlab_redis_shared_state do
it_behaves_like 'the licensed feature is not available'
it_behaves_like 'the licensed feature is available' do
it 'attempts to validate' do
expected_args = { project: project, current_user: developer, params: { dast_site_validation: instance_of(DastSiteValidation) } }
expect(AppSec::Dast::SiteValidations::RunnerService).to receive(:new).with(expected_args).and_call_original
subject
end
it_behaves_like 'a dast_site_validation already exists' do
it 'does not attempt to re-validate' do it 'does not attempt to re-validate' do
expect(AppSec::Dast::SiteValidations::RunnerService).not_to receive(:new) expect(AppSec::Dast::SiteValidations::RunnerService).not_to receive(:new)
subject subject
end end
it 'associates the dast_site_validation with the dast_site' do
expect(subject.payload).to eq(dast_site.reload.dast_site_validation)
end
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