Class: ActiveRecord::Encryption::EncryptedAttributeType
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
|
|
Instance Chain:
|
|
Inherits: |
ActiveModel::Type::Value
|
Defined in: | activerecord/lib/active_record/encryption/encrypted_attribute_type.rb |
Overview
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.
Class Method Summary
-
.new(scheme:, cast_type: ActiveModel::Type::String.new, previous_type: false, default: nil) ⇒ EncryptedAttributeType
constructor
Options.
::ActiveModel::Type::Value
- Inherited
.new | Initializes a type with three basic configuration settings: precision, limit, and scale. |
Instance Attribute Summary
- #accessor readonly
- #cast_type readonly
- #key_provider readonly
- #previous_schemes readonly
- #scheme readonly
- #support_unencrypted_data? ⇒ Boolean readonly
- #type readonly
- #with_context readonly
- #previous_type? ⇒ Boolean readonly private
- #serialize_with_oldest? ⇒ Boolean readonly private
::ActiveModel::Type::Helpers::Mutable
- Included
::ActiveModel::Type::Value
- Inherited
#limit, #precision, #scale, | |
#binary? | These predicates are not documented, as I need to look further into their use, and see if they can be removed entirely. |
#mutable?, #serialized? |
Instance Method Summary
- #cast(value)
- #changed_in_place?(raw_old_value, new_value) ⇒ Boolean
- #deserialize(value)
- #deterministic? ⇒ Boolean
- #downcase? ⇒ Boolean
- #encrypted?(value) ⇒ Boolean
- #fixed? ⇒ Boolean
- #serialize(value)
- #build_previous_types_for(schemes) private
- #clean_text_scheme private
- #database_type_to_text(value) private
- #decrypt(value) private
- #decrypt_as_text(value) private
- #decryption_options private
- #encrypt(value) private
- #encrypt_as_text(value) private
- #encryption_options private
- #encryptor private
- #handle_deserialize_error(error, value) private
- #previous_schemes_including_clean_text private
- #previous_types_without_clean_text private
- #serialize_with_current(value) private
- #serialize_with_oldest(value) readonly private
- #text_to_database_type(value) private
- #try_to_deserialize_with_previous_encrypted_types(value) private
- #previous_types Internal use only
::ActiveModel::Type::Helpers::Mutable
- Included
#cast, | |
#changed_in_place? |
|
::ActiveModel::Type::Value
- Inherited
#==, #as_json, #assert_valid_value, | |
#cast |
|
#changed? | Determines whether a value has changed for dirty checking. |
#changed_in_place? | Determines whether the mutable value has been modified since it was read. |
#deserialize | Converts a value from database input to the appropriate ruby type. |
#eql? | Alias for ActiveModel::Type::Value#==. |
#hash, | |
#serializable? | Returns true if this type can convert |
#serialize | Casts a value from the ruby type to a type that the database knows how to understand. |
#type | Returns the unique type name as a |
#cast_value | Convenience method for types which do not need separate type casting behavior for user and database inputs. |
#force_equality?, #map, | |
#type_cast_for_schema |
|
#value_constructed_by_mass_assignment? |
::ActiveModel::Type::SerializeCastValue
- Included
Constructor Details
.new(scheme:, cast_type: ActiveModel::Type::String.new, previous_type: false, default: nil) ⇒ EncryptedAttributeType
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.
Instance Attribute Details
#accessor (readonly)
[ GitHub ]#cast_type (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 13
attr_reader :scheme, :cast_type
#key_provider (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 15
delegate :key_provider, :downcase?, :deterministic?, :previous_schemes, :with_context, :fixed?, to: :scheme
#previous_schemes (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 15
delegate :key_provider, :downcase?, :deterministic?, :previous_schemes, :with_context, :fixed?, to: :scheme
#previous_type? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 80
def previous_type? @previous_type end
#scheme (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 13
attr_reader :scheme, :cast_type
#serialize_with_oldest? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'activerecord/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
#support_unencrypted_data? ⇒ Boolean
(readonly)
[ GitHub ]
# File 'activerecord/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
#type (readonly)
[ GitHub ]#with_context (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 15
delegate :key_provider, :downcase?, :deterministic?, :previous_schemes, :with_context, :fixed?, to: :scheme
Instance Method Details
#build_previous_types_for(schemes) (private)
[ GitHub ]#cast(value)
[ GitHub ]# File 'activerecord/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) ⇒ Boolean
# File 'activerecord/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
#clean_text_scheme (private)
[ GitHub ]# File 'activerecord/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) (private)
[ GitHub ]# File 'activerecord/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) (private)
[ GitHub ]# File 'activerecord/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) (private)
[ GitHub ]# File 'activerecord/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, ** ) 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 (private)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 158
def { key_provider: key_provider }.compact end
#deserialize(value)
[ GitHub ]
#deterministic? ⇒ Boolean
# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 15
delegate :key_provider, :downcase?, :deterministic?, :previous_schemes, :with_context, :fixed?, to: :scheme
#downcase? ⇒ Boolean
# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 15
delegate :key_provider, :downcase?, :deterministic?, :previous_schemes, :with_context, :fixed?, to: :scheme
#encrypt(value) (private)
[ GitHub ]# File 'activerecord/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) (private)
[ GitHub ]
#encrypted?(value) ⇒ Boolean
# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 47
def encrypted?(value) with_context { encryptor.encrypted? value } end
#encryption_options (private)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 154
def { key_provider: key_provider, cipher_options: { deterministic: deterministic? } }.compact end
#encryptor (private)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 150
def encryptor ActiveRecord::Encryption.encryptor end
#fixed? ⇒ Boolean
# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 15
delegate :key_provider, :downcase?, :deterministic?, :previous_schemes, :with_context, :fixed?, to: :scheme
#handle_deserialize_error(error, value) (private)
[ GitHub ]# File 'activerecord/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 (private)
[ GitHub ]# File 'activerecord/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_types
# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 56
def previous_types # :nodoc: @previous_types ||= {} # Memoizing on support_unencrypted_data so that we can tweak it during tests @previous_types[support_unencrypted_data?] ||= build_previous_types_for(previous_schemes_including_clean_text) end
#previous_types_without_clean_text (private)
[ GitHub ]# File 'activerecord/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(value)
[ GitHub ]# File 'activerecord/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
#serialize_with_current(value) (private)
[ GitHub ]#serialize_with_oldest(value) (readonly, private)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 126
def serialize_with_oldest(value) previous_types.first.serialize(value) end
#text_to_database_type(value) (private)
[ GitHub ]#try_to_deserialize_with_previous_encrypted_types(value) (private)
[ GitHub ]# File 'activerecord/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