123456789_123456789_123456789_123456789_123456789_

Class: ActiveRecord::Encryption::MessagePackMessageSerializer

Overview

A message serializer that serializes Messages with ::ActiveRecord::MessagePack.

The message is converted to a hash with this structure:

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

Then it is converted to the ::ActiveRecord::MessagePack format.

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#binary?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/message_pack_message_serializer.rb', line 34

def binary?
  true
end

Instance Method Details

#dump(message)

[ GitHub ]

  
# File 'activerecord/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

#hash_to_message(data, level) (private)

[ GitHub ]

  
# File 'activerecord/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) (private)

[ GitHub ]

  
# File 'activerecord/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

#load(serialized_content)

[ GitHub ]

  
# File 'activerecord/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

#message_to_hash(message) (private)

[ GitHub ]

  
# File 'activerecord/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) (private)

[ GitHub ]

  
# File 'activerecord/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) (private)

[ GitHub ]

  
# File 'activerecord/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