chamber 3.0.0rc1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +5 -5
- data/lib/chamber/binary/runner.rb +10 -12
- data/lib/chamber/commands/base.rb +4 -4
- data/lib/chamber/commands/initialize.rb +5 -5
- data/lib/chamber/commands/securable.rb +5 -9
- data/lib/chamber/commands/show.rb +0 -1
- data/lib/chamber/context_resolver.rb +5 -4
- data/lib/chamber/encryption_methods/public_key.rb +26 -14
- data/lib/chamber/encryption_methods/ssl.rb +36 -28
- data/lib/chamber/errors/disallowed_class.rb +8 -0
- data/lib/chamber/errors/invalid_key_type.rb +8 -0
- data/lib/chamber/errors/missing_index.rb +13 -0
- data/lib/chamber/errors/missing_setting.rb +13 -0
- data/lib/chamber/errors/non_conforming_key.rb +8 -0
- data/lib/chamber/file.rb +18 -7
- data/lib/chamber/file_set.rb +5 -1
- data/lib/chamber/files/signature.rb +6 -6
- data/lib/chamber/filters/decryption_filter.rb +9 -11
- data/lib/chamber/filters/encryption_filter.rb +8 -9
- data/lib/chamber/filters/environment_filter.rb +16 -18
- data/lib/chamber/filters/failed_decryption_filter.rb +3 -3
- data/lib/chamber/filters/namespace_filter.rb +10 -12
- data/lib/chamber/filters/secure_filter.rb +3 -3
- data/lib/chamber/filters/translate_secure_keys_filter.rb +3 -3
- data/lib/chamber/instance.rb +4 -7
- data/lib/chamber/integrations/sinatra.rb +1 -1
- data/lib/chamber/keys/base.rb +11 -7
- data/lib/chamber/namespace_set.rb +2 -2
- data/lib/chamber/rails.rb +1 -1
- data/lib/chamber/refinements/deep_dup.rb +12 -36
- data/lib/chamber/refinements/enumerable.rb +8 -20
- data/lib/chamber/refinements/hash.rb +10 -36
- data/lib/chamber/rubinius_fix.rb +1 -1
- data/lib/chamber/settings.rb +39 -23
- data/lib/chamber/types/secured.rb +8 -8
- data/lib/chamber/version.rb +1 -1
- data/lib/chamber.rb +0 -5
- data.tar.gz.sig +0 -0
- metadata +29 -34
- metadata.gz.sig +0 -0
- data/lib/chamber/adapters/cloud/circle_ci.rb +0 -85
- data/lib/chamber/adapters/cloud/heroku.rb +0 -74
- data/lib/chamber/binary/circle_ci.rb +0 -123
- data/lib/chamber/binary/heroku.rb +0 -111
- data/lib/chamber/binary/travis.rb +0 -37
- data/lib/chamber/commands/cloud/base.rb +0 -35
- data/lib/chamber/commands/cloud/clear.rb +0 -25
- data/lib/chamber/commands/cloud/compare.rb +0 -26
- data/lib/chamber/commands/cloud/pull.rb +0 -29
- data/lib/chamber/commands/cloud/push.rb +0 -44
- data/lib/chamber/commands/travis/secure.rb +0 -37
- data/lib/chamber/refinements/array.rb +0 -20
| @@ -1,15 +1,14 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            require 'yaml'
         | 
| 4 | 
            +
             | 
| 4 5 | 
             
            require 'chamber/errors/environment_conversion'
         | 
| 5 | 
            -
            require 'chamber/refinements/hash'
         | 
| 6 | 
            -
            require 'chamber/refinements/deep_dup'
         | 
| 7 6 |  | 
| 8 7 | 
             
            module  Chamber
         | 
| 9 8 | 
             
            module  Filters
         | 
| 10 9 | 
             
            class   EnvironmentFilter
         | 
| 11 | 
            -
               | 
| 12 | 
            -
             | 
| 10 | 
            +
              attr_accessor :data,
         | 
| 11 | 
            +
                            :secure_key_token
         | 
| 13 12 |  | 
| 14 13 | 
             
              ###
         | 
| 15 14 | 
             
              # Internal: Allows the existing environment to be injected into the passed in
         | 
| @@ -95,9 +94,6 @@ class   EnvironmentFilter | |
| 95 94 | 
             
                new(**args).__send__(:execute)
         | 
| 96 95 | 
             
              end
         | 
| 97 96 |  | 
| 98 | 
            -
              attr_accessor :data,
         | 
| 99 | 
            -
                            :secure_key_token
         | 
| 100 | 
            -
             | 
| 101 97 | 
             
              def initialize(data:, secure_key_prefix:, **_args)
         | 
| 102 98 | 
             
                self.data             = data
         | 
| 103 99 | 
             
                self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
         | 
| @@ -113,9 +109,11 @@ class   EnvironmentFilter | |
| 113 109 | 
             
                    { key => execute(value, environment_keys) }
         | 
| 114 110 | 
             
                  end,
         | 
| 115 111 | 
             
                  lambda do |key, value, environment_key|
         | 
| 116 | 
            -
                    { | 
| 117 | 
            -
             | 
| 118 | 
            -
                                                        | 
| 112 | 
            +
                    {
         | 
| 113 | 
            +
                      key => convert_environment_value(environment_key,
         | 
| 114 | 
            +
                                                       ENV.fetch(environment_key, nil),
         | 
| 115 | 
            +
                                                       value),
         | 
| 116 | 
            +
                    }
         | 
| 119 117 | 
             
                  end,
         | 
| 120 118 | 
             
                )
         | 
| 121 119 | 
             
              end
         | 
| @@ -127,14 +125,14 @@ class   EnvironmentFilter | |
| 127 125 |  | 
| 128 126 | 
             
                settings.each_pair do |key, value|
         | 
| 129 127 | 
             
                  environment_key  = key.to_s.gsub(secure_key_token, '')
         | 
| 130 | 
            -
                  environment_keys = parent_keys. | 
| 128 | 
            +
                  environment_keys = parent_keys.dup.push(environment_key)
         | 
| 131 129 |  | 
| 132 130 | 
             
                  if value.respond_to? :each_pair
         | 
| 133 | 
            -
                    environment_hash. | 
| 131 | 
            +
                    environment_hash.merge!(hash_block.call(key, value, environment_keys))
         | 
| 134 132 | 
             
                  else
         | 
| 135 133 | 
             
                    environment_key = environment_keys.join('_').upcase
         | 
| 136 134 |  | 
| 137 | 
            -
                    environment_hash. | 
| 135 | 
            +
                    environment_hash.merge!(value_block.call(key, value, environment_key))
         | 
| 138 136 | 
             
                  end
         | 
| 139 137 | 
             
                end
         | 
| 140 138 |  | 
| @@ -171,13 +169,13 @@ class   EnvironmentFilter | |
| 171 169 | 
             
                  environment_value
         | 
| 172 170 | 
             
                end
         | 
| 173 171 | 
             
              rescue ArgumentError
         | 
| 174 | 
            -
                raise Chamber::Errors::EnvironmentConversion,  | 
| 175 | 
            -
            We attempted to convert '#{environment_key}' from '#{environment_value}' to a '#{settings_value.class.name}'.
         | 
| 172 | 
            +
                raise Chamber::Errors::EnvironmentConversion, <<~HEREDOC
         | 
| 173 | 
            +
                  We attempted to convert '#{environment_key}' from '#{environment_value}' to a '#{settings_value.class.name}'.
         | 
| 176 174 |  | 
| 177 | 
            -
            Unfortunately, this did not go as planned.  Please either verify that your value is convertable
         | 
| 178 | 
            -
            or change the original YAML value to be something more generic (like a String).
         | 
| 175 | 
            +
                  Unfortunately, this did not go as planned.  Please either verify that your value is convertable
         | 
| 176 | 
            +
                  or change the original YAML value to be something more generic (like a String).
         | 
| 179 177 |  | 
| 180 | 
            -
            For more information, see https://github.com/thekompanee/chamber/wiki/Environment-Variable-Coercions
         | 
| 178 | 
            +
                  For more information, see https://github.com/thekompanee/chamber/wiki/Environment-Variable-Coercions
         | 
| 181 179 | 
             
                HEREDOC
         | 
| 182 180 | 
             
              end
         | 
| 183 181 | 
             
            end
         | 
| @@ -10,13 +10,13 @@ class   FailedDecryptionFilter | |
| 10 10 |  | 
| 11 11 | 
             
              BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}.freeze
         | 
| 12 12 |  | 
| 13 | 
            +
              attr_accessor :data,
         | 
| 14 | 
            +
                            :secure_key_token
         | 
| 15 | 
            +
             | 
| 13 16 | 
             
              def self.execute(**args)
         | 
| 14 17 | 
             
                new(**args).__send__(:execute)
         | 
| 15 18 | 
             
              end
         | 
| 16 19 |  | 
| 17 | 
            -
              attr_accessor :data,
         | 
| 18 | 
            -
                            :secure_key_token
         | 
| 19 | 
            -
             | 
| 20 20 | 
             
              def initialize(data:, secure_key_prefix:, **_args)
         | 
| 21 21 | 
             
                self.data             = data.deep_dup
         | 
| 22 22 | 
             
                self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
         | 
| @@ -1,21 +1,21 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require 'chamber/refinements/hash'
         | 
| 4 3 | 
             
            require 'chamber/refinements/deep_dup'
         | 
| 4 | 
            +
            require 'chamber/refinements/hash'
         | 
| 5 5 |  | 
| 6 6 | 
             
            module  Chamber
         | 
| 7 7 | 
             
            module  Filters
         | 
| 8 8 | 
             
            class   NamespaceFilter
         | 
| 9 | 
            -
              using ::Chamber::Refinements::Hash
         | 
| 10 9 | 
             
              using ::Chamber::Refinements::DeepDup
         | 
| 10 | 
            +
              using ::Chamber::Refinements::Hash
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              attr_accessor :data,
         | 
| 13 | 
            +
                            :namespaces
         | 
| 11 14 |  | 
| 12 15 | 
             
              def self.execute(**args)
         | 
| 13 16 | 
             
                new(**args).__send__(:execute)
         | 
| 14 17 | 
             
              end
         | 
| 15 18 |  | 
| 16 | 
            -
              attr_accessor :data,
         | 
| 17 | 
            -
                            :namespaces
         | 
| 18 | 
            -
             | 
| 19 19 | 
             
              def initialize(data:, namespaces:, **_args)
         | 
| 20 20 | 
             
                self.data       = data.deep_dup
         | 
| 21 21 | 
             
                self.namespaces = namespaces
         | 
| @@ -24,19 +24,17 @@ class   NamespaceFilter | |
| 24 24 | 
             
              protected
         | 
| 25 25 |  | 
| 26 26 | 
             
              def execute
         | 
| 27 | 
            -
                 | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
                   | 
| 31 | 
            -
                else
         | 
| 32 | 
            -
                  data
         | 
| 27 | 
            +
                return data unless data_is_namespaced?
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                namespaces.each_with_object({}) do |namespace, filtered_data|
         | 
| 30 | 
            +
                  filtered_data.deep_merge!(data[namespace]) if data[namespace]
         | 
| 33 31 | 
             
                end
         | 
| 34 32 | 
             
              end
         | 
| 35 33 |  | 
| 36 34 | 
             
              private
         | 
| 37 35 |  | 
| 38 36 | 
             
              def data_is_namespaced?
         | 
| 39 | 
            -
                @data_is_namespaced ||= data.keys.any? { |key| namespaces.include? | 
| 37 | 
            +
                @data_is_namespaced ||= data.keys.any? { |key| namespaces.include?(key.to_s) }
         | 
| 40 38 | 
             
              end
         | 
| 41 39 | 
             
            end
         | 
| 42 40 | 
             
            end
         | 
| @@ -7,13 +7,13 @@ module  Filters | |
| 7 7 | 
             
            class   SecureFilter
         | 
| 8 8 | 
             
              using ::Chamber::Refinements::DeepDup
         | 
| 9 9 |  | 
| 10 | 
            +
              attr_accessor :data,
         | 
| 11 | 
            +
                            :secure_key_token
         | 
| 12 | 
            +
             | 
| 10 13 | 
             
              def self.execute(**args)
         | 
| 11 14 | 
             
                new(**args).__send__(:execute)
         | 
| 12 15 | 
             
              end
         | 
| 13 16 |  | 
| 14 | 
            -
              attr_accessor :data,
         | 
| 15 | 
            -
                            :secure_key_token
         | 
| 16 | 
            -
             | 
| 17 17 | 
             
              def initialize(data:, secure_key_prefix:, **_args)
         | 
| 18 18 | 
             
                self.data             = data.deep_dup
         | 
| 19 19 | 
             
                self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
         | 
| @@ -7,13 +7,13 @@ module  Filters | |
| 7 7 | 
             
            class   TranslateSecureKeysFilter
         | 
| 8 8 | 
             
              using ::Chamber::Refinements::DeepDup
         | 
| 9 9 |  | 
| 10 | 
            +
              attr_accessor :data,
         | 
| 11 | 
            +
                            :secure_key_token
         | 
| 12 | 
            +
             | 
| 10 13 | 
             
              def self.execute(**args)
         | 
| 11 14 | 
             
                new(**args).__send__(:execute)
         | 
| 12 15 | 
             
              end
         | 
| 13 16 |  | 
| 14 | 
            -
              attr_accessor :data,
         | 
| 15 | 
            -
                            :secure_key_token
         | 
| 16 | 
            -
             | 
| 17 17 | 
             
              def initialize(data:, secure_key_prefix:, **_args)
         | 
| 18 18 | 
             
                self.data             = data.deep_dup
         | 
| 19 19 | 
             
                self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
         | 
    
        data/lib/chamber/instance.rb
    CHANGED
    
    | @@ -3,12 +3,9 @@ | |
| 3 3 | 
             
            require 'chamber/configuration'
         | 
| 4 4 | 
             
            require 'chamber/file_set'
         | 
| 5 5 | 
             
            require 'chamber/settings'
         | 
| 6 | 
            -
            require 'chamber/refinements/hash'
         | 
| 7 6 |  | 
| 8 7 | 
             
            module  Chamber
         | 
| 9 8 | 
             
            class   Instance
         | 
| 10 | 
            -
              using ::Chamber::Refinements::Hash
         | 
| 11 | 
            -
             | 
| 12 9 | 
             
              attr_accessor :configuration,
         | 
| 13 10 | 
             
                            :files
         | 
| 14 11 |  | 
| @@ -66,11 +63,11 @@ class   Instance | |
| 66 63 | 
             
              end
         | 
| 67 64 |  | 
| 68 65 | 
             
              def encrypt(data, **args)
         | 
| 69 | 
            -
                config = configuration.to_hash. | 
| 66 | 
            +
                config = configuration.to_hash.merge(**args)
         | 
| 70 67 |  | 
| 71 68 | 
             
                Settings
         | 
| 72 69 | 
             
                  .new(
         | 
| 73 | 
            -
                    **config. | 
| 70 | 
            +
                    **config.merge(
         | 
| 74 71 | 
             
                      settings:     data,
         | 
| 75 72 | 
             
                      pre_filters:  [Filters::EncryptionFilter],
         | 
| 76 73 | 
             
                      post_filters: [],
         | 
| @@ -80,11 +77,11 @@ class   Instance | |
| 80 77 | 
             
              end
         | 
| 81 78 |  | 
| 82 79 | 
             
              def decrypt(data, **args)
         | 
| 83 | 
            -
                config = configuration.to_hash. | 
| 80 | 
            +
                config = configuration.to_hash.merge(**args)
         | 
| 84 81 |  | 
| 85 82 | 
             
                Settings
         | 
| 86 83 | 
             
                  .new(
         | 
| 87 | 
            -
                    **config. | 
| 84 | 
            +
                    **config.merge(
         | 
| 88 85 | 
             
                      settings:     data,
         | 
| 89 86 | 
             
                      pre_filters:  [Filters::NamespaceFilter],
         | 
| 90 87 | 
             
                      post_filters: [
         | 
    
        data/lib/chamber/keys/base.rb
    CHANGED
    
    | @@ -3,14 +3,14 @@ | |
| 3 3 | 
             
            module  Chamber
         | 
| 4 4 | 
             
            module  Keys
         | 
| 5 5 | 
             
            class   Base
         | 
| 6 | 
            -
              def self.resolve(**args)
         | 
| 7 | 
            -
                new(**args).resolve
         | 
| 8 | 
            -
              end
         | 
| 9 | 
            -
             | 
| 10 6 | 
             
              attr_accessor :rootpath
         | 
| 11 7 | 
             
              attr_reader   :filenames,
         | 
| 12 8 | 
             
                            :namespaces
         | 
| 13 9 |  | 
| 10 | 
            +
              def self.resolve(**args)
         | 
| 11 | 
            +
                new(**args).resolve
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 14 | 
             
              def initialize(rootpath:, namespaces:, filenames: nil)
         | 
| 15 15 | 
             
                self.rootpath   = Pathname.new(rootpath)
         | 
| 16 16 | 
             
                self.namespaces = namespaces
         | 
| @@ -20,7 +20,11 @@ class   Base | |
| 20 20 | 
             
              def resolve
         | 
| 21 21 | 
             
                key_paths.each_with_object({}) do |path, memo|
         | 
| 22 22 | 
             
                  namespace = namespace_from_path(path) || '__default'
         | 
| 23 | 
            -
                  value     = path.readable? | 
| 23 | 
            +
                  value     = if path.readable?
         | 
| 24 | 
            +
                                path.read
         | 
| 25 | 
            +
                              else
         | 
| 26 | 
            +
                                ENV.fetch(environment_variable_from_path(path), nil)
         | 
| 27 | 
            +
                              end
         | 
| 24 28 |  | 
| 25 29 | 
             
                  memo[namespace.downcase.to_sym] = value if value
         | 
| 26 30 | 
             
                end
         | 
| @@ -39,13 +43,13 @@ class   Base | |
| 39 43 | 
             
                             namespaces.map { |n| namespace_to_key_path(n) }
         | 
| 40 44 | 
             
              end
         | 
| 41 45 |  | 
| 42 | 
            -
              # rubocop:disable Performance/ | 
| 46 | 
            +
              # rubocop:disable Performance/MapCompact
         | 
| 43 47 | 
             
              def filenames=(other)
         | 
| 44 48 | 
             
                @filenames = Array(other)
         | 
| 45 49 | 
             
                               .map { |o| Pathname.new(o) }
         | 
| 46 50 | 
             
                               .compact
         | 
| 47 51 | 
             
              end
         | 
| 48 | 
            -
              # rubocop:enable Performance/ | 
| 52 | 
            +
              # rubocop:enable Performance/MapCompact
         | 
| 49 53 |  | 
| 50 54 | 
             
              def namespaces=(other)
         | 
| 51 55 | 
             
                @namespaces = other + %w{signature}
         | 
| @@ -14,6 +14,8 @@ module  Chamber | |
| 14 14 | 
             
            class   NamespaceSet
         | 
| 15 15 | 
             
              include Enumerable
         | 
| 16 16 |  | 
| 17 | 
            +
              attr_reader :raw_namespaces
         | 
| 18 | 
            +
             | 
| 17 19 | 
             
              ###
         | 
| 18 20 | 
             
              # Internal: Allows for more compact NamespaceSet creation by giving a list of
         | 
| 19 21 | 
             
              # namespace values.
         | 
| @@ -28,8 +30,6 @@ class   NamespaceSet | |
| 28 30 | 
             
                new(namespace_values)
         | 
| 29 31 | 
             
              end
         | 
| 30 32 |  | 
| 31 | 
            -
              attr_reader :raw_namespaces
         | 
| 32 | 
            -
             | 
| 33 33 | 
             
              ###
         | 
| 34 34 | 
             
              # Internal: Creates a new NamespaceSet from arrays, hashes and sets.
         | 
| 35 35 | 
             
              #
         | 
    
        data/lib/chamber/rails.rb
    CHANGED
    
    
| @@ -4,50 +4,26 @@ module Chamber | |
| 4 4 | 
             
            module Refinements
         | 
| 5 5 | 
             
            module DeepDup
         | 
| 6 6 | 
             
            refine ::Array do
         | 
| 7 | 
            -
               | 
| 8 | 
            -
                 | 
| 9 | 
            -
                  map do |i|
         | 
| 10 | 
            -
                    if i.respond_to?(:deep_dup)
         | 
| 11 | 
            -
                      i.deep_dup
         | 
| 12 | 
            -
                    else
         | 
| 13 | 
            -
                      begin
         | 
| 14 | 
            -
                        i.dup
         | 
| 15 | 
            -
                      rescue ::TypeError
         | 
| 16 | 
            -
                        # Hack for < Ruby 2.4 since FalseClass, TrueClass, Fixnum, etc can't be
         | 
| 17 | 
            -
                        # dupped
         | 
| 18 | 
            -
                        i
         | 
| 19 | 
            -
                      end
         | 
| 20 | 
            -
                    end
         | 
| 21 | 
            -
                  end
         | 
| 22 | 
            -
                end
         | 
| 7 | 
            +
              def deep_dup
         | 
| 8 | 
            +
                map { |i| i.respond_to?(:deep_dup) ? i.deep_dup : i.dup }
         | 
| 23 9 | 
             
              end
         | 
| 24 10 | 
             
            end
         | 
| 25 11 |  | 
| 26 12 | 
             
            refine ::Object do
         | 
| 27 | 
            -
               | 
| 28 | 
            -
                 | 
| 29 | 
            -
                  begin
         | 
| 30 | 
            -
                    dup
         | 
| 31 | 
            -
                  rescue ::TypeError
         | 
| 32 | 
            -
                    # Hack for < Ruby 2.4 since FalseClass, TrueClass, Fixnum, etc can't be
         | 
| 33 | 
            -
                    # dupped
         | 
| 34 | 
            -
                    self
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
                end
         | 
| 13 | 
            +
              def deep_dup
         | 
| 14 | 
            +
                dup
         | 
| 37 15 | 
             
              end
         | 
| 38 16 | 
             
            end
         | 
| 39 17 |  | 
| 40 18 | 
             
            refine ::Hash do
         | 
| 41 | 
            -
               | 
| 42 | 
            -
                 | 
| 43 | 
            -
                   | 
| 44 | 
            -
                     | 
| 45 | 
            -
                       | 
| 46 | 
            -
             | 
| 47 | 
            -
                       | 
| 48 | 
            -
             | 
| 49 | 
            -
                        hash[key.deep_dup] = value.deep_dup
         | 
| 50 | 
            -
                      end
         | 
| 19 | 
            +
              def deep_dup
         | 
| 20 | 
            +
                dup.tap do |hash|
         | 
| 21 | 
            +
                  each_pair do |key, value|
         | 
| 22 | 
            +
                    if key.frozen? && key.is_a?(::String)
         | 
| 23 | 
            +
                      hash[key] = value.deep_dup
         | 
| 24 | 
            +
                    else
         | 
| 25 | 
            +
                      hash.delete(key)
         | 
| 26 | 
            +
                      hash[key.deep_dup] = value.deep_dup
         | 
| 51 27 | 
             
                    end
         | 
| 52 28 | 
             
                  end
         | 
| 53 29 | 
             
                end
         | 
| @@ -1,34 +1,22 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'chamber/errors/non_conforming_key'
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            module Chamber
         | 
| 4 6 | 
             
            module Refinements
         | 
| 5 7 | 
             
            class  Enumerable
         | 
| 6 | 
            -
              def self. | 
| 8 | 
            +
              def self.deep_validate_keys(object, &block)
         | 
| 7 9 | 
             
                case object
         | 
| 8 10 | 
             
                when ::Hash
         | 
| 9 | 
            -
                  object. | 
| 10 | 
            -
                     | 
| 11 | 
            -
                  end
         | 
| 12 | 
            -
                when ::Array
         | 
| 13 | 
            -
                  object.map { |e| deep_transform_keys(e, &block) }
         | 
| 14 | 
            -
                else
         | 
| 15 | 
            -
                  object
         | 
| 16 | 
            -
                end
         | 
| 17 | 
            -
              end
         | 
| 11 | 
            +
                  object.each do |(key, value)|
         | 
| 12 | 
            +
                    fail ::Chamber::Errors::NonConformingKey unless key == yield(key)
         | 
| 18 13 |  | 
| 19 | 
            -
             | 
| 20 | 
            -
                case value
         | 
| 21 | 
            -
                when ::Hash
         | 
| 22 | 
            -
                  value.each_with_object({}) do |(k, v), memo|
         | 
| 23 | 
            -
                    memo[k] = deep_transform_values(k, v, &block)
         | 
| 14 | 
            +
                    deep_validate_keys(value, &block)
         | 
| 24 15 | 
             
                  end
         | 
| 25 16 | 
             
                when ::Array
         | 
| 26 | 
            -
                   | 
| 27 | 
            -
                    key,
         | 
| 28 | 
            -
                    value.map { |v| deep_transform_values(nil, v, &block) }
         | 
| 29 | 
            -
                  )
         | 
| 17 | 
            +
                  object.map { |v| deep_validate_keys(v, &block) }
         | 
| 30 18 | 
             
                else
         | 
| 31 | 
            -
                   | 
| 19 | 
            +
                  object
         | 
| 32 20 | 
             
                end
         | 
| 33 21 | 
             
              end
         | 
| 34 22 | 
             
            end
         | 
| @@ -1,47 +1,21 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require 'rspectacular'
         | 
| 4 | 
            -
            require 'chamber/refinements/hash'
         | 
| 5 | 
            -
            require 'chamber/refinements/enumerable'
         | 
| 6 | 
            -
             | 
| 7 3 | 
             
            module Chamber
         | 
| 8 4 | 
             
            module Refinements
         | 
| 9 5 | 
             
            module Hash
         | 
| 10 6 | 
             
            refine ::Hash do
         | 
| 11 | 
            -
              def  | 
| 12 | 
            -
                 | 
| 13 | 
            -
                  if value.respond_to?(:strip)
         | 
| 14 | 
            -
                    self[key] = value.strip
         | 
| 15 | 
            -
                  elsif value.respond_to?(:deep_strip!)
         | 
| 16 | 
            -
                    self[key] = value.deep_strip!
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
              def deep_transform_keys(&block)
         | 
| 22 | 
            -
                Refinements::Enumerable.deep_transform_keys(self, &block)
         | 
| 23 | 
            -
              end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
              def deep_transform_values(&block)
         | 
| 26 | 
            -
                Refinements::Enumerable.deep_transform_values(nil, self, &block)
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              unless method_defined?(:deep_merge)
         | 
| 30 | 
            -
                def deep_merge(other, &block)
         | 
| 31 | 
            -
                  dup.deep_merge!(other, &block)
         | 
| 32 | 
            -
                end
         | 
| 7 | 
            +
              def deep_merge(other_hash, &block)
         | 
| 8 | 
            +
                dup.deep_merge!(other_hash, &block)
         | 
| 33 9 | 
             
              end
         | 
| 34 10 |  | 
| 35 | 
            -
               | 
| 36 | 
            -
                 | 
| 37 | 
            -
                   | 
| 38 | 
            -
                     | 
| 39 | 
            -
             | 
| 40 | 
            -
                     | 
| 41 | 
            -
             | 
| 42 | 
            -
                     | 
| 43 | 
            -
                      value_2
         | 
| 44 | 
            -
                    end
         | 
| 11 | 
            +
              def deep_merge!(other_hash, &block)
         | 
| 12 | 
            +
                merge!(other_hash) do |key, this_val, other_val|
         | 
| 13 | 
            +
                  if this_val.is_a?(::Hash) && other_val.is_a?(::Hash)
         | 
| 14 | 
            +
                    this_val.deep_merge(other_val, &block)
         | 
| 15 | 
            +
                  elsif block
         | 
| 16 | 
            +
                    yield(key, this_val, other_val)
         | 
| 17 | 
            +
                  else
         | 
| 18 | 
            +
                    other_val
         | 
| 45 19 | 
             
                  end
         | 
| 46 20 | 
             
                end
         | 
| 47 21 | 
             
              end
         | 
    
        data/lib/chamber/rubinius_fix.rb
    CHANGED
    
    
    
        data/lib/chamber/settings.rb
    CHANGED
    
    | @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'chamber/errors/missing_index'
         | 
| 4 | 
            +
            require 'chamber/errors/missing_setting'
         | 
| 3 5 | 
             
            require 'chamber/namespace_set'
         | 
| 4 6 | 
             
            require 'chamber/filters/namespace_filter'
         | 
| 5 7 | 
             
            require 'chamber/filters/encryption_filter'
         | 
| @@ -10,6 +12,7 @@ require 'chamber/filters/translate_secure_keys_filter' | |
| 10 12 | 
             
            require 'chamber/filters/insecure_filter'
         | 
| 11 13 | 
             
            require 'chamber/filters/failed_decryption_filter'
         | 
| 12 14 | 
             
            require 'chamber/refinements/deep_dup'
         | 
| 15 | 
            +
            require 'chamber/refinements/enumerable'
         | 
| 13 16 | 
             
            require 'chamber/refinements/hash'
         | 
| 14 17 |  | 
| 15 18 | 
             
            ###
         | 
| @@ -26,7 +29,6 @@ class   Settings | |
| 26 29 | 
             
                            :pre_filters,
         | 
| 27 30 | 
             
                            :secure_key_prefix
         | 
| 28 31 | 
             
              attr_reader   :namespaces
         | 
| 29 | 
            -
              attr_writer   :raw_data
         | 
| 30 32 |  | 
| 31 33 | 
             
              # rubocop:disable Metrics/ParameterLists
         | 
| 32 34 | 
             
              def initialize(
         | 
| @@ -46,9 +48,12 @@ class   Settings | |
| 46 48 | 
             
                              settings:          {},
         | 
| 47 49 | 
             
                              **_args
         | 
| 48 50 | 
             
                            )
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                 | 
| 51 | 
            -
             | 
| 51 | 
            +
             | 
| 52 | 
            +
                ::Chamber::Refinements::Enumerable.deep_validate_keys(settings, &:to_s)
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                self.decryption_keys   = (decryption_keys || {}).transform_keys(&:to_s)
         | 
| 55 | 
            +
                self.encryption_keys   = (encryption_keys || {}).transform_keys(&:to_s)
         | 
| 56 | 
            +
                self.namespaces        = NamespaceSet.new(namespaces)
         | 
| 52 57 | 
             
                self.post_filters      = post_filters
         | 
| 53 58 | 
             
                self.pre_filters       = pre_filters
         | 
| 54 59 | 
             
                self.raw_data          = settings.deep_dup
         | 
| @@ -114,7 +119,7 @@ class   Settings | |
| 114 119 | 
             
              # Returns a Hash
         | 
| 115 120 | 
             
              #
         | 
| 116 121 | 
             
              def to_hash
         | 
| 117 | 
            -
                data. | 
| 122 | 
            +
                data.deep_dup
         | 
| 118 123 | 
             
              end
         | 
| 119 124 |  | 
| 120 125 | 
             
              ###
         | 
| @@ -147,11 +152,11 @@ class   Settings | |
| 147 152 | 
             
                flattened_name_hash = {}
         | 
| 148 153 |  | 
| 149 154 | 
             
                hash.each_pair do |key, value|
         | 
| 150 | 
            -
                  flattened_name_components = parent_keys. | 
| 155 | 
            +
                  flattened_name_components = parent_keys.dup.push(key)
         | 
| 151 156 |  | 
| 152 157 | 
             
                  if value.respond_to?(:each_pair)
         | 
| 153 | 
            -
                    flattened_name_hash
         | 
| 154 | 
            -
             | 
| 158 | 
            +
                    flattened_name_hash.merge! to_flattened_name_hash(value,
         | 
| 159 | 
            +
                                                                      flattened_name_components)
         | 
| 155 160 | 
             
                  else
         | 
| 156 161 | 
             
                    flattened_name_hash[flattened_name_components] = value
         | 
| 157 162 | 
             
                  end
         | 
| @@ -197,7 +202,7 @@ class   Settings | |
| 197 202 | 
             
                other_settings = case other
         | 
| 198 203 | 
             
                                 when Settings
         | 
| 199 204 | 
             
                                   other
         | 
| 200 | 
            -
                                 when  | 
| 205 | 
            +
                                 when Hash
         | 
| 201 206 | 
             
                                   Settings.new(settings: other)
         | 
| 202 207 | 
             
                                 end
         | 
| 203 208 |  | 
| @@ -233,10 +238,13 @@ class   Settings | |
| 233 238 | 
             
              end
         | 
| 234 239 |  | 
| 235 240 | 
             
              def [](key)
         | 
| 236 | 
            -
                 | 
| 237 | 
            -
                warn "WARNING: Accessing a non-existent key ('#{key}') with brackets will fail in Chamber 3.0.  See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#bracket-access-now-fails-on-non-existent-keys for full details." unless data.has_key?(key) # rubocop:disable Layout/LineLength
         | 
| 241 | 
            +
                fail ::Chamber::Errors::InvalidKeyType, 'Bracket access with anything other than a String is unsupported.' unless key.is_a?(::String)
         | 
| 238 242 |  | 
| 239 243 | 
             
                data.fetch(key)
         | 
| 244 | 
            +
              rescue ::KeyError => error
         | 
| 245 | 
            +
                missing_setting_name = error.message.gsub(/.*key not found: "([^"]+)".*/, '\1')
         | 
| 246 | 
            +
             | 
| 247 | 
            +
                raise ::Chamber::Errors::MissingSetting.new(missing_setting_name, [])
         | 
| 240 248 | 
             
              end
         | 
| 241 249 |  | 
| 242 250 | 
             
              def dig!(*args)
         | 
| @@ -245,23 +253,33 @@ class   Settings | |
| 245 253 |  | 
| 246 254 | 
             
                  data_value.fetch(key)
         | 
| 247 255 | 
             
                end
         | 
| 256 | 
            +
              rescue ::KeyError => error
         | 
| 257 | 
            +
                missing_setting_name = error.message.gsub(/.*key not found: "([^"]+)".*/, '\1')
         | 
| 258 | 
            +
             | 
| 259 | 
            +
                raise ::Chamber::Errors::MissingSetting.new(missing_setting_name, args)
         | 
| 260 | 
            +
              rescue ::IndexError => error
         | 
| 261 | 
            +
                missing_index_number = error.message.gsub(/.*index (\d+) outside.*/, '\1')
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                raise ::Chamber::Errors::MissingIndex.new(missing_index_number, args)
         | 
| 248 264 | 
             
              end
         | 
| 249 265 |  | 
| 250 266 | 
             
              def dig(*args)
         | 
| 251 267 | 
             
                dig!(*args)
         | 
| 252 | 
            -
              rescue :: | 
| 268 | 
            +
              rescue ::Chamber::Errors::MissingSetting,
         | 
| 269 | 
            +
                     ::Chamber::Errors::MissingIndex
         | 
| 270 | 
            +
             | 
| 253 271 | 
             
                nil
         | 
| 254 272 | 
             
              end
         | 
| 255 273 |  | 
| 256 274 | 
             
              def securable
         | 
| 257 | 
            -
                Settings.new(**metadata. | 
| 275 | 
            +
                Settings.new(**metadata.merge(
         | 
| 258 276 | 
             
                               settings:    raw_data,
         | 
| 259 277 | 
             
                               pre_filters: [Filters::SecureFilter],
         | 
| 260 278 | 
             
                             ))
         | 
| 261 279 | 
             
              end
         | 
| 262 280 |  | 
| 263 281 | 
             
              def secure
         | 
| 264 | 
            -
                Settings.new(**metadata. | 
| 282 | 
            +
                Settings.new(**metadata.merge(
         | 
| 265 283 | 
             
                               settings:     raw_data,
         | 
| 266 284 | 
             
                               pre_filters:  [Filters::EncryptionFilter],
         | 
| 267 285 | 
             
                               post_filters: [Filters::TranslateSecureKeysFilter],
         | 
| @@ -269,7 +287,7 @@ class   Settings | |
| 269 287 | 
             
              end
         | 
| 270 288 |  | 
| 271 289 | 
             
              def insecure
         | 
| 272 | 
            -
                Settings.new(**metadata. | 
| 290 | 
            +
                Settings.new(**metadata.merge(
         | 
| 273 291 | 
             
                               settings:     raw_data,
         | 
| 274 292 | 
             
                               pre_filters:  [Filters::InsecureFilter],
         | 
| 275 293 | 
             
                               post_filters: [Filters::TranslateSecureKeysFilter],
         | 
| @@ -278,23 +296,21 @@ class   Settings | |
| 278 296 |  | 
| 279 297 | 
             
              protected
         | 
| 280 298 |  | 
| 281 | 
            -
               | 
| 282 | 
            -
             | 
| 283 | 
            -
              end
         | 
| 299 | 
            +
              attr_writer :namespaces,
         | 
| 300 | 
            +
                          :raw_data
         | 
| 284 301 |  | 
| 285 302 | 
             
              # rubocop:disable Naming/MemoizedInstanceVariableName
         | 
| 286 303 | 
             
              def raw_data
         | 
| 287 304 | 
             
                @filtered_raw_data ||= pre_filters.inject(@raw_data) do |filtered_data, filter|
         | 
| 288 | 
            -
                  filter.execute(**{ data: filtered_data }. | 
| 305 | 
            +
                  filter.execute(**{ data: filtered_data }.merge(metadata))
         | 
| 289 306 | 
             
                end
         | 
| 290 307 | 
             
              end
         | 
| 291 308 | 
             
              # rubocop:enable Naming/MemoizedInstanceVariableName
         | 
| 292 309 |  | 
| 293 310 | 
             
              def data
         | 
| 294 | 
            -
                @data ||= post_filters
         | 
| 295 | 
            -
             | 
| 296 | 
            -
             | 
| 297 | 
            -
                            end
         | 
| 311 | 
            +
                @data ||= post_filters.inject(raw_data) do |filtered_data, filter|
         | 
| 312 | 
            +
                  filter.execute(**{ data: filtered_data }.merge(metadata))
         | 
| 313 | 
            +
                end
         | 
| 298 314 | 
             
              end
         | 
| 299 315 |  | 
| 300 316 | 
             
              def metadata
         |