diff options
Diffstat (limited to 'lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information.rb')
-rw-r--r-- | lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information.rb | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information.rb b/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information.rb new file mode 100644 index 00000000000..bc0a181a06c --- /dev/null +++ b/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +module Gitlab + module BackgroundMigration + # This class populates missing dismissal information for + # vulnerability entries. + class PopulateMissingVulnerabilityDismissalInformation + class Vulnerability < ActiveRecord::Base # rubocop:disable Style/Documentation + include EachBatch + + self.table_name = 'vulnerabilities' + + has_one :finding, class_name: '::Gitlab::BackgroundMigration::PopulateMissingVulnerabilityDismissalInformation::Finding' + + scope :broken, -> { where('state = 2 AND (dismissed_at IS NULL OR dismissed_by_id IS NULL)') } + + def copy_dismissal_information + return unless finding&.dismissal_feedback + + update_columns( + dismissed_at: finding.dismissal_feedback.created_at, + dismissed_by_id: finding.dismissal_feedback.author_id + ) + end + end + + class Finding < ActiveRecord::Base # rubocop:disable Style/Documentation + include ShaAttribute + + self.table_name = 'vulnerability_occurrences' + + sha_attribute :project_fingerprint + + def dismissal_feedback + Feedback.dismissal.where(category: report_type, project_fingerprint: project_fingerprint, project_id: project_id).first + end + end + + class Feedback < ActiveRecord::Base # rubocop:disable Style/Documentation + DISMISSAL_TYPE = 0 + + self.table_name = 'vulnerability_feedback' + + scope :dismissal, -> { where(feedback_type: DISMISSAL_TYPE) } + end + + def perform(*vulnerability_ids) + Vulnerability.includes(:finding).where(id: vulnerability_ids).each { |vulnerability| populate_for(vulnerability) } + + log_info(vulnerability_ids) + end + + private + + def populate_for(vulnerability) + log_warning(vulnerability) unless vulnerability.copy_dismissal_information + rescue StandardError => error + log_error(error, vulnerability) + end + + def log_info(vulnerability_ids) + ::Gitlab::BackgroundMigration::Logger.info( + migrator: self.class.name, + message: 'Dismissal information has been copied', + count: vulnerability_ids.length + ) + end + + def log_warning(vulnerability) + ::Gitlab::BackgroundMigration::Logger.warn( + migrator: self.class.name, + message: 'Could not update vulnerability!', + vulnerability_id: vulnerability.id + ) + end + + def log_error(error, vulnerability) + ::Gitlab::BackgroundMigration::Logger.error( + migrator: self.class.name, + message: error.message, + vulnerability_id: vulnerability.id + ) + end + end + end +end |