chamber 3.0.0rc1 → 3.0.0
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +5 -5
- data/lib/chamber/binary/runner.rb +10 -12
- data/lib/chamber/commands/base.rb +4 -4
- data/lib/chamber/commands/initialize.rb +5 -5
- data/lib/chamber/commands/securable.rb +5 -9
- data/lib/chamber/commands/show.rb +0 -1
- data/lib/chamber/context_resolver.rb +5 -4
- data/lib/chamber/encryption_methods/public_key.rb +26 -14
- data/lib/chamber/encryption_methods/ssl.rb +36 -28
- data/lib/chamber/errors/disallowed_class.rb +8 -0
- data/lib/chamber/errors/invalid_key_type.rb +8 -0
- data/lib/chamber/errors/missing_index.rb +13 -0
- data/lib/chamber/errors/missing_setting.rb +13 -0
- data/lib/chamber/errors/non_conforming_key.rb +8 -0
- data/lib/chamber/file.rb +18 -7
- data/lib/chamber/file_set.rb +5 -1
- data/lib/chamber/files/signature.rb +6 -6
- data/lib/chamber/filters/decryption_filter.rb +9 -11
- data/lib/chamber/filters/encryption_filter.rb +8 -9
- data/lib/chamber/filters/environment_filter.rb +16 -18
- data/lib/chamber/filters/failed_decryption_filter.rb +3 -3
- data/lib/chamber/filters/namespace_filter.rb +10 -12
- data/lib/chamber/filters/secure_filter.rb +3 -3
- data/lib/chamber/filters/translate_secure_keys_filter.rb +3 -3
- data/lib/chamber/instance.rb +4 -7
- data/lib/chamber/integrations/sinatra.rb +1 -1
- data/lib/chamber/keys/base.rb +11 -7
- data/lib/chamber/namespace_set.rb +2 -2
- data/lib/chamber/rails.rb +1 -1
- data/lib/chamber/refinements/deep_dup.rb +12 -36
- data/lib/chamber/refinements/enumerable.rb +8 -20
- data/lib/chamber/refinements/hash.rb +10 -36
- data/lib/chamber/rubinius_fix.rb +1 -1
- data/lib/chamber/settings.rb +39 -23
- data/lib/chamber/types/secured.rb +8 -8
- data/lib/chamber/version.rb +1 -1
- data/lib/chamber.rb +0 -5
- data.tar.gz.sig +0 -0
- metadata +29 -34
- metadata.gz.sig +0 -0
- data/lib/chamber/adapters/cloud/circle_ci.rb +0 -85
- data/lib/chamber/adapters/cloud/heroku.rb +0 -74
- data/lib/chamber/binary/circle_ci.rb +0 -123
- data/lib/chamber/binary/heroku.rb +0 -111
- data/lib/chamber/binary/travis.rb +0 -37
- data/lib/chamber/commands/cloud/base.rb +0 -35
- data/lib/chamber/commands/cloud/clear.rb +0 -25
- data/lib/chamber/commands/cloud/compare.rb +0 -26
- data/lib/chamber/commands/cloud/pull.rb +0 -29
- data/lib/chamber/commands/cloud/push.rb +0 -44
- data/lib/chamber/commands/travis/secure.rb +0 -37
- data/lib/chamber/refinements/array.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d89ed0b7af0eced2bb6890ea18af915dfdecaf4e521fb8f48bea9bc39fbbaae
|
4
|
+
data.tar.gz: 5befdc9cd11ca4e0aced5a7da916f6d849e49eb3a8a60df63cd61c9afb5e5637
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bdebbf96a6ca8183d4f480230d2cffe39d2d927f9ffa3fe396ab394271e3f33c7fcde2c58259483617817fc2fe1528c92391ecd822845de71e9d3dddca6a67a
|
7
|
+
data.tar.gz: 54603c3d40c94f6d4b7c57bd7a424730afe1e3d1ddd9e499426d14fa57549176bb32844034ef8da3b0fee1c38c9d3245e920941dc65c671a7362150f7ba157a9
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ Chamber
|
|
19
19
|
</a>
|
20
20
|
|
21
21
|
<a href="https://github.com/thekompanee/chamber/actions?query=workflow%3ABuild" alt="Build Status">
|
22
|
-
<img src="https://img.shields.io/github/workflow/status/thekompanee/chamber/
|
22
|
+
<img src="https://img.shields.io/github/actions/workflow/status/thekompanee/chamber/testing.yml?branch=master&label=CI&style=flat-square&logo=github" alt="Build Status" />
|
23
23
|
</a>
|
24
24
|
|
25
25
|
<a href="#" alt="Maintainability">
|
@@ -61,11 +61,11 @@ smtp_username: 'my_username'
|
|
61
61
|
smtp_password: 'my_password'
|
62
62
|
```
|
63
63
|
|
64
|
-
From there you can access your settings by using the special `Chamber.
|
64
|
+
From there you can access your settings by using the special `Chamber.dig`
|
65
65
|
constant.
|
66
66
|
|
67
67
|
```ruby
|
68
|
-
Chamber.
|
68
|
+
Chamber.dig('smtp_password')
|
69
69
|
# => 'my_password'
|
70
70
|
```
|
71
71
|
|
@@ -92,7 +92,7 @@ which you still access the same way because Chamber handles the decryption for
|
|
92
92
|
you:
|
93
93
|
|
94
94
|
```ruby
|
95
|
-
Chamber.
|
95
|
+
Chamber.dig('smtp_password')
|
96
96
|
# => 'my_password'
|
97
97
|
```
|
98
98
|
|
@@ -117,7 +117,7 @@ The names and logos for The Kompanee are trademarks of The Kompanee, Ltd.
|
|
117
117
|
License
|
118
118
|
--------------------------------------------------------------------------------
|
119
119
|
|
120
|
-
Chamber is Copyright © 2014-
|
120
|
+
Chamber is Copyright © 2014-2023 Jeff Felchner and Mark McEahern. It is free
|
121
121
|
software, and may be redistributed under the terms specified in the
|
122
122
|
[LICENSE][license] file.
|
123
123
|
|
@@ -12,20 +12,18 @@ require 'chamber/commands/sign'
|
|
12
12
|
require 'chamber/commands/verify'
|
13
13
|
require 'chamber/commands/compare'
|
14
14
|
require 'chamber/commands/initialize'
|
15
|
-
require 'chamber/refinements/hash'
|
16
15
|
|
17
16
|
module Chamber
|
18
17
|
module Binary
|
19
|
-
class Runner <
|
20
|
-
include
|
21
|
-
using ::Chamber::Refinements::Hash
|
18
|
+
class Runner < Thor
|
19
|
+
include Thor::Actions
|
22
20
|
|
23
21
|
source_root ::File.expand_path('../../../templates', __dir__)
|
24
22
|
|
25
23
|
class_option :rootpath,
|
26
24
|
type: :string,
|
27
25
|
aliases: '-r',
|
28
|
-
default: ENV
|
26
|
+
default: ENV.fetch('PWD', nil),
|
29
27
|
desc: 'The root filepath of the application'
|
30
28
|
|
31
29
|
class_option :basepath,
|
@@ -94,7 +92,7 @@ class Runner < ::Thor
|
|
94
92
|
'Useful for debugging.'
|
95
93
|
|
96
94
|
def show
|
97
|
-
puts Commands::Show.call(**options.
|
95
|
+
puts Commands::Show.call(**options.transform_keys(&:to_sym).merge(shell: self))
|
98
96
|
end
|
99
97
|
|
100
98
|
################################################################################
|
@@ -102,7 +100,7 @@ class Runner < ::Thor
|
|
102
100
|
desc 'files', 'Lists the settings files which are parsed with the given options'
|
103
101
|
|
104
102
|
def files
|
105
|
-
puts Commands::Files.call(**options.
|
103
|
+
puts Commands::Files.call(**options.transform_keys(&:to_sym).merge(shell: self))
|
106
104
|
end
|
107
105
|
|
108
106
|
################################################################################
|
@@ -132,7 +130,7 @@ class Runner < ::Thor
|
|
132
130
|
'destination of the comparison'
|
133
131
|
|
134
132
|
def compare
|
135
|
-
Commands::Compare.call(**options.
|
133
|
+
Commands::Compare.call(**options.transform_keys(&:to_sym).merge(shell: self))
|
136
134
|
end
|
137
135
|
|
138
136
|
################################################################################
|
@@ -152,7 +150,7 @@ class Runner < ::Thor
|
|
152
150
|
'what values would be encrypted'
|
153
151
|
|
154
152
|
def secure
|
155
|
-
Commands::Secure.call(**options.
|
153
|
+
Commands::Secure.call(**options.transform_keys(&:to_sym).merge(shell: self))
|
156
154
|
end
|
157
155
|
|
158
156
|
################################################################################
|
@@ -171,9 +169,9 @@ class Runner < ::Thor
|
|
171
169
|
|
172
170
|
def sign
|
173
171
|
if options[:verify]
|
174
|
-
Commands::Verify.call(**options.
|
172
|
+
Commands::Verify.call(**options.transform_keys(&:to_sym).merge(shell: self))
|
175
173
|
else
|
176
|
-
Commands::Sign.call(**options.
|
174
|
+
Commands::Sign.call(**options.transform_keys(&:to_sym).merge(shell: self))
|
177
175
|
end
|
178
176
|
end
|
179
177
|
|
@@ -187,7 +185,7 @@ class Runner < ::Thor
|
|
187
185
|
default: false
|
188
186
|
|
189
187
|
def init
|
190
|
-
Commands::Initialize.call(**options.
|
188
|
+
Commands::Initialize.call(**options.transform_keys(&:to_sym).merge(shell: self))
|
191
189
|
end
|
192
190
|
end
|
193
191
|
end
|
@@ -6,15 +6,15 @@ require 'chamber/instance'
|
|
6
6
|
module Chamber
|
7
7
|
module Commands
|
8
8
|
class Base
|
9
|
-
def self.call(**args)
|
10
|
-
new(**args).call
|
11
|
-
end
|
12
|
-
|
13
9
|
attr_accessor :chamber,
|
14
10
|
:dry_run,
|
15
11
|
:rootpath,
|
16
12
|
:shell
|
17
13
|
|
14
|
+
def self.call(**args)
|
15
|
+
new(**args).call
|
16
|
+
end
|
17
|
+
|
18
18
|
def initialize(shell: nil, rootpath: nil, dry_run: nil, **args)
|
19
19
|
self.chamber = Chamber::Instance.new(rootpath: rootpath, **args)
|
20
20
|
self.shell = shell
|
@@ -11,14 +11,14 @@ require 'chamber/commands/base'
|
|
11
11
|
module Chamber
|
12
12
|
module Commands
|
13
13
|
class Initialize < Chamber::Commands::Base
|
14
|
-
def self.call(**args)
|
15
|
-
new(**args).call
|
16
|
-
end
|
17
|
-
|
18
14
|
attr_accessor :basepath,
|
19
15
|
:namespaces,
|
20
16
|
:signature
|
21
17
|
|
18
|
+
def self.call(**args)
|
19
|
+
new(**args).call
|
20
|
+
end
|
21
|
+
|
22
22
|
def initialize(signature:, namespaces: [], **args)
|
23
23
|
super(**args)
|
24
24
|
|
@@ -194,7 +194,7 @@ class Initialize < Chamber::Commands::Base
|
|
194
194
|
.chamber*.enc.pass
|
195
195
|
!.chamber*.pub.pem
|
196
196
|
}.each do |pattern|
|
197
|
-
unless gitignore_contents
|
197
|
+
unless gitignore_contents&.match?(Regexp.new(Regexp.escape(pattern)))
|
198
198
|
shell.append_to_file gitignore_filepath, "#{pattern}\n"
|
199
199
|
end
|
200
200
|
end
|
@@ -2,18 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'shellwords'
|
4
4
|
require 'chamber/instance'
|
5
|
-
require 'chamber/refinements/hash'
|
6
5
|
|
7
6
|
module Chamber
|
8
7
|
module Commands
|
9
8
|
module Securable
|
10
|
-
using ::Chamber::Refinements::Hash
|
11
|
-
|
12
9
|
def initialize(only_sensitive: nil, **args)
|
13
10
|
super(**args)
|
14
11
|
|
15
12
|
ignored_settings_options = args
|
16
|
-
.
|
13
|
+
.merge(files: ignored_settings_filepaths)
|
17
14
|
.reject { |k, _v| k == 'basepath' }
|
18
15
|
self.ignored_settings_instance = Chamber::Instance.new(**ignored_settings_options)
|
19
16
|
self.current_settings_instance = Chamber::Instance.new(**args)
|
@@ -55,11 +52,10 @@ module Securable
|
|
55
52
|
Shellwords.escape(filename)
|
56
53
|
end
|
57
54
|
|
58
|
-
`
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
`.split("\n")
|
55
|
+
`git ls-files --other --ignored --exclude-per-directory=.gitignore`
|
56
|
+
.split("\n")
|
57
|
+
.map { |filename| "#{Shellwords.escape(rootpath.to_s)}/#{filename}" }
|
58
|
+
.select { |filename| shell_escaped_chamber_filenames.include?(filename) }
|
63
59
|
end
|
64
60
|
end
|
65
61
|
end
|
@@ -10,6 +10,10 @@ module Chamber
|
|
10
10
|
class ContextResolver
|
11
11
|
attr_accessor :options
|
12
12
|
|
13
|
+
def self.resolve(**args)
|
14
|
+
new(**args).resolve
|
15
|
+
end
|
16
|
+
|
13
17
|
def initialize(**args)
|
14
18
|
self.options = args
|
15
19
|
end
|
@@ -41,16 +45,13 @@ class ContextResolver
|
|
41
45
|
options[:basepath] + 'settings*.yml',
|
42
46
|
options[:basepath] + 'settings',
|
43
47
|
]
|
48
|
+
|
44
49
|
options[:signature_name] = options[:signature_name]
|
45
50
|
|
46
51
|
options
|
47
52
|
end
|
48
53
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize, Layout/LineLength
|
49
54
|
|
50
|
-
def self.resolve(**args)
|
51
|
-
new(**args).resolve
|
52
|
-
end
|
53
|
-
|
54
55
|
protected
|
55
56
|
|
56
57
|
def resolve_namespaces(other)
|
@@ -2,29 +2,41 @@
|
|
2
2
|
|
3
3
|
require 'base64'
|
4
4
|
|
5
|
+
require 'chamber/errors/disallowed_class'
|
6
|
+
|
5
7
|
module Chamber
|
6
8
|
module EncryptionMethods
|
7
9
|
class PublicKey
|
8
|
-
def self.encrypt(
|
10
|
+
def self.encrypt(_settings_key, value, encryption_key)
|
9
11
|
value = YAML.dump(value)
|
10
12
|
encrypted_string = encryption_key.public_encrypt(value)
|
11
13
|
|
12
14
|
Base64.strict_encode64(encrypted_string)
|
13
15
|
end
|
14
16
|
|
15
|
-
def self.decrypt(
|
16
|
-
if decryption_key.nil?
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
17
|
+
def self.decrypt(_settings_key, value, decryption_key)
|
18
|
+
return value if decryption_key.nil?
|
19
|
+
|
20
|
+
decoded_string = ::Base64.strict_decode64(value)
|
21
|
+
unencrypted_value = decryption_key.private_decrypt(decoded_string)
|
22
|
+
|
23
|
+
::YAML.safe_load(unencrypted_value,
|
24
|
+
aliases: true,
|
25
|
+
permitted_classes: [
|
26
|
+
::Date,
|
27
|
+
::Time,
|
28
|
+
::Regexp,
|
29
|
+
])
|
30
|
+
rescue ::Psych::DisallowedClass => error
|
31
|
+
raise ::Chamber::Errors::DisallowedClass, <<~HEREDOC
|
32
|
+
#{error.message}
|
33
|
+
|
34
|
+
You attempted to load a class instance via your Chamber settings that is not allowed.
|
35
|
+
|
36
|
+
See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#limiting-complex-classes for full details.
|
37
|
+
HEREDOC
|
38
|
+
rescue ::TypeError
|
39
|
+
unencrypted_value
|
28
40
|
end
|
29
41
|
end
|
30
42
|
end
|
@@ -16,7 +16,7 @@ class Ssl
|
|
16
16
|
\z
|
17
17
|
/x.freeze
|
18
18
|
|
19
|
-
def self.encrypt(
|
19
|
+
def self.encrypt(_settings_key, value, encryption_keys) # rubocop:disable Metrics/AbcSize
|
20
20
|
value = YAML.dump(value)
|
21
21
|
cipher = OpenSSL::Cipher.new('AES-128-CBC')
|
22
22
|
cipher.encrypt
|
@@ -35,38 +35,46 @@ class Ssl
|
|
35
35
|
Base64.strict_encode64(encrypted_data)
|
36
36
|
end
|
37
37
|
|
38
|
-
def self.decrypt(
|
39
|
-
if decryption_keys.nil?
|
40
|
-
value
|
41
|
-
else
|
42
|
-
key, iv, decoded_string = value
|
43
|
-
.match(LARGE_DATA_STRING_PATTERN)
|
44
|
-
.captures
|
45
|
-
.map do |part|
|
46
|
-
Base64.strict_decode64(part)
|
47
|
-
end
|
48
|
-
key = decryption_keys.private_decrypt(key)
|
38
|
+
def self.decrypt(_settings_key, value, decryption_keys) # rubocop:disable Metrics/AbcSize
|
39
|
+
return value if decryption_keys.nil?
|
49
40
|
|
50
|
-
|
41
|
+
key, iv, decoded_string = value
|
42
|
+
.match(LARGE_DATA_STRING_PATTERN)
|
43
|
+
.captures
|
44
|
+
.map do |part|
|
45
|
+
::Base64.strict_decode64(part)
|
46
|
+
end
|
47
|
+
key = decryption_keys.private_decrypt(key)
|
51
48
|
|
52
|
-
|
49
|
+
cipher_dec = ::OpenSSL::Cipher.new('AES-128-CBC')
|
53
50
|
|
54
|
-
|
55
|
-
cipher_dec.iv = iv
|
51
|
+
cipher_dec.decrypt
|
56
52
|
|
57
|
-
|
58
|
-
|
59
|
-
rescue OpenSSL::Cipher::CipherError
|
60
|
-
raise Chamber::Errors::DecryptionFailure,
|
61
|
-
'A decryption error occurred. It was probably due to invalid key data.'
|
62
|
-
end
|
53
|
+
cipher_dec.key = key
|
54
|
+
cipher_dec.iv = iv
|
63
55
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
56
|
+
unencrypted_value = cipher_dec.update(decoded_string) + cipher_dec.final
|
57
|
+
|
58
|
+
::YAML.safe_load(unencrypted_value,
|
59
|
+
aliases: true,
|
60
|
+
permitted_classes: [
|
61
|
+
::Date,
|
62
|
+
::Time,
|
63
|
+
::Regexp,
|
64
|
+
])
|
65
|
+
rescue ::OpenSSL::Cipher::CipherError
|
66
|
+
raise ::Chamber::Errors::DecryptionFailure,
|
67
|
+
'A decryption error occurred. It was probably due to invalid key data.'
|
68
|
+
rescue ::Psych::DisallowedClass => error
|
69
|
+
raise ::Chamber::Errors::DisallowedClass, <<~HEREDOC
|
70
|
+
#{error.message}
|
71
|
+
|
72
|
+
You attempted to load a class instance via your Chamber settings that is not allowed.
|
73
|
+
|
74
|
+
See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#limiting-complex-classes for full details.
|
75
|
+
HEREDOC
|
76
|
+
rescue ::TypeError
|
77
|
+
unencrypted_value
|
70
78
|
end
|
71
79
|
end
|
72
80
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Chamber
|
4
|
+
module Errors
|
5
|
+
class MissingIndex < ::IndexError
|
6
|
+
def initialize(missing_index, all_keys)
|
7
|
+
super(<<~HEREDOC.chomp)
|
8
|
+
You attempted to access setting '#{all_keys.join(':')}' but the index '#{missing_index}' in the array did not exist.
|
9
|
+
HEREDOC
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Chamber
|
4
|
+
module Errors
|
5
|
+
class MissingSetting < ::KeyError
|
6
|
+
def initialize(missing_key, all_keys)
|
7
|
+
super(<<~HEREDOC.chomp)
|
8
|
+
You attempted to access setting '#{all_keys.join(':')}' but '#{missing_key}' did not exist.
|
9
|
+
HEREDOC
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/chamber/file.rb
CHANGED
@@ -4,7 +4,6 @@ require 'pathname'
|
|
4
4
|
require 'yaml'
|
5
5
|
require 'erb'
|
6
6
|
require 'chamber/files/signature'
|
7
|
-
require 'chamber/refinements/hash'
|
8
7
|
|
9
8
|
###
|
10
9
|
# Internal: Represents a single file containing settings information in a given
|
@@ -12,8 +11,6 @@ require 'chamber/refinements/hash'
|
|
12
11
|
#
|
13
12
|
module Chamber
|
14
13
|
class File < Pathname
|
15
|
-
using ::Chamber::Refinements::Hash
|
16
|
-
|
17
14
|
attr_accessor :namespaces,
|
18
15
|
:decryption_keys,
|
19
16
|
:encryption_keys,
|
@@ -144,10 +141,24 @@ class File < Pathname
|
|
144
141
|
|
145
142
|
def file_contents_hash
|
146
143
|
file_contents = read
|
147
|
-
erb_result = ERB.new(file_contents).result
|
148
|
-
|
149
|
-
|
150
|
-
|
144
|
+
erb_result = ::ERB.new(file_contents).result
|
145
|
+
|
146
|
+
::YAML.safe_load(erb_result,
|
147
|
+
aliases: true,
|
148
|
+
permitted_classes: [
|
149
|
+
::Date,
|
150
|
+
::Time,
|
151
|
+
::Regexp,
|
152
|
+
]) || {}
|
153
|
+
rescue ::Psych::DisallowedClass => error
|
154
|
+
raise ::Chamber::Errors::DisallowedClass, <<~HEREDOC
|
155
|
+
#{error.message}
|
156
|
+
|
157
|
+
You attempted to load a class instance via your Chamber settings that is not allowed.
|
158
|
+
|
159
|
+
See https://github.com/thekompanee/chamber/wiki/Upgrading-To-Chamber-3.0#limiting-complex-classes for full details.
|
160
|
+
HEREDOC
|
161
|
+
rescue ::Errno::ENOENT
|
151
162
|
{}
|
152
163
|
end
|
153
164
|
end
|
data/lib/chamber/file_set.rb
CHANGED
@@ -257,7 +257,11 @@ class FileSet
|
|
257
257
|
private
|
258
258
|
|
259
259
|
def all_files
|
260
|
-
@all_files ||= file_globs
|
260
|
+
@all_files ||= file_globs
|
261
|
+
.map { |fg| Pathname.glob(fg) }
|
262
|
+
.flatten
|
263
|
+
.uniq
|
264
|
+
.sort
|
261
265
|
end
|
262
266
|
|
263
267
|
def non_namespaced_files
|
@@ -42,13 +42,13 @@ class Signature
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def write
|
45
|
-
signature_filename.write(
|
46
|
-
Signed By: #{signature_name}
|
47
|
-
Signed At: #{Time.now.utc.iso8601}
|
45
|
+
signature_filename.write(<<~HEREDOC, 0, mode: 'w+')
|
46
|
+
Signed By: #{signature_name}
|
47
|
+
Signed At: #{Time.now.utc.iso8601}
|
48
48
|
|
49
|
-
#{SIGNATURE_HEADER}
|
50
|
-
#{encoded_signature}
|
51
|
-
#{SIGNATURE_FOOTER}
|
49
|
+
#{SIGNATURE_HEADER}
|
50
|
+
#{encoded_signature}
|
51
|
+
#{SIGNATURE_FOOTER}
|
52
52
|
HEREDOC
|
53
53
|
end
|
54
54
|
|
@@ -35,16 +35,16 @@ class DecryptionFilter
|
|
35
35
|
:secure_key_token
|
36
36
|
attr_reader :decryption_keys
|
37
37
|
|
38
|
+
def self.execute(**args)
|
39
|
+
new(**args).__send__(:execute)
|
40
|
+
end
|
41
|
+
|
38
42
|
def initialize(data:, secure_key_prefix:, decryption_keys: {}, **_args)
|
39
|
-
self.decryption_keys = decryption_keys || {}
|
43
|
+
self.decryption_keys = (decryption_keys || {}).transform_keys(&:to_s)
|
40
44
|
self.data = data.deep_dup
|
41
45
|
self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
|
42
46
|
end
|
43
47
|
|
44
|
-
def self.execute(**args)
|
45
|
-
new(**args).__send__(:execute)
|
46
|
-
end
|
47
|
-
|
48
48
|
protected
|
49
49
|
|
50
50
|
def execute(raw_data = data)
|
@@ -81,18 +81,16 @@ class DecryptionFilter
|
|
81
81
|
method = decryption_method(value)
|
82
82
|
|
83
83
|
decryption_keys.each do |decryption_key|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
next
|
88
|
-
end
|
84
|
+
return method.decrypt(key, value, decryption_key)
|
85
|
+
rescue OpenSSL::PKey::RSAError
|
86
|
+
next
|
89
87
|
end
|
90
88
|
|
91
89
|
value
|
92
90
|
end
|
93
91
|
|
94
92
|
def decryption_method(value)
|
95
|
-
if value.
|
93
|
+
if value.is_a?(::String)
|
96
94
|
if value.match(BASE64_STRING_PATTERN)
|
97
95
|
EncryptionMethods::PublicKey
|
98
96
|
elsif value.match(LARGE_DATA_STRING_PATTERN)
|
@@ -28,16 +28,16 @@ class EncryptionFilter
|
|
28
28
|
:secure_key_token
|
29
29
|
attr_reader :encryption_keys
|
30
30
|
|
31
|
+
def self.execute(**args)
|
32
|
+
new(**args).__send__(:execute)
|
33
|
+
end
|
34
|
+
|
31
35
|
def initialize(data:, secure_key_prefix:, encryption_keys: {}, **_args)
|
32
|
-
self.encryption_keys = encryption_keys || {}
|
36
|
+
self.encryption_keys = (encryption_keys || {}).transform_keys(&:to_s)
|
33
37
|
self.data = data.deep_dup
|
34
38
|
self.secure_key_token = /\A#{Regexp.escape(secure_key_prefix)}/
|
35
39
|
end
|
36
40
|
|
37
|
-
def self.execute(**args)
|
38
|
-
new(**args).__send__(:execute)
|
39
|
-
end
|
40
|
-
|
41
41
|
protected
|
42
42
|
|
43
43
|
def execute(raw_data = data, namespace = nil)
|
@@ -53,7 +53,7 @@ class EncryptionFilter
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def encryption_keys=(other)
|
56
|
-
@encryption_keys = other.each_with_object({}) do |(namespace, keyish), memo|
|
56
|
+
@encryption_keys = other.each_with_object({}) do |(namespace, keyish), memo| # rubocop:disable Style/HashTransformValues
|
57
57
|
memo[namespace] = if keyish.is_a?(OpenSSL::PKey::RSA)
|
58
58
|
keyish
|
59
59
|
elsif ::File.readable?(::File.expand_path(keyish))
|
@@ -69,8 +69,7 @@ class EncryptionFilter
|
|
69
69
|
|
70
70
|
def encrypt(namespace, key, value)
|
71
71
|
method = encryption_method(value)
|
72
|
-
|
73
|
-
encryption_key = encryption_keys[namespace_key] || encryption_keys[:__default]
|
72
|
+
encryption_key = encryption_keys[namespace] || encryption_keys['__default']
|
74
73
|
|
75
74
|
return value unless encryption_key
|
76
75
|
|
@@ -78,7 +77,7 @@ class EncryptionFilter
|
|
78
77
|
end
|
79
78
|
|
80
79
|
def encryption_method(value)
|
81
|
-
value_is_encrypted = value.
|
80
|
+
value_is_encrypted = value.is_a?(::String) &&
|
82
81
|
(value.match(BASE64_STRING_PATTERN) ||
|
83
82
|
value.match(LARGE_DATA_STRING_PATTERN))
|
84
83
|
|