chamber 2.13.1 → 2.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +101 -26
- data/lib/chamber.rb +72 -10
- data/lib/chamber/adapters/cloud/circle_ci.rb +16 -13
- data/lib/chamber/adapters/cloud/heroku.rb +40 -13
- data/lib/chamber/binary/circle_ci.rb +25 -12
- data/lib/chamber/binary/heroku.rb +31 -12
- data/lib/chamber/binary/runner.rb +37 -27
- data/lib/chamber/binary/travis.rb +5 -3
- data/lib/chamber/commands/base.rb +10 -16
- data/lib/chamber/commands/cloud/base.rb +3 -3
- data/lib/chamber/commands/cloud/pull.rb +2 -2
- data/lib/chamber/commands/cloud/push.rb +7 -7
- data/lib/chamber/commands/comparable.rb +2 -2
- data/lib/chamber/commands/compare.rb +6 -9
- data/lib/chamber/commands/initialize.rb +26 -22
- data/lib/chamber/commands/securable.rb +9 -9
- data/lib/chamber/commands/secure.rb +2 -2
- data/lib/chamber/commands/show.rb +8 -8
- data/lib/chamber/commands/sign.rb +2 -2
- data/lib/chamber/commands/verify.rb +2 -2
- data/lib/chamber/configuration.rb +6 -3
- data/lib/chamber/context_resolver.rb +8 -7
- data/lib/chamber/encryption_methods/ssl.rb +12 -12
- data/lib/chamber/file.rb +16 -14
- data/lib/chamber/file_set.rb +18 -8
- data/lib/chamber/files/signature.rb +16 -14
- data/lib/chamber/filters/decryption_filter.rb +12 -10
- data/lib/chamber/filters/encryption_filter.rb +8 -8
- data/lib/chamber/filters/environment_filter.rb +12 -14
- data/lib/chamber/filters/failed_decryption_filter.rb +6 -6
- data/lib/chamber/filters/insecure_filter.rb +3 -3
- data/lib/chamber/filters/namespace_filter.rb +5 -5
- data/lib/chamber/filters/secure_filter.rb +5 -5
- data/lib/chamber/filters/translate_secure_keys_filter.rb +5 -5
- data/lib/chamber/instance.rb +37 -21
- data/lib/chamber/key_pair.rb +7 -7
- data/lib/chamber/keys/base.rb +13 -13
- data/lib/chamber/keys/decryption.rb +3 -3
- data/lib/chamber/keys/encryption.rb +3 -3
- data/lib/chamber/namespace_set.rb +2 -4
- data/lib/chamber/settings.rb +45 -43
- data/lib/chamber/types/secured.rb +8 -10
- data/lib/chamber/version.rb +1 -1
- data/templates/settings.yml +2 -0
- metadata +24 -26
- metadata.gz.sig +0 -0
@@ -6,15 +6,15 @@ require 'chamber/instance'
|
|
6
6
|
module Chamber
|
7
7
|
module Commands
|
8
8
|
module Securable
|
9
|
-
def initialize(
|
10
|
-
super
|
11
|
-
|
12
|
-
ignored_settings_options =
|
13
|
-
merge(files: ignored_settings_filepaths)
|
14
|
-
reject { |k, _v| k == 'basepath' }
|
15
|
-
self.ignored_settings_instance = Chamber::Instance.new(ignored_settings_options)
|
16
|
-
self.current_settings_instance = Chamber::Instance.new(
|
17
|
-
self.only_sensitive =
|
9
|
+
def initialize(only_sensitive: nil, **args)
|
10
|
+
super(**args)
|
11
|
+
|
12
|
+
ignored_settings_options = args
|
13
|
+
.merge(files: ignored_settings_filepaths)
|
14
|
+
.reject { |k, _v| k == 'basepath' }
|
15
|
+
self.ignored_settings_instance = Chamber::Instance.new(**ignored_settings_options)
|
16
|
+
self.current_settings_instance = Chamber::Instance.new(**args)
|
17
|
+
self.only_sensitive = only_sensitive
|
18
18
|
end
|
19
19
|
|
20
20
|
protected
|
@@ -8,8 +8,8 @@ module Commands
|
|
8
8
|
class Secure < Chamber::Commands::Base
|
9
9
|
include Chamber::Commands::Securable
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
super(
|
11
|
+
def initialize(**args)
|
12
|
+
super(**args.merge(namespaces: ['*']))
|
13
13
|
end
|
14
14
|
|
15
15
|
def call
|
@@ -9,21 +9,21 @@ class Show < Chamber::Commands::Base
|
|
9
9
|
attr_accessor :as_env,
|
10
10
|
:only_sensitive
|
11
11
|
|
12
|
-
def initialize(
|
13
|
-
super
|
12
|
+
def initialize(as_env: nil, only_sensitive: nil, **args)
|
13
|
+
super(**args)
|
14
14
|
|
15
|
-
self.as_env =
|
16
|
-
self.only_sensitive =
|
15
|
+
self.as_env = as_env
|
16
|
+
self.only_sensitive = only_sensitive
|
17
17
|
end
|
18
18
|
|
19
19
|
def call
|
20
20
|
if as_env
|
21
21
|
settings.to_s(pair_separator: "\n")
|
22
22
|
else
|
23
|
-
PP
|
24
|
-
pp(settings.to_hash, StringIO.new, 60)
|
25
|
-
string
|
26
|
-
chomp
|
23
|
+
PP
|
24
|
+
.pp(settings.to_hash, StringIO.new, 60)
|
25
|
+
.string
|
26
|
+
.chomp
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -5,8 +5,8 @@ require 'chamber/commands/base'
|
|
5
5
|
module Chamber
|
6
6
|
module Commands
|
7
7
|
class Sign < Chamber::Commands::Base
|
8
|
-
def initialize(
|
9
|
-
super(
|
8
|
+
def initialize(**args)
|
9
|
+
super(**args.merge(namespaces: ['*']))
|
10
10
|
end
|
11
11
|
|
12
12
|
def call
|
@@ -5,8 +5,8 @@ require 'chamber/commands/base'
|
|
5
5
|
module Chamber
|
6
6
|
module Commands
|
7
7
|
class Verify < Chamber::Commands::Base
|
8
|
-
def initialize(
|
9
|
-
super(
|
8
|
+
def initialize(**args)
|
9
|
+
super(**args.merge(namespaces: ['*']))
|
10
10
|
end
|
11
11
|
|
12
12
|
def call
|
@@ -9,10 +9,11 @@ class Configuration
|
|
9
9
|
:encryption_keys,
|
10
10
|
:files,
|
11
11
|
:namespaces,
|
12
|
-
:rootpath
|
12
|
+
:rootpath,
|
13
|
+
:signature_name
|
13
14
|
|
14
|
-
def initialize(
|
15
|
-
options = ContextResolver.resolve(
|
15
|
+
def initialize(**args)
|
16
|
+
options = ContextResolver.resolve(**args)
|
16
17
|
|
17
18
|
self.basepath = options.fetch(:basepath)
|
18
19
|
self.namespaces = options.fetch(:namespaces)
|
@@ -20,6 +21,7 @@ class Configuration
|
|
20
21
|
self.encryption_keys = options.fetch(:encryption_keys)
|
21
22
|
self.files = options.fetch(:files)
|
22
23
|
self.rootpath = options.fetch(:rootpath)
|
24
|
+
self.signature_name = options.fetch(:signature_name)
|
23
25
|
end
|
24
26
|
|
25
27
|
def to_hash
|
@@ -29,6 +31,7 @@ class Configuration
|
|
29
31
|
encryption_keys: encryption_keys,
|
30
32
|
files: files,
|
31
33
|
namespaces: namespaces,
|
34
|
+
signature_name: signature_name,
|
32
35
|
}
|
33
36
|
end
|
34
37
|
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'socket'
|
5
5
|
|
6
|
-
require 'chamber/core_ext/hash'
|
7
6
|
require 'chamber/keys/decryption'
|
8
7
|
require 'chamber/keys/encryption'
|
9
8
|
|
@@ -11,11 +10,11 @@ module Chamber
|
|
11
10
|
class ContextResolver
|
12
11
|
attr_accessor :options
|
13
12
|
|
14
|
-
def initialize(
|
15
|
-
self.options =
|
13
|
+
def initialize(**args)
|
14
|
+
self.options = args
|
16
15
|
end
|
17
16
|
|
18
|
-
# rubocop:disable Metrics/
|
17
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize, Layout/LineLength
|
19
18
|
def resolve
|
20
19
|
options[:rootpath] ||= Pathname.pwd
|
21
20
|
options[:rootpath] = Pathname.new(options[:rootpath])
|
@@ -43,12 +42,14 @@ class ContextResolver
|
|
43
42
|
options[:basepath] + 'settings',
|
44
43
|
]
|
45
44
|
|
45
|
+
options[:signature_name] = options[:signature_name]
|
46
|
+
|
46
47
|
options
|
47
48
|
end
|
48
|
-
# rubocop:enable Metrics/
|
49
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize, Layout/LineLength
|
49
50
|
|
50
|
-
def self.resolve(
|
51
|
-
new(
|
51
|
+
def self.resolve(**args)
|
52
|
+
new(**args).resolve
|
52
53
|
end
|
53
54
|
|
54
55
|
protected
|
@@ -5,7 +5,7 @@ require 'base64'
|
|
5
5
|
module Chamber
|
6
6
|
module EncryptionMethods
|
7
7
|
class Ssl
|
8
|
-
BASE64_STRING_PATTERN = %r{[A-Za-z0-9
|
8
|
+
BASE64_STRING_PATTERN = %r{[A-Za-z0-9+/#]*={0,2}}.freeze
|
9
9
|
LARGE_DATA_STRING_PATTERN = /
|
10
10
|
\A
|
11
11
|
(#{BASE64_STRING_PATTERN})
|
@@ -16,12 +16,12 @@ class Ssl
|
|
16
16
|
\z
|
17
17
|
/x.freeze
|
18
18
|
|
19
|
-
def self.encrypt(_key, value, encryption_keys)
|
20
|
-
value
|
21
|
-
cipher
|
19
|
+
def self.encrypt(_key, value, encryption_keys) # rubocop:disable Metrics/AbcSize
|
20
|
+
value = YAML.dump(value)
|
21
|
+
cipher = OpenSSL::Cipher.new('AES-128-CBC')
|
22
22
|
cipher.encrypt
|
23
23
|
symmetric_key = cipher.random_key
|
24
|
-
iv
|
24
|
+
iv = cipher.random_iv
|
25
25
|
|
26
26
|
# encrypt all data with this key and iv
|
27
27
|
encrypted_data = cipher.update(value) + cipher.final
|
@@ -35,24 +35,24 @@ class Ssl
|
|
35
35
|
Base64.strict_encode64(encrypted_data)
|
36
36
|
end
|
37
37
|
|
38
|
-
def self.decrypt(key, value, decryption_keys)
|
38
|
+
def self.decrypt(key, value, decryption_keys) # rubocop:disable Metrics/AbcSize
|
39
39
|
if decryption_keys.nil?
|
40
40
|
value
|
41
41
|
else
|
42
|
-
key, iv, decoded_string = value
|
43
|
-
match(LARGE_DATA_STRING_PATTERN)
|
44
|
-
captures
|
45
|
-
map do |part|
|
42
|
+
key, iv, decoded_string = value
|
43
|
+
.match(LARGE_DATA_STRING_PATTERN)
|
44
|
+
.captures
|
45
|
+
.map do |part|
|
46
46
|
Base64.strict_decode64(part)
|
47
47
|
end
|
48
|
-
key
|
48
|
+
key = decryption_keys.private_decrypt(key)
|
49
49
|
|
50
50
|
cipher_dec = OpenSSL::Cipher.new('AES-128-CBC')
|
51
51
|
|
52
52
|
cipher_dec.decrypt
|
53
53
|
|
54
54
|
cipher_dec.key = key
|
55
|
-
cipher_dec.iv
|
55
|
+
cipher_dec.iv = iv
|
56
56
|
|
57
57
|
begin
|
58
58
|
unencrypted_value = cipher_dec.update(decoded_string) + cipher_dec.final
|
data/lib/chamber/file.rb
CHANGED
@@ -13,7 +13,8 @@ module Chamber
|
|
13
13
|
class File < Pathname
|
14
14
|
attr_accessor :namespaces,
|
15
15
|
:decryption_keys,
|
16
|
-
:encryption_keys
|
16
|
+
:encryption_keys,
|
17
|
+
:signature_name
|
17
18
|
|
18
19
|
###
|
19
20
|
# Internal: Creates a settings file representing a path to a file on the
|
@@ -42,12 +43,13 @@ class File < Pathname
|
|
42
43
|
# Chamber::File.new path: '/tmp/settings.yml'
|
43
44
|
# # => <Chamber::File>
|
44
45
|
#
|
45
|
-
def initialize(
|
46
|
-
self.namespaces =
|
47
|
-
self.decryption_keys =
|
48
|
-
self.encryption_keys =
|
46
|
+
def initialize(path:, namespaces: {}, decryption_keys: {}, encryption_keys: {}, signature_name: nil)
|
47
|
+
self.namespaces = namespaces
|
48
|
+
self.decryption_keys = decryption_keys
|
49
|
+
self.encryption_keys = encryption_keys
|
50
|
+
self.signature_name = signature_name
|
49
51
|
|
50
|
-
super
|
52
|
+
super path
|
51
53
|
end
|
52
54
|
|
53
55
|
###
|
@@ -76,7 +78,7 @@ class File < Pathname
|
|
76
78
|
encryption_keys: encryption_keys)
|
77
79
|
end
|
78
80
|
|
79
|
-
# rubocop:disable Metrics/
|
81
|
+
# rubocop:disable Layout/LineLength, Metrics/AbcSize
|
80
82
|
def secure
|
81
83
|
insecure_settings = to_settings.insecure.to_flattened_name_hash
|
82
84
|
secure_settings = to_settings.insecure.secure.to_flattened_name_hash
|
@@ -88,14 +90,14 @@ class File < Pathname
|
|
88
90
|
escaped_name = Regexp.escape(name_pieces.last)
|
89
91
|
escaped_value = Regexp.escape(value)
|
90
92
|
|
91
|
-
file_contents
|
92
|
-
sub!(
|
93
|
+
file_contents
|
94
|
+
.sub!(
|
93
95
|
/^(\s*)#{secure_prefix_pattern}#{escaped_name}(\s*):(\s*)['"]?#{escaped_value}['"]?$/,
|
94
96
|
"\\1#{secure_prefix}#{name_pieces.last}\\2:\\3#{secure_value}",
|
95
97
|
)
|
96
98
|
|
97
|
-
file_contents
|
98
|
-
sub!(
|
99
|
+
file_contents
|
100
|
+
.sub!(
|
99
101
|
/^(\s*)#{secure_prefix_pattern}#{escaped_name}(\s*):(\s*)\|((?:\n\1\s{2}.*)+)/,
|
100
102
|
"\\1#{secure_prefix}#{name_pieces.last}\\2:\\3#{secure_value}",
|
101
103
|
)
|
@@ -103,7 +105,7 @@ class File < Pathname
|
|
103
105
|
|
104
106
|
write(file_contents)
|
105
107
|
end
|
106
|
-
# rubocop:enable Metrics/
|
108
|
+
# rubocop:enable Layout/LineLength, Metrics/AbcSize
|
107
109
|
|
108
110
|
def sign
|
109
111
|
signature_key_contents = decryption_keys[:signature]
|
@@ -111,7 +113,7 @@ class File < Pathname
|
|
111
113
|
fail ArgumentError, 'You asked to sign your settings files but no signature key was found. Run `chamber init --signature` to generate one.' \
|
112
114
|
unless signature_key_contents
|
113
115
|
|
114
|
-
signature = Files::Signature.new(to_s, read, signature_key_contents)
|
116
|
+
signature = Files::Signature.new(to_s, read, signature_key_contents, signature_name)
|
115
117
|
|
116
118
|
signature.write
|
117
119
|
end
|
@@ -122,7 +124,7 @@ class File < Pathname
|
|
122
124
|
fail ArgumentError, 'You asked to verify your settings files but no signature key was found. Run `chamber init --signature` to generate one.' \
|
123
125
|
unless signature_key_contents
|
124
126
|
|
125
|
-
signature = Files::Signature.new(to_s, read, signature_key_contents)
|
127
|
+
signature = Files::Signature.new(to_s, read, signature_key_contents, signature_name)
|
126
128
|
|
127
129
|
signature.verify
|
128
130
|
end
|
data/lib/chamber/file_set.rb
CHANGED
@@ -114,17 +114,26 @@ module Chamber
|
|
114
114
|
class FileSet
|
115
115
|
attr_accessor :decryption_keys,
|
116
116
|
:encryption_keys,
|
117
|
-
:basepath
|
117
|
+
:basepath,
|
118
|
+
:signature_name
|
118
119
|
attr_reader :namespaces,
|
119
120
|
:paths
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
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
|
@@ -8,9 +8,9 @@ module Chamber
|
|
8
8
|
module Files
|
9
9
|
class Signature
|
10
10
|
SIGNATURE_HEADER = '-----BEGIN CHAMBER SIGNATURE-----'
|
11
|
-
SIGNATURE_HEADER_PATTERN =
|
11
|
+
SIGNATURE_HEADER_PATTERN = /-----BEGIN\sCHAMBER\sSIGNATURE-----/.freeze
|
12
12
|
SIGNATURE_FOOTER = '-----END CHAMBER SIGNATURE-----'
|
13
|
-
SIGNATURE_FOOTER_PATTERN =
|
13
|
+
SIGNATURE_FOOTER_PATTERN = /-----END\sCHAMBER\sSIGNATURE-----/.freeze
|
14
14
|
SIGNATURE_IN_FILE_PATTERN = /
|
15
15
|
#{SIGNATURE_HEADER_PATTERN}\n # Header
|
16
16
|
(.*)\n # Signature Body
|
@@ -18,14 +18,16 @@ class Signature
|
|
18
18
|
/x.freeze
|
19
19
|
|
20
20
|
attr_accessor :settings_content,
|
21
|
-
:settings_filename
|
21
|
+
:settings_filename,
|
22
|
+
:signature_name
|
22
23
|
|
23
24
|
attr_reader :signature_key
|
24
25
|
|
25
|
-
def initialize(settings_filename, settings_content, signature_key)
|
26
|
+
def initialize(settings_filename, settings_content, signature_key, signature_name)
|
26
27
|
self.signature_key = signature_key
|
27
28
|
self.settings_content = settings_content
|
28
29
|
self.settings_filename = Pathname.new(settings_filename)
|
30
|
+
self.signature_name = signature_name
|
29
31
|
end
|
30
32
|
|
31
33
|
def signature_key=(keyish)
|
@@ -41,7 +43,7 @@ class Signature
|
|
41
43
|
|
42
44
|
def write
|
43
45
|
signature_filename.write(<<-HEREDOC, 0, mode: 'w+')
|
44
|
-
Signed By: #{
|
46
|
+
Signed By: #{signature_name}
|
45
47
|
Signed At: #{Time.now.utc.iso8601}
|
46
48
|
|
47
49
|
#{SIGNATURE_HEADER}
|
@@ -61,20 +63,20 @@ Signed At: #{Time.now.utc.iso8601}
|
|
61
63
|
end
|
62
64
|
|
63
65
|
def raw_signature
|
64
|
-
@raw_signature ||= signature_key
|
65
|
-
sign(digest, settings_content)
|
66
|
+
@raw_signature ||= signature_key
|
67
|
+
.sign(digest, settings_content)
|
66
68
|
end
|
67
69
|
|
68
70
|
def signature_filename
|
69
|
-
@signature_filename ||= settings_filename
|
70
|
-
sub('.yml', '.sig')
|
71
|
-
sub('.erb', '')
|
71
|
+
@signature_filename ||= settings_filename
|
72
|
+
.sub('.yml', '.sig')
|
73
|
+
.sub('.erb', '')
|
72
74
|
end
|
73
75
|
|
74
76
|
def encoded_signature_content
|
75
|
-
@encoded_signature_content ||= signature_filename
|
76
|
-
read
|
77
|
-
match(SIGNATURE_IN_FILE_PATTERN) do |match|
|
77
|
+
@encoded_signature_content ||= signature_filename
|
78
|
+
.read
|
79
|
+
.match(SIGNATURE_IN_FILE_PATTERN) do |match|
|
78
80
|
match[1]
|
79
81
|
end
|
80
82
|
end
|
@@ -84,7 +86,7 @@ Signed At: #{Time.now.utc.iso8601}
|
|
84
86
|
end
|
85
87
|
|
86
88
|
def digest
|
87
|
-
@digest ||= OpenSSL::Digest
|
89
|
+
@digest ||= OpenSSL::Digest.new('SHA512')
|
88
90
|
end
|
89
91
|
end
|
90
92
|
end
|
@@ -12,19 +12,19 @@ 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
|
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
|
19
|
+
[A-Za-z0-9+/#]*={0,2} # Base64 Encoded Key
|
20
20
|
)
|
21
21
|
\# # Separator
|
22
22
|
(
|
23
|
-
[A-Za-z0-9
|
23
|
+
[A-Za-z0-9+/#]*={0,2} # Base64 Encoded IV
|
24
24
|
)
|
25
25
|
\# # Separator
|
26
26
|
(
|
27
|
-
[A-Za-z0-9
|
27
|
+
[A-Za-z0-9+/#]*={0,2} # Base64 Encoded Data
|
28
28
|
)
|
29
29
|
\z # End of String
|
30
30
|
}x.freeze
|
@@ -33,14 +33,14 @@ class DecryptionFilter
|
|
33
33
|
:secure_key_token
|
34
34
|
attr_reader :decryption_keys
|
35
35
|
|
36
|
-
def initialize(
|
37
|
-
self.decryption_keys =
|
38
|
-
self.data =
|
39
|
-
self.secure_key_token = /\A#{Regexp.escape(
|
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(
|
43
|
-
new(
|
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)
|