chamber 2.14.3 → 3.0.0rc2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08e636d1674a305c9d330e9adf5be147b1e5c2d2c57f131da98a216e3d3b3111'
4
- data.tar.gz: 7848e6ca2e2e4de843eedc65f9ca5315c18e71f9a8a2ba67a37c0ea46930a482
3
+ metadata.gz: 9de7c74ea902d381006bd6b5f05bae3680d1beef940ae75e483f30c923bc310f
4
+ data.tar.gz: b6f45eb5b668a5964e898ffb4caa5b9a3e9bc227736dd0e687e257cff0c99f84
5
5
  SHA512:
6
- metadata.gz: 8337ba8c0c7cc899f40bb712a455e5ee56e878ed11f6258e0917863acf194b4cac1a4b11ff087a4c72ed7e5550972fc2d097dafd5b26492a40c8094bd33a744a
7
- data.tar.gz: 27b49b8592d343b050491f2a2d22cbd69323989ac031abc9d6a2bf375a30887cd16580d9c76259a4475c9f42d6603aa73769754b454bbfa55bac98e493ae9c3b
6
+ metadata.gz: b1ab7fedfaf6cb26ab3e97402966368f3e686751ca76e441a7d9db64b7fe354a289ac4ac330cac806fb7960f3b4750c1ce4f7799e548c4f0f549ee57826e8552
7
+ data.tar.gz: 64cfa0683ca78d71cd620e38e60c4d2c25683c5217d74858995b2ee65eda704f7d2aca9395451ac743424bd75b8974ee088ed3563e192be5ab057f49ad458165
checksums.yaml.gz.sig CHANGED
Binary file
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
- require 'chamber/core_ext/hash'
5
4
  require 'chamber/commands/cloud/clear'
6
5
  require 'chamber/commands/cloud/push'
7
6
  require 'chamber/commands/cloud/pull'
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
- require 'chamber/core_ext/hash'
5
4
  require 'chamber/commands/cloud/clear'
6
5
  require 'chamber/commands/cloud/push'
7
6
  require 'chamber/commands/cloud/pull'
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
- require 'chamber/core_ext/hash'
5
4
  require 'chamber/rubinius_fix'
6
5
  require 'chamber/binary/travis'
7
6
  require 'chamber/binary/heroku'
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
- require 'chamber/core_ext/hash'
5
4
  require 'chamber/commands/travis/secure'
6
5
 
7
6
  module Chamber
@@ -194,7 +194,7 @@ class Initialize < Chamber::Commands::Base
194
194
  .chamber*.enc.pass
195
195
  !.chamber*.pub.pem
196
196
  }.each do |pattern|
197
- unless gitignore_contents =~ Regexp.new(Regexp.escape(pattern))
197
+ unless gitignore_contents&.match?(Regexp.new(Regexp.escape(pattern)))
198
198
  shell.append_to_file gitignore_filepath, "#{pattern}\n"
199
199
  end
200
200
  end
@@ -2,55 +2,41 @@
2
2
 
3
3
  require 'base64'
4
4
 
5
+ require 'chamber/errors/disallowed_class'
6
+
5
7
  module Chamber
6
8
  module EncryptionMethods
7
9
  class PublicKey
8
- def self.encrypt(_key, value, encryption_key)
10
+ def self.encrypt(_settings_key, value, encryption_key)
9
11
  value = YAML.dump(value)
10
12
  encrypted_string = encryption_key.public_encrypt(value)
11
13
 
12
14
  Base64.strict_encode64(encrypted_string)
13
15
  end
14
16
 
15
- def self.decrypt(_key, value, decryption_key)
16
- if decryption_key.nil?
17
- value
18
- else
19
- decoded_string = Base64.strict_decode64(value)
20
- unencrypted_value = decryption_key.private_decrypt(decoded_string)
21
-
22
- begin
23
- _unserialized_value = begin
24
- YAML.safe_load(unencrypted_value,
25
- aliases: true,
26
- permitted_classes: [
27
- ::Date,
28
- ::Time,
29
- ::Regexp,
30
- ])
31
- rescue ::Psych::DisallowedClass => error
32
- warn <<-HEREDOC
33
- WARNING: Recursive data structures (complex classes) being loaded from Chamber
34
- has been deprecated and will be removed in 3.0.
35
-
36
- See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#limiting-complex-classes
37
- for full details.
38
-
39
- #{error.message}
40
-
41
- Called from: '#{caller.to_a[8]}'
42
- HEREDOC
43
-
44
- if YAML.respond_to?(:unsafe_load)
45
- YAML.unsafe_load(unencrypted_value)
46
- else
47
- YAML.load(unencrypted_value)
48
- end
49
- end
50
- rescue TypeError
51
- unencrypted_value
52
- end
53
- end
17
+ def self.decrypt(_settings_key, value, decryption_key)
18
+ return value if decryption_key.nil?
19
+
20
+ decoded_string = ::Base64.strict_decode64(value)
21
+ unencrypted_value = decryption_key.private_decrypt(decoded_string)
22
+
23
+ ::YAML.safe_load(unencrypted_value,
24
+ aliases: true,
25
+ permitted_classes: [
26
+ ::Date,
27
+ ::Time,
28
+ ::Regexp,
29
+ ])
30
+ rescue ::Psych::DisallowedClass => error
31
+ raise ::Chamber::Errors::DisallowedClass, <<~HEREDOC
32
+ #{error.message}
33
+
34
+ You attempted to load a class instance via your Chamber settings that is not allowed.
35
+
36
+ See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#limiting-complex-classes for full details.
37
+ HEREDOC
38
+ rescue ::TypeError
39
+ unencrypted_value
54
40
  end
55
41
  end
56
42
  end
@@ -16,7 +16,7 @@ class Ssl
16
16
  \z
17
17
  /x.freeze
18
18
 
19
- def self.encrypt(_key, value, encryption_keys) # rubocop:disable Metrics/AbcSize
19
+ def self.encrypt(_settings_key, value, encryption_keys) # rubocop:disable Metrics/AbcSize
20
20
  value = YAML.dump(value)
21
21
  cipher = OpenSSL::Cipher.new('AES-128-CBC')
22
22
  cipher.encrypt
@@ -35,64 +35,46 @@ class Ssl
35
35
  Base64.strict_encode64(encrypted_data)
36
36
  end
37
37
 
38
- def self.decrypt(key, value, decryption_keys) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
39
- if decryption_keys.nil?
40
- value
41
- else
42
- key, iv, decoded_string = value
43
- .match(LARGE_DATA_STRING_PATTERN)
44
- .captures
45
- .map do |part|
46
- Base64.strict_decode64(part)
47
- end
48
- key = decryption_keys.private_decrypt(key)
38
+ def self.decrypt(_settings_key, value, decryption_keys) # rubocop:disable Metrics/AbcSize
39
+ return value if decryption_keys.nil?
49
40
 
50
- cipher_dec = OpenSSL::Cipher.new('AES-128-CBC')
51
-
52
- cipher_dec.decrypt
41
+ key, iv, decoded_string = value
42
+ .match(LARGE_DATA_STRING_PATTERN)
43
+ .captures
44
+ .map do |part|
45
+ ::Base64.strict_decode64(part)
46
+ end
47
+ key = decryption_keys.private_decrypt(key)
53
48
 
54
- cipher_dec.key = key
55
- cipher_dec.iv = iv
49
+ cipher_dec = ::OpenSSL::Cipher.new('AES-128-CBC')
56
50
 
57
- begin
58
- unencrypted_value = cipher_dec.update(decoded_string) + cipher_dec.final
59
- rescue OpenSSL::Cipher::CipherError
60
- raise Chamber::Errors::DecryptionFailure,
61
- 'A decryption error occurred. It was probably due to invalid key data.'
62
- end
51
+ cipher_dec.decrypt
63
52
 
64
- begin
65
- _unserialized_value = begin
66
- YAML.safe_load(unencrypted_value,
67
- aliases: true,
68
- permitted_classes: [
69
- ::Date,
70
- ::Time,
71
- ::Regexp,
72
- ])
73
- rescue ::Psych::DisallowedClass => error
74
- warn <<-HEREDOC
75
- WARNING: Recursive data structures (complex classes) being loaded from Chamber
76
- has been deprecated and will be removed in 3.0.
53
+ cipher_dec.key = key
54
+ cipher_dec.iv = iv
77
55
 
78
- See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#limiting-complex-classes
79
- for full details.
56
+ unencrypted_value = cipher_dec.update(decoded_string) + cipher_dec.final
80
57
 
81
- #{error.message}
58
+ ::YAML.safe_load(unencrypted_value,
59
+ aliases: true,
60
+ permitted_classes: [
61
+ ::Date,
62
+ ::Time,
63
+ ::Regexp,
64
+ ])
65
+ rescue ::OpenSSL::Cipher::CipherError
66
+ raise ::Chamber::Errors::DecryptionFailure,
67
+ 'A decryption error occurred. It was probably due to invalid key data.'
68
+ rescue ::Psych::DisallowedClass => error
69
+ raise ::Chamber::Errors::DisallowedClass, <<~HEREDOC
70
+ #{error.message}
82
71
 
83
- Called from: '#{caller.to_a[8]}'
84
- HEREDOC
72
+ You attempted to load a class instance via your Chamber settings that is not allowed.
85
73
 
86
- if YAML.respond_to?(:unsafe_load)
87
- YAML.unsafe_load(unencrypted_value)
88
- else
89
- YAML.load(unencrypted_value)
90
- end
91
- end
92
- rescue TypeError
93
- unencrypted_value
94
- end
95
- end
74
+ See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#limiting-complex-classes for full details.
75
+ HEREDOC
76
+ rescue ::TypeError
77
+ unencrypted_value
96
78
  end
97
79
  end
98
80
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chamber
4
+ module Errors
5
+ class DisallowedClass < ::Psych::DisallowedClass
6
+ end
7
+ end
8
+ end
data/lib/chamber/file.rb CHANGED
@@ -139,38 +139,26 @@ class File < Pathname
139
139
  @secure_prefix_pattern ||= Regexp.escape(secure_prefix)
140
140
  end
141
141
 
142
- def file_contents_hash # rubocop:disable Metrics/CyclomaticComplexity
142
+ def file_contents_hash
143
143
  file_contents = read
144
- erb_result = ERB.new(file_contents).result
144
+ erb_result = ::ERB.new(file_contents).result
145
145
 
146
- begin
147
- YAML.safe_load(erb_result,
146
+ ::YAML.safe_load(erb_result,
148
147
  aliases: true,
149
148
  permitted_classes: [
150
149
  ::Date,
151
150
  ::Time,
152
151
  ::Regexp,
153
152
  ]) || {}
154
- rescue ::Psych::DisallowedClass => error
155
- warn <<-HEREDOC
156
- WARNING: Recursive data structures (complex classes) being loaded from Chamber
157
- has been deprecated and will be removed in 3.0.
153
+ rescue ::Psych::DisallowedClass => error
154
+ raise ::Chamber::Errors::DisallowedClass, <<~HEREDOC
155
+ #{error.message}
158
156
 
159
- See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#limiting-complex-classes
160
- for full details.
157
+ You attempted to load a class instance via your Chamber settings that is not allowed.
161
158
 
162
- #{error.message}
163
-
164
- Called from: '#{caller.to_a[2]}'
165
- HEREDOC
166
-
167
- if YAML.respond_to?(:unsafe_load)
168
- YAML.unsafe_load(erb_result) || {}
169
- else
170
- YAML.load(erb_result) || {}
171
- end
172
- end
173
- rescue Errno::ENOENT
159
+ See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#limiting-complex-classes for full details.
160
+ HEREDOC
161
+ rescue ::Errno::ENOENT
174
162
  {}
175
163
  end
176
164
  end
@@ -42,13 +42,13 @@ class Signature
42
42
  end
43
43
 
44
44
  def write
45
- signature_filename.write(<<-HEREDOC, 0, mode: 'w+')
46
- Signed By: #{signature_name}
47
- Signed At: #{Time.now.utc.iso8601}
45
+ signature_filename.write(<<~HEREDOC, 0, mode: 'w+')
46
+ Signed By: #{signature_name}
47
+ Signed At: #{Time.now.utc.iso8601}
48
48
 
49
- #{SIGNATURE_HEADER}
50
- #{encoded_signature}
51
- #{SIGNATURE_FOOTER}
49
+ #{SIGNATURE_HEADER}
50
+ #{encoded_signature}
51
+ #{SIGNATURE_FOOTER}
52
52
  HEREDOC
53
53
  end
54
54
 
@@ -2,16 +2,18 @@
2
2
 
3
3
  require 'openssl'
4
4
  require 'base64'
5
- require 'hashie/mash'
6
5
  require 'yaml'
7
6
  require 'chamber/encryption_methods/public_key'
8
7
  require 'chamber/encryption_methods/ssl'
9
8
  require 'chamber/encryption_methods/none'
10
9
  require 'chamber/errors/decryption_failure'
10
+ require 'chamber/refinements/deep_dup'
11
11
 
12
12
  module Chamber
13
13
  module Filters
14
14
  class DecryptionFilter
15
+ using ::Chamber::Refinements::DeepDup
16
+
15
17
  BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}.freeze
16
18
  LARGE_DATA_STRING_PATTERN = %r{
17
19
  \A # Beginning of String
@@ -34,8 +36,8 @@ class DecryptionFilter
34
36
  attr_reader :decryption_keys
35
37
 
36
38
  def initialize(data:, secure_key_prefix:, decryption_keys: {}, **_args)
37
- self.decryption_keys = decryption_keys || {}
38
- self.data = data.dup
39
+ self.decryption_keys = (decryption_keys || {}).transform_keys(&:to_s)
40
+ self.data = data.deep_dup
39
41
  self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
40
42
  end
41
43
 
@@ -46,7 +48,7 @@ class DecryptionFilter
46
48
  protected
47
49
 
48
50
  def execute(raw_data = data)
49
- settings = Hashie::Mash.new
51
+ settings = {}
50
52
 
51
53
  raw_data.each_pair do |key, value|
52
54
  settings[key] = if value.respond_to? :each_pair
@@ -75,21 +77,17 @@ class DecryptionFilter
75
77
 
76
78
  private
77
79
 
78
- # rubocop:disable Style/RedundantBegin
79
80
  def decrypt(key, value)
80
81
  method = decryption_method(value)
81
82
 
82
83
  decryption_keys.each do |decryption_key|
83
- begin
84
- return method.decrypt(key, value, decryption_key)
85
- rescue OpenSSL::PKey::RSAError
86
- next
87
- end
84
+ return method.decrypt(key, value, decryption_key)
85
+ rescue OpenSSL::PKey::RSAError
86
+ next
88
87
  end
89
88
 
90
89
  value
91
90
  end
92
- # rubocop:enable Style/RedundantBegin
93
91
 
94
92
  def decryption_method(value)
95
93
  if value.is_a?(::String)
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openssl'
4
- require 'hashie/mash'
5
4
  require 'yaml'
6
5
  require 'chamber/encryption_methods/public_key'
7
6
  require 'chamber/encryption_methods/ssl'
8
7
  require 'chamber/encryption_methods/none'
8
+ require 'chamber/refinements/deep_dup'
9
9
 
10
10
  module Chamber
11
11
  module Filters
12
12
  class EncryptionFilter
13
+ using ::Chamber::Refinements::DeepDup
14
+
13
15
  BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}.freeze
14
16
  BASE64_SUBSTRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}.freeze
15
17
  LARGE_DATA_STRING_PATTERN = /
@@ -27,8 +29,8 @@ class EncryptionFilter
27
29
  attr_reader :encryption_keys
28
30
 
29
31
  def initialize(data:, secure_key_prefix:, encryption_keys: {}, **_args)
30
- self.encryption_keys = encryption_keys || {}
31
- self.data = data.dup
32
+ self.encryption_keys = (encryption_keys || {}).transform_keys(&:to_s)
33
+ self.data = data.deep_dup
32
34
  self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
33
35
  end
34
36
 
@@ -39,7 +41,7 @@ class EncryptionFilter
39
41
  protected
40
42
 
41
43
  def execute(raw_data = data, namespace = nil)
42
- raw_data.each_with_object(Hashie::Mash.new) do |(key, value), settings|
44
+ raw_data.each_with_object({}) do |(key, value), settings|
43
45
  settings[key] = if value.respond_to? :each_pair
44
46
  execute(value, namespace || key)
45
47
  elsif key.match(secure_key_token)
@@ -51,7 +53,7 @@ class EncryptionFilter
51
53
  end
52
54
 
53
55
  def encryption_keys=(other)
54
- @encryption_keys = other.each_with_object({}) do |(namespace, keyish), memo|
56
+ @encryption_keys = other.each_with_object({}) do |(namespace, keyish), memo| # rubocop:disable Style/HashTransformValues
55
57
  memo[namespace] = if keyish.is_a?(OpenSSL::PKey::RSA)
56
58
  keyish
57
59
  elsif ::File.readable?(::File.expand_path(keyish))
@@ -67,7 +69,7 @@ class EncryptionFilter
67
69
 
68
70
  def encrypt(namespace, key, value)
69
71
  method = encryption_method(value)
70
- encryption_key = encryption_keys[namespace] || encryption_keys[:__default]
72
+ encryption_key = encryption_keys[namespace] || encryption_keys['__default']
71
73
 
72
74
  return value unless encryption_key
73
75
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yaml'
4
- require 'hashie/mash'
5
4
 
6
5
  require 'chamber/errors/environment_conversion'
7
6
 
@@ -122,7 +121,7 @@ class EnvironmentFilter
122
121
  private
123
122
 
124
123
  def with_environment(settings, parent_keys, hash_block, value_block)
125
- environment_hash = Hashie::Mash.new
124
+ environment_hash = {}
126
125
 
127
126
  settings.each_pair do |key, value|
128
127
  environment_key = key.to_s.gsub(secure_key_token, '')
@@ -170,13 +169,13 @@ class EnvironmentFilter
170
169
  environment_value
171
170
  end
172
171
  rescue ArgumentError
173
- raise Chamber::Errors::EnvironmentConversion, <<-HEREDOC
174
- 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}'.
175
174
 
176
- Unfortunately, this did not go as planned. Please either verify that your value is convertable
177
- 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).
178
177
 
179
- 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
180
179
  HEREDOC
181
180
  end
182
181
  end
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'chamber/errors/decryption_failure'
4
+ require 'chamber/refinements/deep_dup'
4
5
 
5
6
  module Chamber
6
7
  module Filters
7
8
  class FailedDecryptionFilter
9
+ using ::Chamber::Refinements::DeepDup
10
+
8
11
  BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}.freeze
9
12
 
10
13
  def self.execute(**args)
@@ -15,7 +18,7 @@ class FailedDecryptionFilter
15
18
  :secure_key_token
16
19
 
17
20
  def initialize(data:, secure_key_prefix:, **_args)
18
- self.data = data.dup
21
+ self.data = data.deep_dup
19
22
  self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
20
23
  end
21
24
 
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'hashie/mash'
4
3
  require 'chamber/filters/secure_filter'
5
4
 
6
5
  module Chamber
@@ -22,7 +21,7 @@ class InsecureFilter < SecureFilter
22
21
 
23
22
  def execute(raw_data = data) # rubocop:disable Metrics/CyclomaticComplexity
24
23
  securable_settings = super
25
- settings = Hashie::Mash.new
24
+ settings = {}
26
25
 
27
26
  securable_settings.each_pair do |key, value|
28
27
  value = if value.respond_to? :each_pair
@@ -1,10 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'hashie/mash'
3
+ require 'chamber/refinements/deep_dup'
4
+ require 'chamber/refinements/hash'
4
5
 
5
6
  module Chamber
6
7
  module Filters
7
8
  class NamespaceFilter
9
+ using ::Chamber::Refinements::DeepDup
10
+ using ::Chamber::Refinements::Hash
11
+
8
12
  def self.execute(**args)
9
13
  new(**args).__send__(:execute)
10
14
  end
@@ -13,26 +17,24 @@ class NamespaceFilter
13
17
  :namespaces
14
18
 
15
19
  def initialize(data:, namespaces:, **_args)
16
- self.data = Hashie::Mash.new(data)
20
+ self.data = data.deep_dup
17
21
  self.namespaces = namespaces
18
22
  end
19
23
 
20
24
  protected
21
25
 
22
26
  def execute
23
- if data_is_namespaced?
24
- namespaces.each_with_object(Hashie::Mash.new) do |namespace, filtered_data|
25
- filtered_data.merge!(data[namespace]) if data[namespace]
26
- end
27
- else
28
- Hashie::Mash.new(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]
29
31
  end
30
32
  end
31
33
 
32
34
  private
33
35
 
34
36
  def data_is_namespaced?
35
- @data_is_namespaced ||= data.keys.any? { |key| namespaces.include? key.to_s }
37
+ @data_is_namespaced ||= data.keys.any? { |key| namespaces.include?(key.to_s) }
36
38
  end
37
39
  end
38
40
  end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'hashie/mash'
3
+ require 'chamber/refinements/deep_dup'
4
4
 
5
5
  module Chamber
6
6
  module Filters
7
7
  class SecureFilter
8
+ using ::Chamber::Refinements::DeepDup
9
+
8
10
  def self.execute(**args)
9
11
  new(**args).__send__(:execute)
10
12
  end
@@ -13,14 +15,14 @@ class SecureFilter
13
15
  :secure_key_token
14
16
 
15
17
  def initialize(data:, secure_key_prefix:, **_args)
16
- self.data = Hashie::Mash.new(data)
18
+ self.data = data.deep_dup
17
19
  self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
18
20
  end
19
21
 
20
22
  protected
21
23
 
22
24
  def execute(raw_data = data)
23
- settings = Hashie::Mash.new
25
+ settings = {}
24
26
 
25
27
  raw_data.each_pair do |key, value|
26
28
  secure_value = if value.respond_to? :each_pair
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'hashie/mash'
3
+ require 'chamber/refinements/deep_dup'
4
4
 
5
5
  module Chamber
6
6
  module Filters
7
7
  class TranslateSecureKeysFilter
8
+ using ::Chamber::Refinements::DeepDup
9
+
8
10
  def self.execute(**args)
9
11
  new(**args).__send__(:execute)
10
12
  end
@@ -13,14 +15,14 @@ class TranslateSecureKeysFilter
13
15
  :secure_key_token
14
16
 
15
17
  def initialize(data:, secure_key_prefix:, **_args)
16
- self.data = data.dup
18
+ self.data = data.deep_dup
17
19
  self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
18
20
  end
19
21
 
20
22
  protected
21
23
 
22
24
  def execute(raw_data = data)
23
- settings = Hashie::Mash.new
25
+ settings = {}
24
26
 
25
27
  raw_data.each_pair do |key, value|
26
28
  value = execute(value) if value.respond_to? :each_pair
@@ -92,15 +92,5 @@ class Instance
92
92
  )
93
93
  .to_hash
94
94
  end
95
-
96
- def method_missing(name, *args)
97
- return settings.public_send(name, *args) if settings.respond_to?(name)
98
-
99
- super
100
- end
101
-
102
- def respond_to_missing?(name, include_private = false)
103
- settings.respond_to?(name, include_private)
104
- end
105
95
  end
106
96
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chamber
4
+ module Refinements
5
+ module DeepDup
6
+ refine ::Array do
7
+ def deep_dup
8
+ map { |i| i.respond_to?(:deep_dup) ? i.deep_dup : i.dup }
9
+ end
10
+ end
11
+
12
+ refine ::Object do
13
+ def deep_dup
14
+ dup
15
+ end
16
+ end
17
+
18
+ refine ::Hash do
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
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -9,8 +9,7 @@ class Enumerable
9
9
  case object
10
10
  when ::Hash
11
11
  object.each do |(key, value)|
12
- # fail ::Chamber::Errors::NonConformingKey unless key == yield(key)
13
- warn "WARNING: Non-String settings keys are deprecated and will be removed in Chamber 3.0. You attempted to access the '#{key}' setting. See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#all-settings-keys-are-now-stored-as-strings for full details. Called from: '#{caller.to_a.first}'" unless key == yield(key) # rubocop:disable Layout/LineLength
12
+ fail ::Chamber::Errors::NonConformingKey unless key == yield(key)
14
13
 
15
14
  deep_validate_keys(value, &block)
16
15
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chamber
4
+ module Refinements
5
+ module Hash
6
+ refine ::Hash do
7
+ def deep_merge(other_hash, &block)
8
+ dup.deep_merge!(other_hash, &block)
9
+ end
10
+
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
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'hashie/mash'
4
3
  require 'chamber/namespace_set'
5
4
  require 'chamber/filters/namespace_filter'
6
5
  require 'chamber/filters/encryption_filter'
@@ -10,13 +9,18 @@ require 'chamber/filters/secure_filter'
10
9
  require 'chamber/filters/translate_secure_keys_filter'
11
10
  require 'chamber/filters/insecure_filter'
12
11
  require 'chamber/filters/failed_decryption_filter'
12
+ require 'chamber/refinements/deep_dup'
13
13
  require 'chamber/refinements/enumerable'
14
+ require 'chamber/refinements/hash'
14
15
 
15
16
  ###
16
17
  # Internal: Represents the base settings storage needed for Chamber.
17
18
  #
18
19
  module Chamber
19
20
  class Settings
21
+ using ::Chamber::Refinements::Hash
22
+ using ::Chamber::Refinements::DeepDup
23
+
20
24
  attr_accessor :decryption_keys,
21
25
  :encryption_keys,
22
26
  :post_filters,
@@ -45,12 +49,12 @@ class Settings
45
49
 
46
50
  ::Chamber::Refinements::Enumerable.deep_validate_keys(settings, &:to_s)
47
51
 
48
- self.decryption_keys = decryption_keys
49
- self.encryption_keys = encryption_keys
50
- self.namespaces = namespaces
52
+ self.decryption_keys = (decryption_keys || {}).transform_keys(&:to_s)
53
+ self.encryption_keys = (encryption_keys || {}).transform_keys(&:to_s)
54
+ self.namespaces = NamespaceSet.new(namespaces)
51
55
  self.post_filters = post_filters
52
56
  self.pre_filters = pre_filters
53
- self.raw_data = settings
57
+ self.raw_data = settings.deep_dup
54
58
  self.secure_key_prefix = secure_key_prefix
55
59
  end
56
60
  # rubocop:enable Metrics/ParameterLists
@@ -113,7 +117,7 @@ class Settings
113
117
  # Returns a Hash
114
118
  #
115
119
  def to_hash
116
- data.to_hash
120
+ data.deep_dup
117
121
  end
118
122
 
119
123
  ###
@@ -205,7 +209,7 @@ class Settings
205
209
  encryption_keys: encryption_keys.any? ? encryption_keys : other_settings.encryption_keys,
206
210
  decryption_keys: decryption_keys.any? ? decryption_keys : other_settings.decryption_keys,
207
211
  namespaces: (namespaces + other_settings.namespaces),
208
- settings: raw_data.merge(other_settings.raw_data),
212
+ settings: raw_data.deep_merge(other_settings.raw_data),
209
213
  )
210
214
  # rubocop:enable Layout/LineLength
211
215
  end
@@ -232,10 +236,9 @@ class Settings
232
236
  end
233
237
 
234
238
  def [](key)
235
- warn "WARNING: Bracket access will require strings instead of symbols in Chamber 3.0. You attempted to access the '#{key}' setting. See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#removal-of-bracket-indifferent-access for full details. Called from: '#{caller.to_a.first}'" if key.is_a?(::Symbol) # rubocop:disable Layout/LineLength
236
- 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. Called from: '#{caller.to_a.first}'" unless data.has_key?(key) # rubocop:disable Layout/LineLength
239
+ fail ::ArgumentError, 'Bracket access with anything other than a String is unsupported.' unless key.is_a?(::String)
237
240
 
238
- data.[](key)
241
+ data.fetch(key)
239
242
  end
240
243
 
241
244
  def dig!(*args)
@@ -275,30 +278,10 @@ class Settings
275
278
  ))
276
279
  end
277
280
 
278
- def method_missing(name, *args)
279
- if data.respond_to?(name)
280
- warn "WARNING: Object notation access is deprecated and will be removed in Chamber 3.0. You attempted to access the '#{name}' setting. See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#removal-of-object-notation-access for full details. Called from: '#{caller.to_a.first}'" # rubocop:disable Layout/LineLength
281
- warn "WARNING: Predicate methods are deprecated and will be removed in Chamber 3.0. You attempted to access the '#{name}' setting. See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#removal-of-predicate-accessors for full details. Called from: '#{caller.to_a.first}'" if name.to_s.end_with?('?') # rubocop:disable Layout/LineLength
282
-
283
- data.public_send(name, *args)
284
- else
285
- super
286
- end
287
- end
288
-
289
- def respond_to_missing?(name, include_private = false)
290
- data.respond_to?(name, include_private)
291
- end
292
-
293
281
  protected
294
282
 
295
- def raw_data=(new_raw_data)
296
- @raw_data = Hashie::Mash.new(new_raw_data)
297
- end
298
-
299
- def namespaces=(raw_namespaces)
300
- @namespaces = NamespaceSet.new(raw_namespaces)
301
- end
283
+ attr_writer :namespaces,
284
+ :raw_data
302
285
 
303
286
  # rubocop:disable Naming/MemoizedInstanceVariableName
304
287
  def raw_data
@@ -40,7 +40,7 @@ class Secured < CHAMBER_TYPE_VALUE_SUPERCLASS
40
40
  when Hash
41
41
  value
42
42
  when String
43
- ::ActiveSupport::JSON.decode(value)
43
+ ::JSON.parse(value)
44
44
  when NilClass
45
45
  nil
46
46
  else
@@ -63,10 +63,10 @@ class Secured < CHAMBER_TYPE_VALUE_SUPERCLASS
63
63
  def serialize(value)
64
64
  fail ArgumentError, 'Any attributes encrypted with Chamber must be a Hash' unless value.is_a?(Hash)
65
65
 
66
- ::ActiveSupport::JSON.encode(
67
- Chamber.encrypt(value,
68
- decryption_keys: decryption_keys,
69
- encryption_keys: encryption_keys),
66
+ ::JSON.dump(
67
+ ::Chamber.encrypt(value,
68
+ decryption_keys: decryption_keys,
69
+ encryption_keys: encryption_keys),
70
70
  )
71
71
  end
72
72
  alias type_cast_for_database serialize
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Chamber
4
- VERSION = '2.14.3'
4
+ VERSION = '3.0.0rc2'
5
5
  end
data/lib/chamber.rb CHANGED
@@ -11,10 +11,6 @@ module Chamber
11
11
  self.instance = Instance.new(**args)
12
12
  end
13
13
 
14
- def env
15
- instance.settings
16
- end
17
-
18
14
  def instance
19
15
  @instance ||= Instance.new
20
16
  end
@@ -81,29 +77,17 @@ module Chamber
81
77
  instance.to_s(**args)
82
78
  end
83
79
 
84
- def method_missing(name, *args)
85
- return instance.public_send(name, *args) if instance.respond_to?(name)
86
-
87
- super
88
- end
89
-
90
- def respond_to_missing?(name, include_private = false)
91
- instance.respond_to?(name, include_private)
92
- end
93
-
94
80
  module_function :[],
95
81
  :configuration,
96
82
  :decrypt,
97
83
  :dig!,
98
84
  :dig,
99
85
  :encrypt,
100
- :env,
101
86
  :filenames,
102
87
  :files,
103
88
  :instance,
104
89
  :instance=,
105
90
  :load,
106
- :method_missing,
107
91
  :namespaces,
108
92
  :respond_to_missing?,
109
93
  :secure,
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chamber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.14.3
4
+ version: 3.0.0rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - thekompanee
@@ -38,7 +38,7 @@ cert_chain:
38
38
  ZjvLRaDI6IVoq0skZju//VZLiN6slVhAYYQj0uka/T0DZieabVYDcT4BVpa9M7Gz
39
39
  CDW/VDWjvEEbsCIW0oYhtUrkqE8GLIdrpLUjefOERbS5TslD7lG/MH5k
40
40
  -----END CERTIFICATE-----
41
- date: 2022-03-05 00:00:00.000000000 Z
41
+ date: 2022-03-06 00:00:00.000000000 Z
42
42
  dependencies:
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: thor
@@ -60,20 +60,6 @@ dependencies:
60
60
  - - "<"
61
61
  - !ruby/object:Gem::Version
62
62
  version: '2.0'
63
- - !ruby/object:Gem::Dependency
64
- name: hashie
65
- requirement: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "~>"
68
- - !ruby/object:Gem::Version
69
- version: '3.3'
70
- type: :runtime
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - "~>"
75
- - !ruby/object:Gem::Version
76
- version: '3.3'
77
63
  - !ruby/object:Gem::Dependency
78
64
  name: rspec
79
65
  requirement: !ruby/object:Gem::Requirement
@@ -183,11 +169,11 @@ files:
183
169
  - lib/chamber/commands/verify.rb
184
170
  - lib/chamber/configuration.rb
185
171
  - lib/chamber/context_resolver.rb
186
- - lib/chamber/core_ext/hash.rb
187
172
  - lib/chamber/encryption_methods/none.rb
188
173
  - lib/chamber/encryption_methods/public_key.rb
189
174
  - lib/chamber/encryption_methods/ssl.rb
190
175
  - lib/chamber/errors/decryption_failure.rb
176
+ - lib/chamber/errors/disallowed_class.rb
191
177
  - lib/chamber/errors/environment_conversion.rb
192
178
  - lib/chamber/errors/non_conforming_key.rb
193
179
  - lib/chamber/file.rb
@@ -210,7 +196,9 @@ files:
210
196
  - lib/chamber/keys/encryption.rb
211
197
  - lib/chamber/namespace_set.rb
212
198
  - lib/chamber/rails.rb
199
+ - lib/chamber/refinements/deep_dup.rb
213
200
  - lib/chamber/refinements/enumerable.rb
201
+ - lib/chamber/refinements/hash.rb
214
202
  - lib/chamber/rubinius_fix.rb
215
203
  - lib/chamber/settings.rb
216
204
  - lib/chamber/types/secured.rb
@@ -235,14 +223,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
235
223
  requirements:
236
224
  - - ">="
237
225
  - !ruby/object:Gem::Version
238
- version: 2.1.0
226
+ version: 2.7.5
239
227
  required_rubygems_version: !ruby/object:Gem::Requirement
240
228
  requirements:
241
- - - ">="
229
+ - - ">"
242
230
  - !ruby/object:Gem::Version
243
- version: '0'
231
+ version: 1.3.1
244
232
  requirements: []
245
- rubygems_version: 3.1.4
233
+ rubygems_version: 3.1.6
246
234
  signing_key:
247
235
  specification_version: 4
248
236
  summary: A surprisingly configurable convention-based approach to managing your application's
metadata.gz.sig CHANGED
Binary file
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Hash
4
- def transform_keys
5
- return enum_for(:transform_keys) { size } unless block_given?
6
-
7
- result = {}
8
-
9
- each_key do |key|
10
- result[yield(key)] = self[key]
11
- end
12
-
13
- result
14
- end
15
- end