chamber 2.12.3 → 2.14.1

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.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +101 -26
  5. data/lib/chamber.rb +82 -10
  6. data/lib/chamber/adapters/cloud/circle_ci.rb +85 -0
  7. data/lib/chamber/adapters/cloud/heroku.rb +74 -0
  8. data/lib/chamber/binary/circle_ci.rb +122 -0
  9. data/lib/chamber/binary/heroku.rb +45 -16
  10. data/lib/chamber/binary/runner.rb +42 -26
  11. data/lib/chamber/binary/travis.rb +5 -3
  12. data/lib/chamber/commands/base.rb +10 -16
  13. data/lib/chamber/commands/cloud/base.rb +35 -0
  14. data/lib/chamber/commands/{heroku → cloud}/clear.rb +6 -8
  15. data/lib/chamber/commands/cloud/compare.rb +26 -0
  16. data/lib/chamber/commands/cloud/pull.rb +29 -0
  17. data/lib/chamber/commands/cloud/push.rb +44 -0
  18. data/lib/chamber/commands/comparable.rb +2 -2
  19. data/lib/chamber/commands/compare.rb +6 -9
  20. data/lib/chamber/commands/initialize.rb +26 -22
  21. data/lib/chamber/commands/securable.rb +10 -10
  22. data/lib/chamber/commands/secure.rb +2 -2
  23. data/lib/chamber/commands/show.rb +8 -8
  24. data/lib/chamber/commands/sign.rb +2 -2
  25. data/lib/chamber/commands/verify.rb +2 -2
  26. data/lib/chamber/configuration.rb +8 -3
  27. data/lib/chamber/context_resolver.rb +16 -7
  28. data/lib/chamber/encryption_methods/ssl.rb +21 -12
  29. data/lib/chamber/file.rb +22 -20
  30. data/lib/chamber/file_set.rb +21 -11
  31. data/lib/chamber/files/signature.rb +31 -23
  32. data/lib/chamber/filters/decryption_filter.rb +13 -11
  33. data/lib/chamber/filters/encryption_filter.rb +17 -8
  34. data/lib/chamber/filters/environment_filter.rb +12 -14
  35. data/lib/chamber/filters/failed_decryption_filter.rb +6 -6
  36. data/lib/chamber/filters/insecure_filter.rb +12 -3
  37. data/lib/chamber/filters/namespace_filter.rb +5 -5
  38. data/lib/chamber/filters/secure_filter.rb +5 -5
  39. data/lib/chamber/filters/translate_secure_keys_filter.rb +5 -5
  40. data/lib/chamber/instance.rb +54 -30
  41. data/lib/chamber/integrations/rails.rb +1 -1
  42. data/lib/chamber/integrations/sinatra.rb +6 -6
  43. data/lib/chamber/key_pair.rb +8 -8
  44. data/lib/chamber/keys/base.rb +35 -41
  45. data/lib/chamber/keys/decryption.rb +8 -14
  46. data/lib/chamber/keys/encryption.rb +8 -14
  47. data/lib/chamber/namespace_set.rb +2 -4
  48. data/lib/chamber/settings.rb +86 -56
  49. data/lib/chamber/types/secured.rb +8 -10
  50. data/lib/chamber/version.rb +1 -1
  51. data/templates/settings.yml +2 -0
  52. metadata +51 -41
  53. metadata.gz.sig +0 -0
  54. data/lib/chamber/commands/heroku.rb +0 -31
  55. data/lib/chamber/commands/heroku/compare.rb +0 -33
  56. data/lib/chamber/commands/heroku/pull.rb +0 -30
  57. data/lib/chamber/commands/heroku/push.rb +0 -27
@@ -112,19 +112,28 @@ require 'chamber/settings'
112
112
  #
113
113
  module Chamber
114
114
  class FileSet
115
- attr_reader :namespaces,
116
- :paths
117
115
  attr_accessor :decryption_keys,
118
116
  :encryption_keys,
119
- :basepath
117
+ :basepath,
118
+ :signature_name
119
+ attr_reader :namespaces,
120
+ :paths
120
121
 
121
- def initialize(options = {})
122
- self.namespaces = options[:namespaces] || {}
123
- self.decryption_keys = options[:decryption_keys]
124
- self.encryption_keys = options[:encryption_keys]
125
- self.paths = options.fetch(:files)
126
- self.basepath = options[:basepath]
122
+ # rubocop:disable Metrics/ParameterLists
123
+ def initialize(files:,
124
+ basepath: nil,
125
+ decryption_keys: nil,
126
+ encryption_keys: nil,
127
+ namespaces: {},
128
+ signature_name: nil)
129
+ self.basepath = basepath
130
+ self.decryption_keys = decryption_keys
131
+ self.encryption_keys = encryption_keys
132
+ self.namespaces = namespaces
133
+ self.paths = files
134
+ self.signature_name = signature_name
127
135
  end
136
+ # rubocop:enable Metrics/ParameterLists
128
137
 
129
138
  ###
130
139
  # Internal: Returns an Array of the ordered list of files that was processed
@@ -234,7 +243,8 @@ class FileSet
234
243
  File.new(path: file,
235
244
  namespaces: namespaces,
236
245
  decryption_keys: decryption_keys,
237
- encryption_keys: encryption_keys)
246
+ encryption_keys: encryption_keys,
247
+ signature_name: signature_name)
238
248
  end
239
249
 
240
250
  sorted_relevant_files += relevant_glob_files
@@ -247,7 +257,7 @@ class FileSet
247
257
  private
248
258
 
249
259
  def all_files
250
- @all_files ||= file_globs.map { |fg| Pathname.glob(fg) }.flatten.uniq.sort
260
+ @all_files ||= file_globs.map { |fg| Pathname.glob(fg) }.flatten.uniq.sort # rubocop:disable Performance/ChainArrayAllocation
251
261
  end
252
262
 
253
263
  def non_namespaced_files
@@ -7,35 +7,43 @@ require 'time'
7
7
  module Chamber
8
8
  module Files
9
9
  class Signature
10
- SIGNATURE_HEADER = '-----BEGIN CHAMBER SIGNATURE-----'
11
- SIGNATURE_FOOTER = '-----END CHAMBER SIGNATURE-----'
12
- SIGNATURE_IN_SIGNATURE_FILE_PATTERN = /#{SIGNATURE_HEADER}\n(.*)\n#{SIGNATURE_FOOTER}/
10
+ SIGNATURE_HEADER = '-----BEGIN CHAMBER SIGNATURE-----'
11
+ SIGNATURE_HEADER_PATTERN = /-----BEGIN\sCHAMBER\sSIGNATURE-----/.freeze
12
+ SIGNATURE_FOOTER = '-----END CHAMBER SIGNATURE-----'
13
+ SIGNATURE_FOOTER_PATTERN = /-----END\sCHAMBER\sSIGNATURE-----/.freeze
14
+ SIGNATURE_IN_FILE_PATTERN = /
15
+ #{SIGNATURE_HEADER_PATTERN}\n # Header
16
+ (.*)\n # Signature Body
17
+ #{SIGNATURE_FOOTER_PATTERN} # Footer
18
+ /x.freeze
13
19
 
14
20
  attr_accessor :settings_content,
15
- :settings_filename
21
+ :settings_filename,
22
+ :signature_name
16
23
 
17
24
  attr_reader :signature_key
18
25
 
19
- def initialize(settings_filename, settings_content, signature_key)
26
+ def initialize(settings_filename, settings_content, signature_key, signature_name)
20
27
  self.signature_key = signature_key
21
28
  self.settings_content = settings_content
22
29
  self.settings_filename = Pathname.new(settings_filename)
30
+ self.signature_name = signature_name
23
31
  end
24
32
 
25
33
  def signature_key=(keyish)
26
- @signature_key ||= if keyish.is_a?(OpenSSL::PKey::RSA)
27
- keyish
28
- elsif ::File.readable?(::File.expand_path(keyish))
29
- file_contents = ::File.read(::File.expand_path(keyish))
30
- OpenSSL::PKey::RSA.new(file_contents)
31
- else
32
- OpenSSL::PKey::RSA.new(keyish)
33
- end
34
+ @signature_key = if keyish.is_a?(OpenSSL::PKey::RSA)
35
+ keyish
36
+ elsif ::File.readable?(::File.expand_path(keyish))
37
+ file_contents = ::File.read(::File.expand_path(keyish))
38
+ OpenSSL::PKey::RSA.new(file_contents)
39
+ else
40
+ OpenSSL::PKey::RSA.new(keyish)
41
+ end
34
42
  end
35
43
 
36
44
  def write
37
45
  signature_filename.write(<<-HEREDOC, 0, mode: 'w+')
38
- Signed By: #{`git config --get 'user.name'`.chomp}
46
+ Signed By: #{signature_name}
39
47
  Signed At: #{Time.now.utc.iso8601}
40
48
 
41
49
  #{SIGNATURE_HEADER}
@@ -55,20 +63,20 @@ Signed At: #{Time.now.utc.iso8601}
55
63
  end
56
64
 
57
65
  def raw_signature
58
- @raw_signature ||= signature_key.
59
- sign(digest, settings_content)
66
+ @raw_signature ||= signature_key
67
+ .sign(digest, settings_content)
60
68
  end
61
69
 
62
70
  def signature_filename
63
- @signature_filename ||= settings_filename.
64
- sub('.yml', '.sig').
65
- sub('.erb', '')
71
+ @signature_filename ||= settings_filename
72
+ .sub('.yml', '.sig')
73
+ .sub('.erb', '')
66
74
  end
67
75
 
68
76
  def encoded_signature_content
69
- @encoded_signature_content ||= signature_filename.
70
- read.
71
- match(SIGNATURE_IN_SIGNATURE_FILE_PATTERN) do |match|
77
+ @encoded_signature_content ||= signature_filename
78
+ .read
79
+ .match(SIGNATURE_IN_FILE_PATTERN) do |match|
72
80
  match[1]
73
81
  end
74
82
  end
@@ -78,7 +86,7 @@ Signed At: #{Time.now.utc.iso8601}
78
86
  end
79
87
 
80
88
  def digest
81
- @digest ||= OpenSSL::Digest::SHA512.new
89
+ @digest ||= OpenSSL::Digest.new('SHA512')
82
90
  end
83
91
  end
84
92
  end
@@ -12,35 +12,35 @@ require 'chamber/errors/decryption_failure'
12
12
  module Chamber
13
13
  module Filters
14
14
  class DecryptionFilter
15
- BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9\+/]{342}==\z}
15
+ BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}.freeze
16
16
  LARGE_DATA_STRING_PATTERN = %r{
17
17
  \A # Beginning of String
18
18
  (
19
- [A-Za-z0-9\+\/#]*\={0,2} # Base64 Encoded Key
19
+ [A-Za-z0-9+/#]*={0,2} # Base64 Encoded Key
20
20
  )
21
21
  \# # Separator
22
22
  (
23
- [A-Za-z0-9\+\/#]*\={0,2} # Base64 Encoded IV
23
+ [A-Za-z0-9+/#]*={0,2} # Base64 Encoded IV
24
24
  )
25
25
  \# # Separator
26
26
  (
27
- [A-Za-z0-9\+\/#]*\={0,2} # Base64 Encoded Data
27
+ [A-Za-z0-9+/#]*={0,2} # Base64 Encoded Data
28
28
  )
29
29
  \z # End of String
30
- }x
30
+ }x.freeze
31
31
 
32
32
  attr_accessor :data,
33
33
  :secure_key_token
34
34
  attr_reader :decryption_keys
35
35
 
36
- def initialize(options = {})
37
- self.decryption_keys = options.fetch(:decryption_keys, {}) || {}
38
- self.data = options.fetch(:data).dup
39
- self.secure_key_token = /\A#{Regexp.escape(options.fetch(:secure_key_prefix))}/
36
+ def initialize(data:, secure_key_prefix:, decryption_keys: {}, **_args)
37
+ self.decryption_keys = decryption_keys || {}
38
+ self.data = data.dup
39
+ self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
40
40
  end
41
41
 
42
- def self.execute(options = {})
43
- new(options).__send__(:execute)
42
+ def self.execute(**args)
43
+ new(**args).__send__(:execute)
44
44
  end
45
45
 
46
46
  protected
@@ -75,6 +75,7 @@ class DecryptionFilter
75
75
 
76
76
  private
77
77
 
78
+ # rubocop:disable Style/RedundantBegin
78
79
  def decrypt(key, value)
79
80
  method = decryption_method(value)
80
81
 
@@ -88,6 +89,7 @@ class DecryptionFilter
88
89
 
89
90
  value
90
91
  end
92
+ # rubocop:enable Style/RedundantBegin
91
93
 
92
94
  def decryption_method(value)
93
95
  if value.respond_to?(:match)
@@ -10,21 +10,30 @@ require 'chamber/encryption_methods/none'
10
10
  module Chamber
11
11
  module Filters
12
12
  class EncryptionFilter
13
- BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9\+\/]{342}==\z}
14
- LARGE_DATA_STRING_PATTERN = %r{\A([A-Za-z0-9\+\/#]*\={0,2})#([A-Za-z0-9\+\/#]*\={0,2})#([A-Za-z0-9\+\/#]*\={0,2})\z} # rubocop:disable Metrics/LineLength
13
+ BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}.freeze
14
+ BASE64_SUBSTRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}.freeze
15
+ LARGE_DATA_STRING_PATTERN = /
16
+ \A
17
+ (#{BASE64_SUBSTRING_PATTERN})
18
+ \#
19
+ (#{BASE64_SUBSTRING_PATTERN})
20
+ \#
21
+ (#{BASE64_SUBSTRING_PATTERN})
22
+ \z
23
+ /x.freeze
15
24
 
16
25
  attr_accessor :data,
17
26
  :secure_key_token
18
27
  attr_reader :encryption_keys
19
28
 
20
- def initialize(options = {})
21
- self.encryption_keys = options.fetch(:encryption_keys, {}) || {}
22
- self.data = options.fetch(:data).dup
23
- self.secure_key_token = /\A#{Regexp.escape(options.fetch(:secure_key_prefix))}/
29
+ def initialize(data:, secure_key_prefix:, encryption_keys: {}, **_args)
30
+ self.encryption_keys = encryption_keys || {}
31
+ self.data = data.dup
32
+ self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
24
33
  end
25
34
 
26
- def self.execute(options = {})
27
- new(options).__send__(:execute)
35
+ def self.execute(**args)
36
+ new(**args).__send__(:execute)
28
37
  end
29
38
 
30
39
  protected
@@ -88,16 +88,16 @@ class EnvironmentFilter
88
88
  # }
89
89
  #
90
90
  #
91
- def self.execute(options = {})
92
- new(options).__send__(:execute)
91
+ def self.execute(**args)
92
+ new(**args).__send__(:execute)
93
93
  end
94
94
 
95
95
  attr_accessor :data,
96
96
  :secure_key_token
97
97
 
98
- def initialize(options = {})
99
- self.data = options.fetch(:data)
100
- self.secure_key_token = /\A#{Regexp.escape(options.fetch(:secure_key_prefix))}/
98
+ def initialize(data:, secure_key_prefix:, **_args)
99
+ self.data = data
100
+ self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
101
101
  end
102
102
 
103
103
  protected
@@ -138,8 +138,7 @@ class EnvironmentFilter
138
138
  environment_hash
139
139
  end
140
140
 
141
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
142
- def convert_environment_value(environment_key, environment_value, settings_value)
141
+ def convert_environment_value(environment_key, environment_value, settings_value) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
143
142
  return settings_value unless environment_value
144
143
  return if %w{___nil___ ___null___}.include?(environment_value)
145
144
 
@@ -163,22 +162,21 @@ class EnvironmentFilter
163
162
  fail ArgumentError, "Invalid value for Array: #{environment_value}"
164
163
  end
165
164
  end
166
- when 'Integer'
165
+ when 'Fixnum', 'Integer'
167
166
  Integer(environment_value)
168
167
  else
169
168
  environment_value
170
169
  end
171
170
  rescue ArgumentError
172
- raise Chamber::Errors::EnvironmentConversion, <<~HEREDOC
173
- We attempted to convert '#{environment_key}' from '#{environment_value}' to a '#{settings_value.class.name}'.
171
+ raise Chamber::Errors::EnvironmentConversion, <<-HEREDOC
172
+ We attempted to convert '#{environment_key}' from '#{environment_value}' to a '#{settings_value.class.name}'.
174
173
 
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).
174
+ Unfortunately, this did not go as planned. Please either verify that your value is convertable
175
+ or change the original YAML value to be something more generic (like a String).
177
176
 
178
- For more information, see https://github.com/thekompanee/chamber/wiki/Environment-Variable-Coercions
177
+ For more information, see https://github.com/thekompanee/chamber/wiki/Environment-Variable-Coercions
179
178
  HEREDOC
180
179
  end
181
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
182
180
  end
183
181
  end
184
182
  end
@@ -5,18 +5,18 @@ require 'chamber/errors/decryption_failure'
5
5
  module Chamber
6
6
  module Filters
7
7
  class FailedDecryptionFilter
8
- BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9\+/]{342}==\z}
8
+ BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}.freeze
9
9
 
10
- def self.execute(options = {})
11
- new(options).__send__(:execute)
10
+ def self.execute(**args)
11
+ new(**args).__send__(:execute)
12
12
  end
13
13
 
14
14
  attr_accessor :data,
15
15
  :secure_key_token
16
16
 
17
- def initialize(options = {})
18
- self.data = options.fetch(:data).dup
19
- self.secure_key_token = /\A#{Regexp.escape(options.fetch(:secure_key_prefix))}/
17
+ def initialize(data:, secure_key_prefix:, **_args)
18
+ self.data = data.dup
19
+ self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
20
20
  end
21
21
 
22
22
  protected
@@ -6,12 +6,21 @@ require 'chamber/filters/secure_filter'
6
6
  module Chamber
7
7
  module Filters
8
8
  class InsecureFilter < SecureFilter
9
- BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9\+\/]{342}==\z}
10
- LARGE_DATA_STRING_PATTERN = %r{\A([A-Za-z0-9\+\/#]*\={0,2})#([A-Za-z0-9\+\/#]*\={0,2})#([A-Za-z0-9\+\/#]*\={0,2})\z} # rubocop:disable Metrics/LineLength
9
+ BASE64_STRING_PATTERN = %r{\A[A-Za-z0-9+/]{342}==\z}.freeze
10
+ BASE64_SUBSTRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}.freeze
11
+ LARGE_DATA_STRING_PATTERN = /
12
+ \A
13
+ (#{BASE64_SUBSTRING_PATTERN})
14
+ \#
15
+ (#{BASE64_SUBSTRING_PATTERN})
16
+ \#
17
+ (#{BASE64_SUBSTRING_PATTERN})
18
+ \z
19
+ /x.freeze
11
20
 
12
21
  protected
13
22
 
14
- def execute(raw_data = data)
23
+ def execute(raw_data = data) # rubocop:disable Metrics/CyclomaticComplexity
15
24
  securable_settings = super
16
25
  settings = Hashie::Mash.new
17
26
 
@@ -5,16 +5,16 @@ require 'hashie/mash'
5
5
  module Chamber
6
6
  module Filters
7
7
  class NamespaceFilter
8
- def self.execute(options = {})
9
- new(options).__send__(:execute)
8
+ def self.execute(**args)
9
+ new(**args).__send__(:execute)
10
10
  end
11
11
 
12
12
  attr_accessor :data,
13
13
  :namespaces
14
14
 
15
- def initialize(options = {})
16
- self.data = Hashie::Mash.new(options.fetch(:data))
17
- self.namespaces = options.fetch(:namespaces)
15
+ def initialize(data:, namespaces:, **_args)
16
+ self.data = Hashie::Mash.new(data)
17
+ self.namespaces = namespaces
18
18
  end
19
19
 
20
20
  protected
@@ -5,16 +5,16 @@ require 'hashie/mash'
5
5
  module Chamber
6
6
  module Filters
7
7
  class SecureFilter
8
- def self.execute(options = {})
9
- new(options).__send__(:execute)
8
+ def self.execute(**args)
9
+ new(**args).__send__(:execute)
10
10
  end
11
11
 
12
12
  attr_accessor :data,
13
13
  :secure_key_token
14
14
 
15
- def initialize(options = {})
16
- self.data = Hashie::Mash.new(options.fetch(:data))
17
- self.secure_key_token = /\A#{Regexp.escape(options.fetch(:secure_key_prefix))}/
15
+ def initialize(data:, secure_key_prefix:, **_args)
16
+ self.data = Hashie::Mash.new(data)
17
+ self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
18
18
  end
19
19
 
20
20
  protected
@@ -5,16 +5,16 @@ require 'hashie/mash'
5
5
  module Chamber
6
6
  module Filters
7
7
  class TranslateSecureKeysFilter
8
- def self.execute(options = {})
9
- new(options).__send__(:execute)
8
+ def self.execute(**args)
9
+ new(**args).__send__(:execute)
10
10
  end
11
11
 
12
12
  attr_accessor :data,
13
13
  :secure_key_token
14
14
 
15
- def initialize(options = {})
16
- self.data = options.fetch(:data).dup
17
- self.secure_key_token = /\A#{Regexp.escape(options.fetch(:secure_key_prefix))}/
15
+ def initialize(data:, secure_key_prefix:, **_args)
16
+ self.data = data.dup
17
+ self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
18
18
  end
19
19
 
20
20
  protected
@@ -9,15 +9,27 @@ class Instance
9
9
  attr_accessor :configuration,
10
10
  :files
11
11
 
12
- def initialize(options = {})
13
- self.configuration = Configuration.new options
14
- self.files = FileSet.new configuration.to_hash
12
+ def initialize(**args)
13
+ self.configuration = Configuration.new(**args)
14
+ self.files = FileSet.new(**configuration.to_hash)
15
15
  end
16
16
 
17
17
  def settings
18
18
  @settings ||= files.to_settings { |settings| @settings = settings }
19
19
  end
20
20
 
21
+ def [](key)
22
+ settings.[](key)
23
+ end
24
+
25
+ def dig!(*args)
26
+ settings.dig!(*args)
27
+ end
28
+
29
+ def dig(*args)
30
+ settings.dig(*args)
31
+ end
32
+
21
33
  def filenames
22
34
  files.filenames
23
35
  end
@@ -34,39 +46,51 @@ class Instance
34
46
  files.verify
35
47
  end
36
48
 
37
- def encrypt(data, options = {})
38
- config = configuration.to_hash.merge(options)
49
+ def to_environment
50
+ settings.to_environment
51
+ end
39
52
 
40
- Settings.
41
- new(
42
- config.merge(
43
- settings: data,
44
- pre_filters: [Filters::EncryptionFilter],
45
- post_filters: [],
46
- ),
47
- ).
48
- to_hash
53
+ def to_s(**args)
54
+ settings.to_s(**args)
49
55
  end
50
56
 
51
- def decrypt(data, options = {})
52
- config = configuration.to_hash.merge(options)
57
+ def to_hash
58
+ settings.to_hash
59
+ end
60
+
61
+ def namespaces
62
+ settings.namespaces
63
+ end
53
64
 
54
- Settings.
55
- new(
56
- config.merge(
57
- settings: data,
58
- pre_filters: [Filters::NamespaceFilter],
59
- post_filters: [
60
- Filters::DecryptionFilter,
61
- Filters::FailedDecryptionFilter,
62
- ],
63
- ),
64
- ).
65
- to_hash
65
+ def encrypt(data, **args)
66
+ config = configuration.to_hash.merge(**args)
67
+
68
+ Settings
69
+ .new(
70
+ **config.merge(
71
+ settings: data,
72
+ pre_filters: [Filters::EncryptionFilter],
73
+ post_filters: [],
74
+ ),
75
+ )
76
+ .to_hash
66
77
  end
67
78
 
68
- def to_s(options = {})
69
- settings.to_s(options)
79
+ def decrypt(data, **args)
80
+ config = configuration.to_hash.merge(**args)
81
+
82
+ Settings
83
+ .new(
84
+ **config.merge(
85
+ settings: data,
86
+ pre_filters: [Filters::NamespaceFilter],
87
+ post_filters: [
88
+ Filters::DecryptionFilter,
89
+ Filters::FailedDecryptionFilter,
90
+ ],
91
+ ),
92
+ )
93
+ .to_hash
70
94
  end
71
95
 
72
96
  def method_missing(name, *args)