class ActiveRecord::Encryption::EncryptedAttributeType
An ActiveModel::Type::Value that encrypts/decrypts strings of text.
This is the central piece that connects the encryption system with encrypts
declarations in the model classes. Whenever you declare an attribute as encrypted, it configures an EncryptedAttributeType
for that attribute.
Attributes
cast_type[R]
scheme[R]
Public Class Methods
new(scheme:, cast_type: ActiveModel::Type::String.new, previous_type: false, default: nil)
click to toggle source
Options¶ ↑
-
:scheme
- AScheme
with the encryption properties for this attribute. -
:cast_type
- A type that will be used to serialize (before encrypting) and deserialize (after decrypting). ActiveModel::Type::String by default.
Calls superclass method
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 23 def initialize(scheme:, cast_type: ActiveModel::Type::String.new, previous_type: false, default: nil) super() @scheme = scheme @cast_type = cast_type @previous_type = previous_type @default = default end
Public Instance Methods
cast(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 31 def cast(value) cast_type.cast(value) end
changed_in_place?(raw_old_value, new_value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 51 def changed_in_place?(raw_old_value, new_value) old_value = raw_old_value.nil? ? nil : deserialize(raw_old_value) old_value != new_value end
deserialize(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 35 def deserialize(value) cast_type.deserialize decrypt(value) end
encrypted?(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 47 def encrypted?(value) with_context { encryptor.encrypted? value } end
serialize(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 39 def serialize(value) if serialize_with_oldest? serialize_with_oldest(value) else serialize_with_current(value) end end
support_unencrypted_data?()
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 61 def support_unencrypted_data? ActiveRecord::Encryption.config.support_unencrypted_data && scheme.support_unencrypted_data? && !previous_type? end
Private Instance Methods
build_previous_types_for(schemes)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 74 def build_previous_types_for(schemes) schemes.collect do |scheme| EncryptedAttributeType.new(scheme: scheme, previous_type: true) end end
clean_text_scheme()
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 162 def clean_text_scheme @clean_text_scheme ||= ActiveRecord::Encryption::Scheme.new(downcase: downcase?, encryptor: ActiveRecord::Encryption::NullEncryptor.new) end
database_type_to_text(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 174 def database_type_to_text(value) if value && cast_type.binary? binary_cast_type = cast_type.serialized? ? cast_type.subtype : cast_type binary_cast_type.deserialize(value) else value end end
decrypt(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 102 def decrypt(value) text_to_database_type decrypt_as_text(database_type_to_text(value)) end
decrypt_as_text(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 84 def decrypt_as_text(value) with_context do unless value.nil? if @default && @default == value value else encryptor.decrypt(value, **decryption_options) end end end rescue ActiveRecord::Encryption::Errors::Base => error if previous_types_without_clean_text.blank? handle_deserialize_error(error, value) else try_to_deserialize_with_previous_encrypted_types(value) end end
decryption_options()
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 158 def decryption_options { key_provider: key_provider }.compact end
encrypt(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 146 def encrypt(value) text_to_database_type encrypt_as_text(value) end
encrypt_as_text(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 136 def encrypt_as_text(value) with_context do if encryptor.binary? && !cast_type.binary? raise Errors::Encoding, "Binary encoded data can only be stored in binary columns" end encryptor.encrypt(value, **encryption_options) end end
encryption_options()
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 154 def encryption_options { key_provider: key_provider, cipher_options: { deterministic: deterministic? } }.compact end
encryptor()
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 150 def encryptor ActiveRecord::Encryption.encryptor end
handle_deserialize_error(error, value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 114 def handle_deserialize_error(error, value) if error.is_a?(Errors::Decryption) && support_unencrypted_data? value else raise error end end
previous_schemes_including_clean_text()
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 66 def previous_schemes_including_clean_text previous_schemes.including((clean_text_scheme if support_unencrypted_data?)).compact end
previous_type?()
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 80 def previous_type? @previous_type end
previous_types_without_clean_text()
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 70 def previous_types_without_clean_text @previous_types_without_clean_text ||= build_previous_types_for(previous_schemes) end
serialize_with_current(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 130 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? end
serialize_with_oldest(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 126 def serialize_with_oldest(value) previous_types.first.serialize(value) end
serialize_with_oldest?()
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 122 def serialize_with_oldest? @serialize_with_oldest ||= fixed? && previous_types_without_clean_text.present? end
text_to_database_type(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 166 def text_to_database_type(value) if value && cast_type.binary? ActiveModel::Type::Binary::Data.new(value) else value end end
try_to_deserialize_with_previous_encrypted_types(value)
click to toggle source
# File lib/active_record/encryption/encrypted_attribute_type.rb, line 106 def try_to_deserialize_with_previous_encrypted_types(value) previous_types.each.with_index do |type, index| break type.deserialize(value) rescue ActiveRecord::Encryption::Errors::Base => error handle_deserialize_error(error, value) if index == previous_types.length - 1 end end