lib/chamber/settings.rb in chamber-1.0.3 vs lib/chamber/settings.rb in chamber-2.0.0
- old
+ new
@@ -1,20 +1,36 @@
require 'hashie/mash'
require 'chamber/system_environment'
require 'chamber/namespace_set'
+require 'chamber/filters/namespace_filter'
+require 'chamber/filters/encryption_filter'
+require 'chamber/filters/decryption_filter'
+require 'chamber/filters/environment_filter'
+require 'chamber/filters/boolean_conversion_filter'
+require 'chamber/filters/secure_filter'
###
# Internal: Represents the base settings storage needed for Chamber.
#
-class Chamber
+module Chamber
class Settings
attr_reader :namespaces
def initialize(options = {})
- self.namespaces = options.fetch(:namespaces, NamespaceSet.new)
- self.data = options.fetch(:settings, Hashie::Mash.new)
+ self.namespaces = options[:namespaces] || []
+ self.raw_data = options[:settings] || {}
+ self.decryption_key = options[:decryption_key]
+ self.encryption_key = options[:encryption_key]
+ self.pre_filters = options[:pre_filters] || [
+ Filters::NamespaceFilter,
+ ]
+ self.post_filters = options[:post_filters] || [
+ Filters::DecryptionFilter,
+ Filters::EnvironmentFilter,
+ Filters::BooleanConversionFilter,
+ ]
end
###
# Internal: Converts a Settings object into a hash that is compatible as an
# environment variable hash.
@@ -66,87 +82,132 @@
###
# Internal: Merges a Settings object with another Settings object or
# a hash-like object.
#
- # Also, if merging Settings, it will merge the namespaces as well.
+ # Also, if merging Settings, it will merge all other Settings data as well.
#
# Example:
#
# settings = Settings.new settings: { my_setting: 'my value' }
# other_settings = Settings.new settings: { my_other_setting: 'my other value' }
#
- # settings.merge! other_settings
+ # settings.merge other_settings
#
# settings
# # => {
# 'my_setting' => 'my value',
# 'my_other_setting' => 'my other value',
# }
#
+ # Returns a new Settings object
+ #
+ def merge(other)
+ other_settings = if other.is_a? Settings
+ other
+ elsif other.is_a? Hash
+ Settings.new(settings: other)
+ end
+
+ Settings.new(
+ encryption_key: encryption_key || other_settings.encryption_key,
+ decryption_key: decryption_key || other_settings.decryption_key,
+ namespaces: (namespaces + other_settings.namespaces),
+ settings: raw_data.merge(other_settings.raw_data))
+ end
+
+ ###
+ # Internal: Returns the Settings data as a Hash for easy manipulation.
+ # Changes made to the hash will *not* be reflected in the original Settings
+ # object.
+ #
# Returns a Hash
#
- def merge!(other)
- self.data = data.merge(other.to_hash)
- self.namespaces = (namespaces + other.namespaces) if other.respond_to? :namespaces
+ def to_hash
+ data.to_hash
end
+ ###
+ # Internal: Determines whether a Settings is equal to another hash-like
+ # object.
+ #
+ # Returns a Boolean
+ #
+ def ==(other)
+ self.to_hash == other.to_hash
+ end
+
+ ###
+ # Internal: Determines whether a Settings is equal to another Settings.
+ #
+ # Returns a Boolean
+ #
def eql?(other)
other.is_a?( Chamber::Settings) &&
self.data == other.data &&
self.namespaces == other.namespaces
end
- def to_hash
- data
+ def secured
+ Settings.new( metadata.merge(
+ settings: raw_data,
+ pre_filters: [Filters::SecureFilter]))
end
- def method_missing(name, *args)
- return data.public_send(name, *args) if data.respond_to?(name)
-
- super
+ def secure
+ Settings.new( metadata.merge(
+ settings: @raw_data,
+ pre_filters: [Filters::EncryptionFilter],
+ post_filters: [] ))
end
- def respond_to_missing?(name, include_private = false)
- data.respond_to?(name, include_private)
- end
-
protected
- attr_reader :raw_data
- attr_writer :namespaces
+ attr_accessor :pre_filters,
+ :post_filters,
+ :encryption_key,
+ :decryption_key,
+ :raw_data
- def data
- @data ||= Hashie::Mash.new
+ def raw_data=(new_raw_data)
+ @raw_data = Hashie::Mash.new(new_raw_data)
end
- def data=(raw_data)
- @raw_data = Hashie::Mash.new(raw_data)
+ def namespaces=(raw_namespaces)
+ @namespaces = NamespaceSet.new(raw_namespaces)
+ end
- namespace_checked_data = if data_is_namespaced?
- namespace_filtered_data
- else
- self.raw_data
- end
+ def raw_data
+ @filtered_raw_data ||= pre_filters.reduce(@raw_data) do |filtered_data, filter|
+ filter.execute({data: filtered_data}.
+ merge(metadata))
+ end
+ end
- @data = SystemEnvironment.inject_into(namespace_checked_data)
+ def data
+ @data ||= post_filters.reduce(raw_data) do |filtered_data, filter|
+ filter.execute({data: filtered_data}.
+ merge(metadata))
+ end
end
- private
-
- def data_is_namespaced?
- @data_is_namespaced ||= raw_data.keys.any? { |key| namespaces.include? key }
+ def metadata
+ {
+ namespaces: self.namespaces,
+ decryption_key: self.decryption_key,
+ encryption_key: self.encryption_key,
+ }
end
- def namespace_filtered_data
- @namespace_filtered_data ||= -> do
- data = Hashie::Mash.new
+ public
- namespaces.each do |namespace|
- data.merge!(raw_data[namespace]) if raw_data[namespace]
- end
+ def method_missing(name, *args)
+ return data.public_send(name, *args) if data.respond_to?(name)
- data
- end.call
+ super
+ end
+
+ def respond_to_missing?(name, include_private = false)
+ data.respond_to?(name, include_private)
end
end
end