Skip to content

Commit

Permalink
Encyption casting with encrypts before serialize
Browse files Browse the repository at this point in the history
A demonstration of how we can simplify encryption serialization and
deserialization if we call `encrypts` before `serialize`.
  • Loading branch information
djmb committed Aug 19, 2024
1 parent 475cfa2 commit 83c7b4f
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def cast(value)
end

def deserialize(value)
cast_type.deserialize decrypt(value)
decrypt(cast_type.deserialize(value))
end

def serialize(value)
Expand Down Expand Up @@ -81,7 +81,7 @@ def previous_type?
@previous_type
end

def decrypt_as_text(value)
def decrypt(value)
with_context do
unless value.nil?
if @default && @default == value
Expand All @@ -99,10 +99,6 @@ def decrypt_as_text(value)
end
end

def decrypt(value)
text_to_database_type decrypt_as_text(database_type_to_text(value))
end

def try_to_deserialize_with_previous_encrypted_types(value)
previous_types.each.with_index do |type, index|
break type.deserialize(value)
Expand All @@ -128,12 +124,11 @@ def serialize_with_oldest(value)
end

def serialize_with_current(value)
casted_value = cast_type.serialize(value)
casted_value = casted_value&.downcase if downcase?
encrypt(casted_value.to_s) unless casted_value.nil?
value = value&.downcase if downcase?
cast_type.serialize(encrypt(value.to_s)) unless value.nil?
end

def encrypt_as_text(value)
def encrypt(value)
with_context do
if encryptor.binary? && !cast_type.binary?
raise Errors::Encoding, "Binary encoded data can only be stored in binary columns"
Expand All @@ -143,10 +138,6 @@ def encrypt_as_text(value)
end
end

def encrypt(value)
text_to_database_type encrypt_as_text(value)
end

def encryptor
ActiveRecord::Encryption.encryptor
end
Expand All @@ -162,26 +153,6 @@ def decryption_options
def clean_text_scheme
@clean_text_scheme ||= ActiveRecord::Encryption::Scheme.new(downcase: downcase?, encryptor: ActiveRecord::Encryption::NullEncryptor.new)
end

def text_to_database_type(value)
if value && cast_type.binary?
ActiveModel::Type::Binary::Data.new(value)
else
value
end
end

def database_type_to_text(value)
if value && cast_type.binary?
if cast_type.is_a?(ActiveRecord::Type::Serialized)
cast_type.subtype.deserialize(value)
else
cast_type.deserialize(value)
end
else
value
end
end
end
end
end
2 changes: 1 addition & 1 deletion activerecord/test/models/book_encrypted.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ class EncryptedBookWithBinary < ActiveRecord::Base
class EncryptedBookWithSerializedBinary < ActiveRecord::Base
self.table_name = "encrypted_books"

serialize :logo, coder: JSON
encrypts :logo
serialize :logo, coder: JSON
end

class EncryptedBookWithCustomCompressor < ActiveRecord::Base
Expand Down
14 changes: 11 additions & 3 deletions activerecord/test/models/traffic_light_encrypted.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@

require "models/traffic_light"

class EncryptedTrafficLight < TrafficLight
class EncryptedTrafficLight < ActiveRecord::Base
self.table_name = "traffic_lights"

encrypts :state
serialize :state, type: Array
serialize :long_state, type: Array
end

class EncryptedTrafficLightWithStoreState < TrafficLight
store :state, accessors: %i[ color ], coder: ActiveRecord::Coders::JSON
class EncryptedTrafficLightWithStoreState < ActiveRecord::Base
self.table_name = "traffic_lights"

encrypts :state
serialize :state, type: Array
serialize :long_state, type: Array
store :state, accessors: %i[ color ], coder: ActiveRecord::Coders::JSON
end

0 comments on commit 83c7b4f

Please sign in to comment.