mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-06 10:19:48 +00:00
67 lines
2.1 KiB
Ruby
67 lines
2.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module Doctor
|
|
class ResetTokens
|
|
attr_reader :logger
|
|
|
|
PRINT_PROGRESS_EVERY = 1000
|
|
|
|
def initialize(logger, model_names:, token_names:, dry_run: true)
|
|
@logger = logger
|
|
@model_names = model_names
|
|
@token_names = token_names
|
|
@dry_run = dry_run
|
|
end
|
|
|
|
def run!
|
|
logger.info "Resetting #{@token_names.join(', ')} on #{@model_names.join(', ')} if they can not be read"
|
|
logger.info "Executing in DRY RUN mode, no records will actually be updated" if @dry_run
|
|
Rails.application.eager_load!
|
|
|
|
models_with_encrypted_tokens.each do |model|
|
|
fix_model(model)
|
|
end
|
|
logger.info "Done!"
|
|
end
|
|
|
|
private
|
|
|
|
def fix_model(model)
|
|
matched_token_names = @token_names & model.encrypted_token_authenticatable_fields.map(&:to_s)
|
|
|
|
return if matched_token_names.empty?
|
|
|
|
total_count = model.count
|
|
|
|
model.find_each.with_index do |instance, index|
|
|
matched_token_names.each do |attribute_name|
|
|
fix_attribute(instance, attribute_name)
|
|
end
|
|
|
|
logger.info "Checked #{index + 1}/#{total_count} #{model.name.pluralize}" if index % PRINT_PROGRESS_EVERY == 0
|
|
end
|
|
logger.info "Checked #{total_count} #{model.name.pluralize}"
|
|
end
|
|
|
|
def fix_attribute(instance, attribute_name)
|
|
instance.public_send(attribute_name) # rubocop:disable GitlabSecurity/PublicSend
|
|
rescue OpenSSL::Cipher::CipherError, TypeError
|
|
logger.debug "> Fix #{instance.class.name}[#{instance.id}].#{attribute_name}"
|
|
instance.public_send("reset_#{attribute_name}!") unless @dry_run # rubocop:disable GitlabSecurity/PublicSend
|
|
rescue StandardError => e
|
|
logger.debug(
|
|
Rainbow("> Something went wrong for #{instance.class.name}[#{instance.id}].#{attribute_name}: #{e}").red)
|
|
|
|
false
|
|
end
|
|
|
|
def models_with_encrypted_tokens
|
|
ApplicationRecord.descendants.select do |model|
|
|
@model_names.include?(model.name) && model.include?(TokenAuthenticatable)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|