chamber 2.14.2 → 3.0.0rc1

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: 89e0b6151f3cafb916f399bd49b780f6df353ab41832012c48a2f5520a03df5d
4
- data.tar.gz: 4e976be3b9be2b3b2e30185895a3c2d330daa3880298a65ead34e30ca5befd81
3
+ metadata.gz: 3119f8787d3c63913a0ab69a0114cbf6d43a154ad1703aef610a2b02720b0cbc
4
+ data.tar.gz: ed25f8e4a9f93045c94aba4776fa6a0296f9db9f1312e4a1dadeb35343eba140
5
5
  SHA512:
6
- metadata.gz: aa7e4a481d465da58e4b99f06e868f0b97fd9242e429ad0a233f6b2763930696ab60eb43d276a8e26aa5a245734e1c5dcce7bb08c1b568ebec83bddb9cc7d6c9
7
- data.tar.gz: 3f9bdb837c924886b72b685d01debdb5ffcb33d1fa1220cf6c243bfde6e3d2b76f1579b565095cf355af54ee43fef8a722ed871bd2a72f484283b2adefe4e5cc
6
+ metadata.gz: acc3d5daf9e6570ccf16e76b8433e8d0912cdd85f4858f6634ee37531aa6a1c53b47621afeb21c0b9524eea6f8af3a02b52872f843b28a3f94d3e20bfa582880
7
+ data.tar.gz: 39a117062b19f734066f11c405730e499cc0325e6b2e3fd208aa68a930645e28f6b88f4f98e43133e8b70457d82ac3860f426b1385611b0d4b924003f79f0490
Binary file
data.tar.gz.sig CHANGED
@@ -1 +1,4 @@
1
- f�,z�$��^^S�-�4*Pk��kɵ/$�_���݄���Ӭ#�|O0G��-6��Mz����hd���4a�/�L�`� �SY?PLd���t%%�i׉/W���#��B$����o�=]M/��b/ɬe��aiX'��M��0���`Ƹ5��3c���ߦ�4��=�/-�L����uo+iR��މ �n8�a99=�A���Չ=f�9�J
1
+ `�1�O���ϓ��Go0�s9m_��v� TB�Ą���DZc�c�[P!�ۨ�t�����J�N(O���!y����"Ye(emg�`!��OV���V?i���ȟ�s��z��IV
2
+ M!=������e�(�iV�Tw���ƾ$U����Lu+l܃�5��ӗ�Yf�ޤ][�T��寲VI�CҞ�-�\�a�%�
3
+ 5W:bL��K���E8�J�� .!Hk�p�)�ׁ�+�p�-�7@�q����R��d��m�
4
+ R�\=���ݾ���ֳ��ھc
@@ -81,16 +81,6 @@ module Chamber
81
81
  instance.to_s(**args)
82
82
  end
83
83
 
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
84
  module_function :[],
95
85
  :configuration,
96
86
  :decrypt,
@@ -103,7 +93,6 @@ module Chamber
103
93
  :instance,
104
94
  :instance=,
105
95
  :load,
106
- :method_missing,
107
96
  :namespaces,
108
97
  :respond_to_missing?,
109
98
  :secure,
@@ -27,11 +27,11 @@ class Heroku
27
27
  request['Authorization'] = "Bearer #{api_token}"
28
28
  request['Accept'] = 'application/vnd.heroku+json; version=3'
29
29
  request['Content-Type'] = 'application/json'
30
- request.body = ::JSON.dump(Hash[name, value])
30
+ request.body = ::JSON.dump(::Hash[name, value])
31
31
 
32
32
  response = ::JSON.parse(response(request).body)
33
33
 
34
- fail NameError, response['message'] if response['message']
34
+ fail ::NameError, response['message'] if response['message']
35
35
 
36
36
  response
37
37
  end
@@ -44,7 +44,7 @@ class Heroku
44
44
 
45
45
  response = ::JSON.parse(response(request).body)
46
46
 
47
- fail NameError, response['message'] if response['message']
47
+ fail ::NameError, response['message'] if response['message']
48
48
 
49
49
  response
50
50
  end
@@ -1,16 +1,17 @@
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'
8
7
  require 'chamber/commands/cloud/compare'
8
+ require 'chamber/refinements/hash'
9
9
 
10
10
  module Chamber
11
11
  module Binary
12
- class CircleCi < Thor
13
- include Thor::Actions
12
+ class CircleCi < ::Thor
13
+ include ::Thor::Actions
14
+ using ::Chamber::Refinements::Hash
14
15
 
15
16
  class_option :api_token,
16
17
  type: :string,
@@ -49,7 +50,7 @@ class CircleCi < Thor
49
50
 
50
51
  def clear
51
52
  Commands::Cloud::Clear.call(**options
52
- .transform_keys(&:to_sym)
53
+ .deep_transform_keys(&:to_sym)
53
54
  .merge(shell: self, adapter: 'circle_ci'))
54
55
  end
55
56
 
@@ -81,7 +82,7 @@ class CircleCi < Thor
81
82
 
82
83
  def push
83
84
  Commands::Cloud::Push.call(**options
84
- .transform_keys(&:to_sym)
85
+ .deep_transform_keys(&:to_sym)
85
86
  .merge(shell: self, adapter: 'circle_ci'))
86
87
  end
87
88
 
@@ -96,7 +97,7 @@ class CircleCi < Thor
96
97
 
97
98
  def pull
98
99
  Commands::Cloud::Pull.call(**options
99
- .transform_keys(&:to_sym)
100
+ .deep_transform_keys(&:to_sym)
100
101
  .merge(shell: self, adapter: 'circle_ci'))
101
102
  end
102
103
 
@@ -114,7 +115,7 @@ class CircleCi < Thor
114
115
 
115
116
  def compare
116
117
  Commands::Cloud::Compare.call(**options
117
- .transform_keys(&:to_sym)
118
+ .deep_transform_keys(&:to_sym)
118
119
  .merge(shell: self, adapter: 'circle_ci'))
119
120
  end
120
121
  end
@@ -1,16 +1,17 @@
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'
8
7
  require 'chamber/commands/cloud/compare'
8
+ require 'chamber/refinements/hash'
9
9
 
10
10
  module Chamber
11
11
  module Binary
12
- class Heroku < Thor
13
- include Thor::Actions
12
+ class Heroku < ::Thor
13
+ include ::Thor::Actions
14
+ using ::Chamber::Refinements::Hash
14
15
 
15
16
  class_option :app,
16
17
  type: :string,
@@ -37,7 +38,7 @@ class Heroku < Thor
37
38
 
38
39
  def clear
39
40
  Commands::Cloud::Clear.call(**options
40
- .transform_keys(&:to_sym)
41
+ .deep_transform_keys(&:to_sym)
41
42
  .merge(shell: self, adapter: 'heroku'))
42
43
  end
43
44
 
@@ -69,7 +70,7 @@ class Heroku < Thor
69
70
 
70
71
  def push
71
72
  Commands::Cloud::Push.call(**options
72
- .transform_keys(&:to_sym)
73
+ .deep_transform_keys(&:to_sym)
73
74
  .merge(shell: self, adapter: 'heroku'))
74
75
  end
75
76
 
@@ -84,7 +85,7 @@ class Heroku < Thor
84
85
 
85
86
  def pull
86
87
  Commands::Cloud::Pull.call(**options
87
- .transform_keys(&:to_sym)
88
+ .deep_transform_keys(&:to_sym)
88
89
  .merge(shell: self, adapter: 'heroku'))
89
90
  end
90
91
 
@@ -102,7 +103,7 @@ class Heroku < Thor
102
103
 
103
104
  def compare
104
105
  Commands::Cloud::Compare.call(**options
105
- .transform_keys(&:to_sym)
106
+ .deep_transform_keys(&:to_sym)
106
107
  .merge(shell: self, adapter: 'heroku'))
107
108
  end
108
109
  end
@@ -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'
@@ -13,11 +12,13 @@ require 'chamber/commands/sign'
13
12
  require 'chamber/commands/verify'
14
13
  require 'chamber/commands/compare'
15
14
  require 'chamber/commands/initialize'
15
+ require 'chamber/refinements/hash'
16
16
 
17
17
  module Chamber
18
18
  module Binary
19
- class Runner < Thor
20
- include Thor::Actions
19
+ class Runner < ::Thor
20
+ include ::Thor::Actions
21
+ using ::Chamber::Refinements::Hash
21
22
 
22
23
  source_root ::File.expand_path('../../../templates', __dir__)
23
24
 
@@ -93,7 +94,7 @@ class Runner < Thor
93
94
  'Useful for debugging.'
94
95
 
95
96
  def show
96
- puts Commands::Show.call(**options.transform_keys(&:to_sym).merge(shell: self))
97
+ puts Commands::Show.call(**options.deep_transform_keys(&:to_sym).merge(shell: self))
97
98
  end
98
99
 
99
100
  ################################################################################
@@ -101,7 +102,7 @@ class Runner < Thor
101
102
  desc 'files', 'Lists the settings files which are parsed with the given options'
102
103
 
103
104
  def files
104
- puts Commands::Files.call(**options.transform_keys(&:to_sym).merge(shell: self))
105
+ puts Commands::Files.call(**options.deep_transform_keys(&:to_sym).merge(shell: self))
105
106
  end
106
107
 
107
108
  ################################################################################
@@ -131,7 +132,7 @@ class Runner < Thor
131
132
  'destination of the comparison'
132
133
 
133
134
  def compare
134
- Commands::Compare.call(**options.transform_keys(&:to_sym).merge(shell: self))
135
+ Commands::Compare.call(**options.deep_transform_keys(&:to_sym).merge(shell: self))
135
136
  end
136
137
 
137
138
  ################################################################################
@@ -151,7 +152,7 @@ class Runner < Thor
151
152
  'what values would be encrypted'
152
153
 
153
154
  def secure
154
- Commands::Secure.call(**options.transform_keys(&:to_sym).merge(shell: self))
155
+ Commands::Secure.call(**options.deep_transform_keys(&:to_sym).merge(shell: self))
155
156
  end
156
157
 
157
158
  ################################################################################
@@ -170,9 +171,9 @@ class Runner < Thor
170
171
 
171
172
  def sign
172
173
  if options[:verify]
173
- Commands::Verify.call(**options.transform_keys(&:to_sym).merge(shell: self))
174
+ Commands::Verify.call(**options.deep_transform_keys(&:to_sym).merge(shell: self))
174
175
  else
175
- Commands::Sign.call(**options.transform_keys(&:to_sym).merge(shell: self))
176
+ Commands::Sign.call(**options.deep_transform_keys(&:to_sym).merge(shell: self))
176
177
  end
177
178
  end
178
179
 
@@ -186,7 +187,7 @@ class Runner < Thor
186
187
  default: false
187
188
 
188
189
  def init
189
- Commands::Initialize.call(**options.transform_keys(&:to_sym).merge(shell: self))
190
+ Commands::Initialize.call(**options.deep_transform_keys(&:to_sym).merge(shell: self))
190
191
  end
191
192
  end
192
193
  end
@@ -1,12 +1,14 @@
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'
5
+ require 'chamber/refinements/hash'
6
6
 
7
7
  module Chamber
8
8
  module Binary
9
- class Travis < Thor
9
+ class Travis < ::Thor
10
+ using ::Chamber::Refinements::Hash
11
+
10
12
  desc 'secure',
11
13
  'Uses your Travis CI public key to encrypt the settings you have ' \
12
14
  'chosen not to commit to the repo'
@@ -26,7 +28,9 @@ class Travis < Thor
26
28
  'which are marked as "_secure"'
27
29
 
28
30
  def secure
29
- Commands::Travis::Secure.call(**options.transform_keys(&:to_sym).merge(shell: self))
31
+ Commands::Travis::Secure.call(**options
32
+ .deep_transform_keys(&:to_sym)
33
+ .merge(shell: self))
30
34
  end
31
35
  end
32
36
  end
@@ -2,15 +2,18 @@
2
2
 
3
3
  require 'shellwords'
4
4
  require 'chamber/instance'
5
+ require 'chamber/refinements/hash'
5
6
 
6
7
  module Chamber
7
8
  module Commands
8
9
  module Securable
10
+ using ::Chamber::Refinements::Hash
11
+
9
12
  def initialize(only_sensitive: nil, **args)
10
13
  super(**args)
11
14
 
12
15
  ignored_settings_options = args
13
- .merge(files: ignored_settings_filepaths)
16
+ .deep_merge(files: ignored_settings_filepaths)
14
17
  .reject { |k, _v| k == 'basepath' }
15
18
  self.ignored_settings_instance = Chamber::Instance.new(**ignored_settings_options)
16
19
  self.current_settings_instance = Chamber::Instance.new(**args)
@@ -41,7 +41,6 @@ class ContextResolver
41
41
  options[:basepath] + 'settings*.yml',
42
42
  options[:basepath] + 'settings',
43
43
  ]
44
-
45
44
  options[:signature_name] = options[:signature_name]
46
45
 
47
46
  options
@@ -4,6 +4,7 @@ require 'pathname'
4
4
  require 'yaml'
5
5
  require 'erb'
6
6
  require 'chamber/files/signature'
7
+ require 'chamber/refinements/hash'
7
8
 
8
9
  ###
9
10
  # Internal: Represents a single file containing settings information in a given
@@ -11,6 +12,8 @@ require 'chamber/files/signature'
11
12
  #
12
13
  module Chamber
13
14
  class File < Pathname
15
+ using ::Chamber::Refinements::Hash
16
+
14
17
  attr_accessor :namespaces,
15
18
  :decryption_keys,
16
19
  :encryption_keys,
@@ -143,7 +146,7 @@ class File < Pathname
143
146
  file_contents = read
144
147
  erb_result = ERB.new(file_contents).result
145
148
 
146
- YAML.load(erb_result) || {}
149
+ (YAML.load(erb_result) || {}).deep_transform_keys(&:to_s)
147
150
  rescue Errno::ENOENT
148
151
  {}
149
152
  end
@@ -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
@@ -35,7 +37,7 @@ class DecryptionFilter
35
37
 
36
38
  def initialize(data:, secure_key_prefix:, decryption_keys: {}, **_args)
37
39
  self.decryption_keys = decryption_keys || {}
38
- self.data = data.dup
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,7 +77,6 @@ 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
 
@@ -89,7 +90,6 @@ class DecryptionFilter
89
90
 
90
91
  value
91
92
  end
92
- # rubocop:enable Style/RedundantBegin
93
93
 
94
94
  def decryption_method(value)
95
95
  if value.respond_to?(:match)
@@ -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 = /
@@ -28,7 +30,7 @@ class EncryptionFilter
28
30
 
29
31
  def initialize(data:, secure_key_prefix:, encryption_keys: {}, **_args)
30
32
  self.encryption_keys = encryption_keys || {}
31
- self.data = data.dup
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)
@@ -67,7 +69,8 @@ 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
+ namespace_key = namespace ? namespace.to_sym : nil
73
+ encryption_key = encryption_keys[namespace_key] || encryption_keys[:__default]
71
74
 
72
75
  return value unless encryption_key
73
76
 
@@ -1,13 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yaml'
4
- require 'hashie/mash'
5
-
6
4
  require 'chamber/errors/environment_conversion'
5
+ require 'chamber/refinements/hash'
6
+ require 'chamber/refinements/deep_dup'
7
7
 
8
8
  module Chamber
9
9
  module Filters
10
10
  class EnvironmentFilter
11
+ using ::Chamber::Refinements::Hash
12
+ using ::Chamber::Refinements::DeepDup
13
+
11
14
  ###
12
15
  # Internal: Allows the existing environment to be injected into the passed in
13
16
  # hash. The hash that is passed in is *not* modified, instead a new hash is
@@ -120,18 +123,18 @@ class EnvironmentFilter
120
123
  private
121
124
 
122
125
  def with_environment(settings, parent_keys, hash_block, value_block)
123
- environment_hash = Hashie::Mash.new
126
+ environment_hash = {}
124
127
 
125
128
  settings.each_pair do |key, value|
126
129
  environment_key = key.to_s.gsub(secure_key_token, '')
127
- environment_keys = parent_keys.dup.push(environment_key)
130
+ environment_keys = parent_keys.deep_dup.push(environment_key)
128
131
 
129
132
  if value.respond_to? :each_pair
130
- environment_hash.merge!(hash_block.call(key, value, environment_keys))
133
+ environment_hash.deep_merge!(hash_block.call(key, value, environment_keys))
131
134
  else
132
135
  environment_key = environment_keys.join('_').upcase
133
136
 
134
- environment_hash.merge!(value_block.call(key, value, environment_key))
137
+ environment_hash.deep_merge!(value_block.call(key, value, environment_key))
135
138
  end
136
139
  end
137
140
 
@@ -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/hash'
4
+ require 'chamber/refinements/deep_dup'
4
5
 
5
6
  module Chamber
6
7
  module Filters
7
8
  class NamespaceFilter
9
+ using ::Chamber::Refinements::Hash
10
+ using ::Chamber::Refinements::DeepDup
11
+
8
12
  def self.execute(**args)
9
13
  new(**args).__send__(:execute)
10
14
  end
@@ -13,7 +17,7 @@ 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
 
@@ -21,11 +25,11 @@ class NamespaceFilter
21
25
 
22
26
  def execute
23
27
  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]
28
+ namespaces.each_with_object({}) do |namespace, filtered_data|
29
+ filtered_data.deep_merge!(data[namespace]) if data[namespace]
26
30
  end
27
31
  else
28
- Hashie::Mash.new(data)
32
+ data
29
33
  end
30
34
  end
31
35
 
@@ -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
@@ -3,9 +3,12 @@
3
3
  require 'chamber/configuration'
4
4
  require 'chamber/file_set'
5
5
  require 'chamber/settings'
6
+ require 'chamber/refinements/hash'
6
7
 
7
8
  module Chamber
8
9
  class Instance
10
+ using ::Chamber::Refinements::Hash
11
+
9
12
  attr_accessor :configuration,
10
13
  :files
11
14
 
@@ -63,11 +66,11 @@ class Instance
63
66
  end
64
67
 
65
68
  def encrypt(data, **args)
66
- config = configuration.to_hash.merge(**args)
69
+ config = configuration.to_hash.deep_merge(**args)
67
70
 
68
71
  Settings
69
72
  .new(
70
- **config.merge(
73
+ **config.deep_merge(
71
74
  settings: data,
72
75
  pre_filters: [Filters::EncryptionFilter],
73
76
  post_filters: [],
@@ -77,11 +80,11 @@ class Instance
77
80
  end
78
81
 
79
82
  def decrypt(data, **args)
80
- config = configuration.to_hash.merge(**args)
83
+ config = configuration.to_hash.deep_merge(**args)
81
84
 
82
85
  Settings
83
86
  .new(
84
- **config.merge(
87
+ **config.deep_merge(
85
88
  settings: data,
86
89
  pre_filters: [Filters::NamespaceFilter],
87
90
  post_filters: [
@@ -92,15 +95,5 @@ class Instance
92
95
  )
93
96
  .to_hash
94
97
  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
98
  end
106
99
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspectacular'
4
+ require 'chamber/refinements/enumerable'
5
+
6
+ module Chamber
7
+ module Refinements
8
+ module Array
9
+ refine ::Array do
10
+ def deep_transform_keys(&block)
11
+ Refinements::Enumerable.deep_transform_keys(self, &block)
12
+ end
13
+
14
+ def deep_transform_values(&block)
15
+ Refinements::Enumerable.deep_transform_values(nil, self, &block)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chamber
4
+ module Refinements
5
+ module DeepDup
6
+ refine ::Array do
7
+ unless method_defined?(:deep_dup)
8
+ def deep_dup
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
23
+ end
24
+ end
25
+
26
+ refine ::Object do
27
+ unless method_defined?(:deep_dup)
28
+ def deep_dup
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
37
+ end
38
+ end
39
+
40
+ refine ::Hash do
41
+ unless method_defined?(:deep_dup)
42
+ def deep_dup
43
+ dup.tap do |hash|
44
+ each_pair do |key, value|
45
+ if key.frozen? && key.is_a?(::String)
46
+ hash[key] = value.deep_dup
47
+ else
48
+ hash.delete(key)
49
+ hash[key.deep_dup] = value.deep_dup
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chamber
4
+ module Refinements
5
+ class Enumerable
6
+ def self.deep_transform_keys(object, &block)
7
+ case object
8
+ when ::Hash
9
+ object.each_with_object({}) do |(key, value), result|
10
+ result[yield(key)] = deep_transform_keys(value, &block)
11
+ end
12
+ when ::Array
13
+ object.map { |e| deep_transform_keys(e, &block) }
14
+ else
15
+ object
16
+ end
17
+ end
18
+
19
+ def self.deep_transform_values(key, value, &block)
20
+ case value
21
+ when ::Hash
22
+ value.each_with_object({}) do |(k, v), memo|
23
+ memo[k] = deep_transform_values(k, v, &block)
24
+ end
25
+ when ::Array
26
+ yield(
27
+ key,
28
+ value.map { |v| deep_transform_values(nil, v, &block) }
29
+ )
30
+ else
31
+ yield(key, value)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspectacular'
4
+ require 'chamber/refinements/hash'
5
+ require 'chamber/refinements/enumerable'
6
+
7
+ module Chamber
8
+ module Refinements
9
+ module Hash
10
+ refine ::Hash do
11
+ def deep_strip!
12
+ each do |key, value|
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
33
+ end
34
+
35
+ unless method_defined?(:deep_merge!)
36
+ def deep_merge!(other, &block)
37
+ merge!(other) do |key, value_1, value_2|
38
+ if value_1.is_a?(::Hash) && value_2.is_a?(::Hash)
39
+ value_1.deep_merge(value_2, &block)
40
+ elsif block
41
+ yield(key, value_1, value_2)
42
+ else
43
+ value_2
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ 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,18 +9,24 @@ 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
+ require 'chamber/refinements/hash'
13
14
 
14
15
  ###
15
16
  # Internal: Represents the base settings storage needed for Chamber.
16
17
  #
17
18
  module Chamber
18
19
  class Settings
20
+ using ::Chamber::Refinements::Hash
21
+ using ::Chamber::Refinements::DeepDup
22
+
19
23
  attr_accessor :decryption_keys,
20
24
  :encryption_keys,
21
25
  :post_filters,
22
26
  :pre_filters,
23
27
  :secure_key_prefix
24
28
  attr_reader :namespaces
29
+ attr_writer :raw_data
25
30
 
26
31
  # rubocop:disable Metrics/ParameterLists
27
32
  def initialize(
@@ -46,7 +51,7 @@ class Settings
46
51
  self.namespaces = namespaces
47
52
  self.post_filters = post_filters
48
53
  self.pre_filters = pre_filters
49
- self.raw_data = settings
54
+ self.raw_data = settings.deep_dup
50
55
  self.secure_key_prefix = secure_key_prefix
51
56
  end
52
57
  # rubocop:enable Metrics/ParameterLists
@@ -109,7 +114,7 @@ class Settings
109
114
  # Returns a Hash
110
115
  #
111
116
  def to_hash
112
- data.to_hash
117
+ data.dup
113
118
  end
114
119
 
115
120
  ###
@@ -142,11 +147,11 @@ class Settings
142
147
  flattened_name_hash = {}
143
148
 
144
149
  hash.each_pair do |key, value|
145
- flattened_name_components = parent_keys.dup.push(key)
150
+ flattened_name_components = parent_keys.deep_dup.push(key)
146
151
 
147
152
  if value.respond_to?(:each_pair)
148
- flattened_name_hash.merge! to_flattened_name_hash(value,
149
- flattened_name_components)
153
+ flattened_name_hash
154
+ .deep_merge!(to_flattened_name_hash(value, flattened_name_components))
150
155
  else
151
156
  flattened_name_hash[flattened_name_components] = value
152
157
  end
@@ -192,7 +197,7 @@ class Settings
192
197
  other_settings = case other
193
198
  when Settings
194
199
  other
195
- when Hash
200
+ when ::Hash
196
201
  Settings.new(settings: other)
197
202
  end
198
203
 
@@ -201,7 +206,7 @@ class Settings
201
206
  encryption_keys: encryption_keys.any? ? encryption_keys : other_settings.encryption_keys,
202
207
  decryption_keys: decryption_keys.any? ? decryption_keys : other_settings.decryption_keys,
203
208
  namespaces: (namespaces + other_settings.namespaces),
204
- settings: raw_data.merge(other_settings.raw_data),
209
+ settings: raw_data.deep_merge(other_settings.raw_data),
205
210
  )
206
211
  # rubocop:enable Layout/LineLength
207
212
  end
@@ -231,7 +236,7 @@ class Settings
231
236
  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." if key.is_a?(::Symbol) # rubocop:disable Layout/LineLength
232
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
233
238
 
234
- data.[](key)
239
+ data.fetch(key)
235
240
  end
236
241
 
237
242
  def dig!(*args)
@@ -249,14 +254,14 @@ class Settings
249
254
  end
250
255
 
251
256
  def securable
252
- Settings.new(**metadata.merge(
257
+ Settings.new(**metadata.deep_merge(
253
258
  settings: raw_data,
254
259
  pre_filters: [Filters::SecureFilter],
255
260
  ))
256
261
  end
257
262
 
258
263
  def secure
259
- Settings.new(**metadata.merge(
264
+ Settings.new(**metadata.deep_merge(
260
265
  settings: raw_data,
261
266
  pre_filters: [Filters::EncryptionFilter],
262
267
  post_filters: [Filters::TranslateSecureKeysFilter],
@@ -264,34 +269,15 @@ class Settings
264
269
  end
265
270
 
266
271
  def insecure
267
- Settings.new(**metadata.merge(
272
+ Settings.new(**metadata.deep_merge(
268
273
  settings: raw_data,
269
274
  pre_filters: [Filters::InsecureFilter],
270
275
  post_filters: [Filters::TranslateSecureKeysFilter],
271
276
  ))
272
277
  end
273
278
 
274
- def method_missing(name, *args)
275
- if data.respond_to?(name)
276
- 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." # rubocop:disable Layout/LineLength
277
- 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." if name.to_s.end_with?('?') # rubocop:disable Layout/LineLength
278
-
279
- data.public_send(name, *args)
280
- else
281
- super
282
- end
283
- end
284
-
285
- def respond_to_missing?(name, include_private = false)
286
- data.respond_to?(name, include_private)
287
- end
288
-
289
279
  protected
290
280
 
291
- def raw_data=(new_raw_data)
292
- @raw_data = Hashie::Mash.new(new_raw_data)
293
- end
294
-
295
281
  def namespaces=(raw_namespaces)
296
282
  @namespaces = NamespaceSet.new(raw_namespaces)
297
283
  end
@@ -299,15 +285,16 @@ class Settings
299
285
  # rubocop:disable Naming/MemoizedInstanceVariableName
300
286
  def raw_data
301
287
  @filtered_raw_data ||= pre_filters.inject(@raw_data) do |filtered_data, filter|
302
- filter.execute(**{ data: filtered_data }.merge(metadata))
288
+ filter.execute(**{ data: filtered_data }.deep_merge(metadata))
303
289
  end
304
290
  end
305
291
  # rubocop:enable Naming/MemoizedInstanceVariableName
306
292
 
307
293
  def data
308
- @data ||= post_filters.inject(raw_data) do |filtered_data, filter|
309
- filter.execute(**{ data: filtered_data }.merge(metadata))
310
- end
294
+ @data ||= post_filters
295
+ .inject(raw_data) do |filtered_data, filter|
296
+ filter.execute(**{ data: filtered_data }.deep_merge(metadata))
297
+ end
311
298
  end
312
299
 
313
300
  def metadata
@@ -37,14 +37,14 @@ class Secured < CHAMBER_TYPE_VALUE_SUPERCLASS
37
37
 
38
38
  def cast(value)
39
39
  case value
40
- when Hash
40
+ when ::Hash
41
41
  value
42
- when String
43
- ::ActiveSupport::JSON.decode(value)
44
- when NilClass
42
+ when ::String
43
+ ::JSON.parse(value)
44
+ when ::NilClass
45
45
  nil
46
46
  else
47
- fail ArgumentError, 'Any attributes encrypted with Chamber must be either a Hash or a valid JSON string'
47
+ fail ::ArgumentError, 'Any attributes encrypted with Chamber must be either a Hash or a valid JSON string'
48
48
  end
49
49
  end
50
50
  alias type_cast_from_user cast
@@ -54,19 +54,19 @@ class Secured < CHAMBER_TYPE_VALUE_SUPERCLASS
54
54
 
55
55
  return if value.nil?
56
56
 
57
- Chamber.decrypt(value,
58
- decryption_keys: decryption_keys,
59
- encryption_keys: encryption_keys)
57
+ ::Chamber.decrypt(value,
58
+ decryption_keys: decryption_keys,
59
+ encryption_keys: encryption_keys)
60
60
  end
61
61
  alias type_cast_from_database deserialize
62
62
 
63
63
  def serialize(value)
64
- fail ArgumentError, 'Any attributes encrypted with Chamber must be a Hash' unless value.is_a?(Hash)
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.2'
4
+ VERSION = '3.0.0rc1'
5
5
  end
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.2
4
+ version: 3.0.0rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - thekompanee
@@ -58,20 +58,6 @@ dependencies:
58
58
  - - "<"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '2.0'
61
- - !ruby/object:Gem::Dependency
62
- name: hashie
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '3.3'
68
- type: :runtime
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '3.3'
75
61
  - !ruby/object:Gem::Dependency
76
62
  name: rspec
77
63
  requirement: !ruby/object:Gem::Requirement
@@ -181,7 +167,6 @@ files:
181
167
  - lib/chamber/commands/verify.rb
182
168
  - lib/chamber/configuration.rb
183
169
  - lib/chamber/context_resolver.rb
184
- - lib/chamber/core_ext/hash.rb
185
170
  - lib/chamber/encryption_methods/none.rb
186
171
  - lib/chamber/encryption_methods/public_key.rb
187
172
  - lib/chamber/encryption_methods/ssl.rb
@@ -207,6 +192,10 @@ files:
207
192
  - lib/chamber/keys/encryption.rb
208
193
  - lib/chamber/namespace_set.rb
209
194
  - lib/chamber/rails.rb
195
+ - lib/chamber/refinements/array.rb
196
+ - lib/chamber/refinements/deep_dup.rb
197
+ - lib/chamber/refinements/enumerable.rb
198
+ - lib/chamber/refinements/hash.rb
210
199
  - lib/chamber/rubinius_fix.rb
211
200
  - lib/chamber/settings.rb
212
201
  - lib/chamber/types/secured.rb
@@ -234,9 +223,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
234
223
  version: 2.1.0
235
224
  required_rubygems_version: !ruby/object:Gem::Requirement
236
225
  requirements:
237
- - - ">="
226
+ - - ">"
238
227
  - !ruby/object:Gem::Version
239
- version: '0'
228
+ version: 1.3.1
240
229
  requirements: []
241
230
  rubygems_version: 3.2.3
242
231
  signing_key:
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