blob: 45333e2effb938b1b2a1b3341c653e4717c90606 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# 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(
"> Something went wrong for #{instance.class.name}[#{instance.id}].#{attribute_name}: #{e}".color(: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
|