Skip to content
Snippets Groups Projects

Fix n plus one issue ci build dast profile

All threads resolved!
2 files
+ 169
51
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -6,78 +6,84 @@ module Profiles
@@ -6,78 +6,84 @@ module Profiles
class CreateAssociationsService < BaseProjectService
class CreateAssociationsService < BaseProjectService
include ::Gitlab::Ci::Pipeline::Chain::Helpers
include ::Gitlab::Ci::Pipeline::Chain::Helpers
def initialize(project:, current_user: nil, params: {})
super(project: project, current_user: current_user, params: params)
@builds = params[:builds] || []
@dast_site_profiles_builds = []
@dast_scanner_profiles_builds = []
end
def execute
def execute
return ServiceResponse.error(message: _('Insufficient permissions for dast_configuration keyword')) unless allowed?
return ServiceResponse.error(message: _('Insufficient permissions for dast_configuration keyword')) unless allowed?
dast_site_profiles = find_dast_site_profiles(project.id)
dast_site_profiles = find_dast_site_profiles
dast_scanner_profiles = find_dast_scanner_profiles(project.id)
dast_scanner_profiles = find_dast_scanner_profiles
prepare_builds(dast_scanner_profiles, dast_site_profiles)
dast_site_profiles_builds, dast_scanner_profiles_builds = prepare_batch_inserts(dast_scanner_profiles, dast_site_profiles)
return ServiceResponse.error(message: errors) unless errors.empty?
return ServiceResponse.error(message: errors) unless errors.empty?
insert_builds
insert_builds(dast_site_profiles_builds, dast_scanner_profiles_builds)
 
ServiceResponse.success(payload: @builds)
ServiceResponse.success(payload: @builds)
end
end
private
private
def prepare_builds(dast_scanner_profiles, dast_site_profiles)
def allowed?
@builds.each do |build|
can?(current_user, :create_on_demand_dast_scan, project)
next unless build.is_a?(::Ci::Build)
end
if build.options.dig(:dast_configuration, :site_profile).present?
dast_site_profile = dast_site_profiles.find { |dsp| dsp.name == build.options[:dast_configuration][:site_profile] }
@dast_site_profiles_builds.append({ ci_build_id: build.id, dast_site_profile_id: dast_site_profile.id }) if has_permission?(dast_site_profile, build.options[:dast_configuration][:site_profile])
end
if build.options.dig(:dast_configuration, :scanner_profile).present?
def has_permission?(profile, name)
dast_scanner_profile = dast_scanner_profiles.find { |dsp| dsp.name == build.options[:dast_configuration][:scanner_profile] }
if can?(current_user, :read_on_demand_dast_scan, profile)
@dast_scanner_profiles_builds.append({ ci_build_id: build.id, dast_scanner_profile_id: dast_scanner_profile.id }) if has_permission?(dast_scanner_profile, build.options[:dast_configuration][:scanner_profile])
true
end
else
 
errors.push(_('DAST profile not found: %{name}') % { name: name })
 
false
end
end
end
end
 
def builds
 
@builds ||= params[:builds] || []
 
end
 
def errors
def errors
@errors ||= []
@errors ||= []
end
end
def find_dast_site_profiles(project_id)
def prepare_batch_inserts(dast_scanner_profiles, dast_site_profiles)
dast_site_profiles_names = @builds.collect {|build| build.options[:dast_configuration][:site_profile] if build.options[:dast_configuration]}
dast_site_profiles_builds = []
DastSiteProfilesFinder.new(project_id: project_id, names: dast_site_profiles_names).execute
dast_scanner_profiles_builds = []
end
def find_dast_scanner_profiles(project_id)
builds.each do |build|
dast_scanner_profiles_names = @builds.collect {|build| build.options[:dast_configuration][:scanner_profile] if build.options[:dast_configuration]}
next unless build.is_a?(::Ci::Build)
DastScannerProfilesFinder.new(project_id: project_id, names: dast_scanner_profiles_names).execute
 
if (site_profile_name = build.options.dig(:dast_configuration, :site_profile))
 
dast_site_profile = dast_site_profiles.find { |dsp| dsp.name == site_profile_name }
 
 
dast_site_profiles_builds.append({ ci_build_id: build.id, dast_site_profile_id: dast_site_profile.id }) if has_permission?(dast_site_profile, site_profile_name)
 
end
 
 
if (scanner_profile_name = build.options.dig(:dast_configuration, :scanner_profile))
 
dast_scanner_profile = dast_scanner_profiles.find { |dsp| dsp.name == scanner_profile_name }
 
 
dast_scanner_profiles_builds.append({ ci_build_id: build.id, dast_scanner_profile_id: dast_scanner_profile.id }) if has_permission?(dast_scanner_profile, scanner_profile_name)
 
end
 
end
 
 
[dast_site_profiles_builds, dast_scanner_profiles_builds]
end
end
def insert_builds
def find(key, with:)
return unless @dast_site_profiles_builds.present? && @dast_scanner_profiles_builds.present?
names = builds.map { |build| build.options.dig(:dast_configuration, key) }.compact
::Dast::SiteProfilesBuild.insert_all(@dast_site_profiles_builds, unique_by: 'ci_build_id')
with.new(project_id: project.id, names: names).execute
 
end
::Dast::ScannerProfilesBuild.insert_all(@dast_scanner_profiles_builds, unique_by: 'ci_build_id')
def find_dast_site_profiles
 
find(:site_profile, with: DastSiteProfilesFinder)
end
end
def has_permission?(profile, name)
def find_dast_scanner_profiles
if can?(current_user, :read_on_demand_dast_scan, profile)
find(:scanner_profile, with: DastScannerProfilesFinder)
true
else
errors.push(_('DAST profile not found: %{name}') % { name: name })
false
end
end
end
def allowed?
def insert_builds(dast_site_profiles_builds, dast_scanner_profiles_builds)
can?(current_user, :create_on_demand_dast_scan, project)
::Dast::SiteProfilesBuild.insert_all(dast_site_profiles_builds, unique_by: 'ci_build_id') unless dast_site_profiles_builds.empty?
 
::Dast::ScannerProfilesBuild.insert_all(dast_scanner_profiles_builds, unique_by: 'ci_build_id') unless dast_scanner_profiles_builds.empty?
end
end
end
end
end
end
Loading