chamber 2.14.2 → 3.0.0rc1

Sign up to get free protection for your applications and to get access to all the features.
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