class ActiveRecord::Encryption::MessageSerializer
Experimental RBS support (using type sampling data from the type_fusion
project).
# sig/active_record/encryption/message_serializer.rbs class ActiveRecord::Encryption::MessageSerializer def decode_if_needed: (true value) -> untyped end
storing the resulting serialized data.
to prevent JSON parsing errors and encoding issues when
Both the payload and the header values are encoded with Base64
}
}
…
header2: value2,
header1: value1,
h: {
p: <payload>,
{
The generated structure is pretty simple:
A message serializer that serializes Messages
with JSON.
def decode_if_needed(value)
Experimental RBS support (using type sampling data from the type_fusion
project).
def decode_if_needed: (true value) -> untyped
This signature was generated using 1 sample from 1 application.
def decode_if_needed(value) if value.is_a?(String) ::Base64.strict_decode64(value) else value end rescue ArgumentError, TypeError raise Errors::Encoding end
def dump(message)
def dump(message) raise ActiveRecord::Encryption::Errors::ForbiddenClass unless message.is_a?(ActiveRecord::Encryption::Message) JSON.dump message_to_json(message) end
def encode_if_needed(value)
def encode_if_needed(value) if value.is_a?(String) ::Base64.strict_encode64 value else value end end
def headers_to_json(headers)
def headers_to_json(headers) headers.transform_values do |value| value.is_a?(ActiveRecord::Encryption::Message) ? message_to_json(value) : encode_if_needed(value) end end
def load(serialized_content)
def load(serialized_content) data = JSON.parse(serialized_content) parse_message(data, 1) rescue JSON::ParserError raise ActiveRecord::Encryption::Errors::Encoding end
def message_to_json(message)
def message_to_json(message) { p: encode_if_needed(message.payload), h: headers_to_json(message.headers) } end
def parse_message(data, level)
def parse_message(data, level) validate_message_data_format(data, level) ActiveRecord::Encryption::Message.new(payload: decode_if_needed(data["p"]), headers: parse_properties(data["h"], level)) end
def parse_properties(headers, level)
def parse_properties(headers, level) ActiveRecord::Encryption::Properties.new.tap do |properties| headers&.each do |key, value| properties[key] = value.is_a?(Hash) ? parse_message(value, level + 1) : decode_if_needed(value) end end end
def validate_message_data_format(data, level)
def validate_message_data_format(data, level) if level > 2 raise ActiveRecord::Encryption::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 ActiveRecord::Encryption::Errors::Decryption, "Invalid data format: hash without payload" end end