123456789_123456789_123456789_123456789_123456789_

Class: ActiveRecord::Encryption::Scheme

Relationships & Source Files
Inherits: Object
Defined in: activerecord/lib/active_record/encryption/scheme.rb

Overview

A container of attribute encryption options.

It validates and serves attribute encryption options.

See EncryptedAttributeType, Context

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(key_provider: nil, key: nil, deterministic: nil, support_unencrypted_data: nil, downcase: nil, ignore_case: nil, previous_schemes: nil, compress: true, compressor: nil, **context_properties) ⇒ Scheme

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 13

def initialize(key_provider: nil, key: nil, deterministic: nil, support_unencrypted_data: nil, downcase: nil, ignore_case: nil,
               previous_schemes: nil, compress: true, compressor: nil, **context_properties)
  # Initializing all attributes to nil as we want to allow a "not set" semantics so that we
  # can merge schemes without overriding values with defaults. See #merge

  @key_provider_param = key_provider
  @key = key
  @deterministic = deterministic
  @support_unencrypted_data = support_unencrypted_data
  @downcase = downcase || ignore_case
  @ignore_case = ignore_case
  @previous_schemes_param = previous_schemes
  @previous_schemes = Array.wrap(previous_schemes)
  @context_properties = context_properties
  @compress = compress
  @compressor = compressor

  validate_config!

  @context_properties[:encryptor] = Encryptor.new(compress: @compress) unless @compress
  @context_properties[:encryptor] = Encryptor.new(compressor: compressor) if compressor
end

Instance Attribute Details

#deterministic?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 52

def deterministic?
  !!@deterministic
end

#downcase?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 48

def downcase?
  @downcase
end

#fixed?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 60

def fixed?
  return @fixed if defined?(@fixed)

  # by default deterministic encryption is fixed
  @fixed = @deterministic && (!@deterministic.is_a?(Hash) || @deterministic[:fixed])
end

#ignore_case?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 44

def ignore_case?
  @ignore_case
end

#previous_schemes (rw)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 11

attr_accessor :previous_schemes

#support_unencrypted_data?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 56

def support_unencrypted_data?
  @support_unencrypted_data.nil? ? ActiveRecord::Encryption.config.support_unencrypted_data : @support_unencrypted_data
end

Instance Method Details

#compatible_with?(other_scheme) ⇒ Boolean

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 88

def compatible_with?(other_scheme)
  deterministic? == other_scheme.deterministic?
end

#default_key_provider (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 116

def default_key_provider
  ActiveRecord::Encryption.key_provider
end

#deterministic_key_provider (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 108

def deterministic_key_provider
  return @deterministic_key_provider if defined?(@deterministic_key_provider)

  @deterministic_key_provider = if @deterministic
    DeterministicKeyProvider.new(ActiveRecord::Encryption.config.deterministic_key)
  end
end

#freeze

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 36

def freeze
  fixed?
  key_provider_from_key
  deterministic_key_provider

  super
end

#key_provider

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 67

def key_provider
  @key_provider_param || key_provider_from_key || deterministic_key_provider || default_key_provider
end

#key_provider_from_key (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 100

def key_provider_from_key
  return @key_provider_from_key if defined?(@key_provider_from_key)

  @key_provider_from_key = if @key.present?
    DerivedSecretKeyProvider.new(@key)
  end
end

#merge(other_scheme)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 71

def merge(other_scheme)
  self.class.new(**to_h, **other_scheme.to_h)
end

#to_h

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 75

def to_h
  { key_provider: @key_provider_param, deterministic: @deterministic, downcase: @downcase, ignore_case: @ignore_case,
    previous_schemes: @previous_schemes_param, **@context_properties }.compact
end

#validate_config! (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 93

def validate_config!
  raise Errors::Configuration, "ignore_case: can only be used with deterministic encryption" if @ignore_case && !@deterministic
  raise Errors::Configuration, "key_provider: and key: can't be used simultaneously" if @key_provider_param && @key
  raise Errors::Configuration, "compressor: can't be used with compress: false" if !@compress && @compressor
  raise Errors::Configuration, "compressor: can't be used with encryptor" if @compressor && @context_properties[:encryptor]
end

#with_context(&block)

[ GitHub ]

  
# File 'activerecord/lib/active_record/encryption/scheme.rb', line 80

def with_context(&block)
  if @context_properties.present?
    ActiveRecord::Encryption.with_encryption_context(**@context_properties, &block)
  else
    block.call
  end
end