class Chef::EncryptedAttribute::EncryptedMash

Mash structure with embedded Mash structure encrypted.

This is the most basic encrypted object, which inherits from `Chef::Mash`.

This class is used to construct the different EncryptedAttribute versions. Each version implements the encryption in a different way or using different algorithms.

Currently three {EncryptedMash} versions exists. But you can create your own versions and name it with the `Chef::EncryptedAttribute::EncryptedMash::Version` prefix.

Uses {EncryptedMash::Version1} by default.

This class is oriented to be easily integrable with chef in the future using `JSONCompat`.

@see .create @see EncryptedMash::Version0 @see EncryptedMash::Version1 @see EncryptedMash::Version2

Constants

CHEF_TYPE

Mash key name to use for Chef object type.

CHEF_TYPE_VALUE

Chef object type value.

JSON_CLASS

Mash key name to use for JSON class name. Chef uses the `'json_class'` key internally for objects, we use a renamed key.

VERSION_PREFIX

Name prefix for all EncryptedAttribute version classes. Used internally by the self.version_class method. @api private

Public Class Methods

create(version) click to toggle source

Factory method to construct an encrypted Mash.

@param version [String, Fixnum] EncryptedMash version to use. @raise [RequirementsFailure] if the specified encrypted attribute

version cannot be used.

@raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute

format is wrong.

@raise [UnsupportedEncryptedAttributeFormat] if encrypted attribute

format is not supported or unknown.
# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 113
def self.create(version)
  klass = version_klass(version)
  klass.send(:new)
end
exist?(enc_hs) click to toggle source

Checks whether an encrypted Mash exists.

@param enc_hs [Mash] Mash to check. @return [Boolean] returns `true` if an encrypted Mash exists.

# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 85
def self.exist?(enc_hs)
  enc_hs.is_a?(Hash) &&
    enc_hs.key?(JSON_CLASS) &&
    enc_hs[JSON_CLASS] =~ /^#{Regexp.escape(Module.nesting[1].name)}/ &&
    enc_hs.key?(CHEF_TYPE) && enc_hs[CHEF_TYPE] == CHEF_TYPE_VALUE
end
exists?(*args) click to toggle source

Checks whether an encrypted Mash exists.

@param args [Mash] {exist?} arguments. @return [Boolean] returns `true` if an encrypted Mash exists. @deprecated Use {exist?} instead.

# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 97
def self.exists?(*args)
  Chef::Log.warn(
    "#{name}.exists? is deprecated in favor of #{name}.exist?."
  )
  exist?(*args)
end
json_create(enc_hs) click to toggle source

Creates an EncryptedMash::Version object from a JSON Hash.

Reads the EncryptedMash version to create from the {JSON_CLASS} key.

@param enc_hs [Mash] Encrypted Mash as a Mash. As it is read from node

attributes.

@return [EncryptedMash] EncryptedMash::Version object. @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute

format is wrong.

@raise [UnsupportedEncryptedAttributeFormat] if encrypted attribute

format is not supported or unknown.
# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 162
def self.json_create(enc_hs)
  unless enc_hs.is_a?(Hash)
    fail UnacceptableEncryptedAttributeFormat,
         'Encrypted attribute not found or corrupted.'
  end
  klass = string_to_klass(enc_hs[JSON_CLASS])
  if klass.nil?
    fail UnsupportedEncryptedAttributeFormat,
         "Unknown chef-encrypted-attribute class #{enc_hs[JSON_CLASS]}"
  end
  klass.send(:new, enc_hs)
end
new(enc_hs = nil) click to toggle source

Encrypted Mash constructor.

@param enc_hs [Mash] encrypted Mash to clone. @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute

format is wrong or does not exist.
Calls superclass method
# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 67
def initialize(enc_hs = nil)
  super
  self[JSON_CLASS] = self.class.name
  self[CHEF_TYPE] = CHEF_TYPE_VALUE
  update_from!(enc_hs) if enc_hs.is_a?(Hash)
end
string_to_klass(class_name) click to toggle source

Gets the class reference from its string representation.

@param class_name [String] the class name as string. @return [Class] the class reference. @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute

class name is wrong.

@api private

# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 182
def self.string_to_klass(class_name)
  unless class_name.is_a?(String)
    fail UnacceptableEncryptedAttributeFormat,
         "Bad chef-encrypted-attribute class name #{class_name.inspect}"
  end
  begin
    class_name.split('::').inject(Kernel) do |scope, const|
      scope.const_get(const, scope == Kernel)
    end
  rescue NameError => e
    Chef::Log.error(e)
    nil
  end
end
version_klass(version) click to toggle source

Gets the class reference for a EncryptedMash version.

The implementation of `“Chef::EncryptedAttribute::Version#{version}”` must exists and be included (`require`) beforehand.

@param version [String, Fixnum] the EncryptedMash version. @return [Class] the EncryptedMash version class reference. @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute

version is wrong.

@raise [UnsupportedEncryptedAttributeFormat] if encrypted attribute

format is not supported or unknown.

@api private

# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 209
def self.version_klass(version)
  version = version.to_s unless version.is_a?(String)
  if version.empty?
    fail UnacceptableEncryptedAttributeFormat,
         "Bad chef-encrypted-attribute version #{version.inspect}"
  end
  klass = string_to_klass("#{VERSION_PREFIX}#{version}")
  if klass.nil?
    fail UnsupportedEncryptedAttributeFormat,
         'This version of chef-encrypted-attribute does not support '\
         "encrypted attribute item format version: \"#{version}\""
  end
  klass
end

Public Instance Methods

for_json() click to toggle source

Returns the object as a Ruby Hash.

@return [Hash] ruby Hash represtation of the object.

# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 129
def for_json
  to_hash
end
to_json(*a) click to toggle source

Serializes this object as a Hash.

@param a [Hash] Ruby #to_json call arguments. @return [String] JSON representation of the object.

# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 122
def to_json(*a)
  for_json.to_json(*a)
end
update_from!(enc_hs) click to toggle source

Replaces the EncryptedMash content from a Mash.

@param enc_hs [Mash] Mash to clone. @return [Mash] `self`. @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute

format is wrong or does not exist.
# File lib/chef/encrypted_attribute/encrypted_mash.rb, line 139
def update_from!(enc_hs)
  unless self.class.exist?(enc_hs)
    fail UnacceptableEncryptedAttributeFormat,
         'Trying to construct invalid encrypted attribute. Maybe it is '\
         'not encrypted?'
  end
  enc_hs = enc_hs.dup
  enc_hs.delete(JSON_CLASS)
  enc_hs.delete(CHEF_TYPE)
  update(enc_hs)
end