class SidekiqFieldEncryptor::Base

Public Class Methods

new(options = {}) click to toggle source
# File lib/sidekiq-field-encryptor/encryptor.rb, line 29
def initialize(options = {})
  @encryption_key = options[:encryption_key]
  @encrypted_fields = options[:encrypted_fields] || {}
  @encryption_algorithm = options[:encryption_algorithm] || 'aes-256-gcm'

  @serialization_method = options[:serialization_method] || SERIALIZE_JSON
  @serialization_compat = options[:serialization_compat]
end

Public Instance Methods

assert_key_configured() click to toggle source
# File lib/sidekiq-field-encryptor/encryptor.rb, line 38
def assert_key_configured
  raise 'Encryption key not configured' if @encryption_key.nil?
end
decrypt(encrypted) click to toggle source
# File lib/sidekiq-field-encryptor/encryptor.rb, line 81
def decrypt(encrypted)
  base64_ciphertext, base64_iv, serialization_method = encrypted
  ciphertext = ::Base64.decode64(base64_ciphertext)
  iv = ::Base64.decode64(base64_iv)
  args = { key: @encryption_key, iv: iv, algorithm: @encryption_algorithm }
  plaintext = ::Encryptor.decrypt(ciphertext, **args)
  deserialize(serialization_method, plaintext)
end
deserialize(method, value) click to toggle source
# File lib/sidekiq-field-encryptor/encryptor.rb, line 53
def deserialize(method, value)
  if !@serialization_compat && method != @serialization_method
    raise "Invalid serialization_method received: #{method}"
  end

  case method
  when SERIALIZE_JSON
    JSON.parse(value, quirks_mode: true)
  when SERIALIZE_MARHSALL, nil
    # No method used to be Marshall, so we respect this here
    Marshal.load(value)
  else
    raise "Invalid serialization_method: #{@serialization_method}"
  end
end
encrypt(value) click to toggle source
# File lib/sidekiq-field-encryptor/encryptor.rb, line 69
def encrypt(value)
  plaintext = serialize(value)
  iv = OpenSSL::Cipher::Cipher.new(@encryption_algorithm).random_iv
  args = { key: @encryption_key, iv: iv, algorithm: @encryption_algorithm }
  ciphertext = ::Encryptor.encrypt(plaintext, **args)
  [
    ::Base64.encode64(ciphertext),
    ::Base64.encode64(iv),
    @serialization_method
  ]
end
process_message(message) { |raw_value| ... } click to toggle source
# File lib/sidekiq-field-encryptor/encryptor.rb, line 90
def process_message(message)
  fields = @encrypted_fields[message['class']]
  return unless fields
  assert_key_configured
  message['args'].size.times.each do |arg_index|
    to_encrypt = fields[arg_index]
    next unless to_encrypt
    raw_value = message['args'][arg_index]
    if to_encrypt == true
      message['args'][arg_index] = yield(raw_value)
    elsif to_encrypt.is_a?(Array) && raw_value.is_a?(Hash)
      message['args'][arg_index] = Hash[raw_value.map do |key, value|
        value = yield(value) if to_encrypt.member?(key.to_s)
        [key, value]
      end]
    end
  end
end
serialize(value) click to toggle source
# File lib/sidekiq-field-encryptor/encryptor.rb, line 42
def serialize(value)
  case @serialization_method
  when SERIALIZE_JSON
    JSON.generate(value, quirks_mode: true)
  when SERIALIZE_MARHSALL
    Marshal.dump(value)
  else
    raise "Invalid serialization_method: #{@serialization_method}"
  end
end