class ActiveRecord::Encryption::MessagePackMessageSerializer

A message serializer that serializes Messages with MessagePack.

The message is converted to a hash with this structure:

{
  p: <payload>,
  h: {
    header1: value1,
    header2: value2,
    ...
  }
}

Then it is converted to the MessagePack format.

Public Instance Methods

binary?() click to toggle source
# File lib/active_record/encryption/message_pack_message_serializer.rb, line 34
def binary?
  true
end
dump(message) click to toggle source
# File lib/active_record/encryption/message_pack_message_serializer.rb, line 22
def dump(message)
  raise Errors::ForbiddenClass unless message.is_a?(Message)
  ActiveSupport::MessagePack.dump(message_to_hash(message))
end
load(serialized_content) click to toggle source
# File lib/active_record/encryption/message_pack_message_serializer.rb, line 27
def load(serialized_content)
  data = ActiveSupport::MessagePack.load(serialized_content)
  hash_to_message(data, 1)
rescue RuntimeError
  raise Errors::Decryption
end

Private Instance Methods

hash_to_message(data, level) click to toggle source
# File lib/active_record/encryption/message_pack_message_serializer.rb, line 52
def hash_to_message(data, level)
  validate_message_data_format(data, level)
  Message.new(payload: data["p"], headers: parse_properties(data["h"], level))
end
headers_to_hash(headers) click to toggle source
# File lib/active_record/encryption/message_pack_message_serializer.rb, line 46
def headers_to_hash(headers)
  headers.transform_values do |value|
    value.is_a?(Message) ? message_to_hash(value) : value
  end
end
message_to_hash(message) click to toggle source
# File lib/active_record/encryption/message_pack_message_serializer.rb, line 39
def message_to_hash(message)
  {
    "p" => message.payload,
    "h" => headers_to_hash(message.headers)
  }
end
parse_properties(headers, level) click to toggle source
# File lib/active_record/encryption/message_pack_message_serializer.rb, line 67
def parse_properties(headers, level)
  Properties.new.tap do |properties|
    headers&.each do |key, value|
      properties[key] = value.is_a?(Hash) ? hash_to_message(value, level + 1) : value
    end
  end
end
validate_message_data_format(data, level) click to toggle source
# File lib/active_record/encryption/message_pack_message_serializer.rb, line 57
def validate_message_data_format(data, level)
  if level > 2
    raise Errors::Decryption, "More than one level of hash nesting in headers is not supported"
  end

  unless data.is_a?(Hash) && data.has_key?("p")
    raise Errors::Decryption, "Invalid data format: hash without payload"
  end
end