Skip to content

Commit

Permalink
Document Assertion and Config classes
Browse files Browse the repository at this point in the history
  • Loading branch information
zuazo committed Dec 8, 2014
1 parent fd20556 commit 50d2a6e
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 3 deletions.
9 changes: 8 additions & 1 deletion lib/chef/encrypted_attribute/assertions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@

class Chef
class EncryptedAttribute
# Include some assertions that throw exceptions if not met
# Include some assertions that throw exceptions if not met.
module Assertions
# Check some assertions related with OpenSSL AEAD support, required to
# to use [GCM](http://en.wikipedia.org/wiki/Galois/Counter_Mode).
#
# @param algorithm [String] the name of the algorithm to use.
# @return void
# @raise [RequirementsFailure] if any of the requirements to use AEAD is
# not met.
def assert_aead_requirements_met!(algorithm)
unless OpenSSL::Cipher.method_defined?(:auth_data=)
fail RequirementsFailure,
Expand Down
123 changes: 122 additions & 1 deletion lib/chef/encrypted_attribute/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@

class Chef
class EncryptedAttribute
# Sets and reads encrypted attributes configuration options
# Encrypted attributes configuration options object.
class Config
include ::Chef::Mixin::ParamsValidate

# Returns configuration options list.
#
# @api private
OPTIONS = [
:version,
:partial_search,
Expand All @@ -33,10 +36,17 @@ class Config
:keys
].freeze

# Constructs a {Config} object.
#
# @param config [Config, Hash] configuration object to clone.
def initialize(config = nil)
update!(config) unless config.nil?
end

# Reads or sets Encrypted Mash protocol version.
#
# @param arg [String, Fixnum] protocol version to use. Must be a number.
# @return [Fixnum] protocol version.
def version(arg = nil)
unless arg.nil? || !arg.is_a?(String)
begin
Expand All @@ -48,20 +58,51 @@ def version(arg = nil)
set_or_return(:version, arg, kind_of: [Fixnum, String], default: 1)
end

# Reads or sets partial search support.
#
# Set it to `false` to disable partial search. Defaults to `true`.
#
# @param arg [Boolean] whether to enable partial search.
# @return [Boolean] partial search usage.
# @see
# [Chef Search documentation](http://docs.getchef.com/chef_search.html)
def partial_search(arg = nil)
set_or_return(
:partial_search, arg, kind_of: [TrueClass, FalseClass], default: true
)
end

# Reads or sets client search query.
#
# This query will return a list of clients that will be able to read the
# encrypted attribute.
#
# @param arg [String, Array<String>] list of client queries to perform.
# @return [Array<String>] list of client queries.
# @see
# [Chef Search documentation](http://docs.getchef.com/chef_search.html)
def client_search(arg = nil)
set_or_return_search_array(:client_search, arg)
end

# Reads or sets node search query.
#
# This query will return a list of nodes that will be able to read the
# encrypted attribute.
#
# @param arg [String, Array<String>] list of node queries to perform.
# @return [Array<String>] list of node queries.
def node_search(arg = nil)
set_or_return_search_array(:node_search, arg)
end

# Reads or sets user list.
#
# This contains the user list that will be able to read the encrypted
# attribute.
#
# @param arg [String, Array<String>] list of users to set.
# @return [Array<String>] list of users.
def users(arg = nil)
set_or_return(
:users, arg,
Expand All @@ -70,6 +111,13 @@ def users(arg = nil)
)
end

# Reads or sets key list.
#
# This contains the raw key list that will be able to read the encrypted
# attribute.
#
# @param arg [Array<String, OpenSSL::PKey::RSA>] the keys in PEM format.
# @return [Array<String, OpenSSL::PKey::RSA>] the keys in PEM format
def keys(arg = nil)
set_or_return(
:keys, arg,
Expand All @@ -78,6 +126,15 @@ def keys(arg = nil)
)
end

# Replaces the current config.
#
# When setting using a {Chef::EncryptedAttribute::Config} class, all the
# configuration options will be replaced.
#
# When setting using a _Hash_, only the provided keys will be replaced.
#
# @param config [Config, Hash] the configuarion to set.
# @return [Config] `self`.
def update!(config)
if config.is_a?(self.class)
update_from_config!(config)
Expand All @@ -86,24 +143,45 @@ def update!(config)
end
end

# Reads a configuration option.
#
# @param key [String, Symbol] configuration option to read.
# @return [Mixed] configuration value.
def [](key)
key = key.to_sym if key.is_a?(String)
send(key) if OPTIONS.include?(key)
end

# Sets a configuration option.
#
# @param key [String, Symbol] configuration option name to set.
# @param value [Mixed] configuration value to set.
# @return [Mixed] configuration value.
def []=(key, value)
key = key.to_sym if key.is_a?(String)
send(key, value) if OPTIONS.include?(key)
end

protected

# Duplicates an object avoiding Ruby exceptions if not supported.
#
# @param o [Object] object to duplicate.
# @return [Object] duplicated object.
def dup_object(o)
o.dup
rescue TypeError
o
end

# Creates getter and setter method for **search array** configuration
# options.
#
# This configuration options contains an array of search queries.
#
# @param name [Symbol] configuration option name.
# @param arg [Array<String>, String] configuration option value to set.
# @return [Array<String>] configuration option value.
def set_or_return_search_array(name, arg = nil)
arg = [arg] unless arg.nil? || !arg.is_a?(String)
set_or_return(
Expand All @@ -112,13 +190,21 @@ def set_or_return_search_array(name, arg = nil)
)
end

# Checks a search query array list.
#
# @param s_ary [Array<String>] search query array.
# @return [Boolean] `true` if the search query list is in the correct
# format.
def config_valid_search_array?(s_ary)
s_ary.each do |s|
return false unless s.is_a?(String)
end
true
end

# Returns configuration option callback function for search arrays.
#
# @return [Proc] search arrays checking callback function.
def config_search_array_callbacks
{
'should be a valid array of search patterns' => lambda do |cs|
Expand All @@ -127,6 +213,11 @@ def config_search_array_callbacks
}
end

# Checks a user list option value.
#
# @param users [Array<String>, '*'] user list to check.
# @return [Boolean] `true` if the user list is in the correct
# format.
def config_valid_user_arg?(users)
return users == '*' if users.is_a?(String)
users.each do |u|
Expand All @@ -135,6 +226,9 @@ def config_valid_user_arg?(users)
true
end

# Returns configuration option callback function for user lists.
#
# @return [Proc] user lists checking callback function.
def config_users_arg_callbacks
{
'should be a valid array of search patterns' => lambda do |us|
Expand All @@ -143,6 +237,12 @@ def config_users_arg_callbacks
}
end

# Checks if an OpenSSL key is in the correct format.
#
# Only checks that has a public key. It may lack private key.
#
# @param k [String, OpenSSL::PKey::RSA] key to check.
# @return [Boolean] `true` if the public key is correct.
def config_valid_key?(k)
rsa_k =
case k
Expand All @@ -160,13 +260,22 @@ def config_valid_key?(k)
rsa_k.public?
end

# Checks if an OpenSSL key array is in the correct format.
#
# Only checks that the keys have a public key. They may lack private key.
#
# @param k_ary [Array<String, OpenSSL::PKey::RSA>] array of keys to check.
# @return [Boolean] `true` if the public keys are all correct.
def config_valid_keys_array?(k_ary)
k_ary.each do |k|
return false unless config_valid_key?(k)
end
true
end

# Returns configuration option callback function for public keys.
#
# @return [Proc] public keys checking callback function.
def config_valid_keys_array_callbacks
{
'should be a valid array of keys' => lambda do |keys|
Expand All @@ -175,13 +284,25 @@ def config_valid_keys_array_callbacks
}
end

# Copies a configuration. All the current configuration options will be
# replaced.
#
# Called by {#update_from!} for {Config} objects.
#
# @param config [Config] configuration options to copy.
def update_from_config!(config)
OPTIONS.each do |attr|
value = dup_object(config.send(attr))
instance_variable_set("@#{attr}", value)
end
end

# Copies a configuration option. Only the provided Hash keys will be
# replaced, the others will be preserved.
#
# Called by {#update_from!} for *Hash* objects.
#
# @param config [Hash] configuration options to copy.
def update_from_hash!(config)
config.each do |attr, value|
attr = attr.to_sym if attr.is_a?(String)
Expand Down
2 changes: 1 addition & 1 deletion lib/chef/encrypted_attribute/encrypted_mash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class EncryptedMash < Mash

# Name prefix for all EncryptedAttribute version classes.
# Used internally by the #self.version_class method.
# @private
# @api private
VERSION_PREFIX = "#{name}::Version"

# Encrypted Mash constructor.
Expand Down

0 comments on commit 50d2a6e

Please sign in to comment.