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, | |
| #transforms_query_predicates? | Returns true if the type customizes how attributes and values are rendered in hash-based |
| #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
- #freeze
- #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, | |
| #query_attribute | Returns the |
| #query_value | Returns the |
| #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 - A
Schemewith 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 92
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 134
def serialize_with_oldest? return @serialize_with_oldest if defined?(@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 64
def 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 176
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 188
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 114
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 96
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 172
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 160
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 168
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 164
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
#freeze
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 68
def freeze serialize_with_oldest? previous_types_without_clean_text previous_types clean_text_scheme super end
#handle_deserialize_error(error, value) (private)
[ GitHub ]# File 'activerecord/lib/active_record/encryption/encrypted_attribute_type.rb', line 126
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 78
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 ||= { support_unencrypted_data? => build_previous_types_for(previous_schemes_including_clean_text), } @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 82
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 140
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 118
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