complex_config 0.12.1 → 0.13.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
- data/README.md +4 -0
- data/VERSION +1 -1
- data/complex_config.gemspec +5 -5
- data/lib/complex_config/provider.rb +63 -26
- data/lib/complex_config/version.rb +1 -1
- data/spec/complex_config/provider_spec.rb +36 -11
- metadata +3 -4
- data/spec/config/with-shell-script.yml.enc +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d1f7d933962f507ac718b852309d72585130723
|
|
4
|
+
data.tar.gz: 91ec39308815be851342140df5a4c3f7618e2ab8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f05aa30b6ba2763e73b73cf9d9b27ef21ba3f8a4c68930f2c80aaeb4a9842e99f35bae7bc2a337d6444d01d66f8c83e2d0dd2aff21b440ad170848e0c48145d
|
|
7
|
+
data.tar.gz: 9c7d6845a920b6e1099d8c7ba588361f173e8e4eeac13c07761c262c31442e1ca8402ab1b564dd3e6857998b343933bc8d769ca8218aa1af1c1d7e00f85c3ea4
|
data/README.md
CHANGED
|
@@ -144,6 +144,10 @@ Here is the `ComplexConfig::Plugins::MONEY` plugin for example:
|
|
|
144
144
|
|
|
145
145
|
## Changes
|
|
146
146
|
|
|
147
|
+
* 2018-01-26 Release 0.13.0
|
|
148
|
+
Improve `write_config` interface and more tests
|
|
149
|
+
* 2017-11-17 Release 0.12.2
|
|
150
|
+
Output string keys on top level configs, Rails don't like it otherwise.
|
|
147
151
|
* 2017-11-17 Release 0.12.1
|
|
148
152
|
Do not output newlines when writing encrypted configs, Rails don't like it.
|
|
149
153
|
* 2017-11-16 Release 0.12.0
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.13.0
|
data/complex_config.gemspec
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: complex_config 0.
|
|
2
|
+
# stub: complex_config 0.13.0 ruby lib
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "complex_config".freeze
|
|
6
|
-
s.version = "0.
|
|
6
|
+
s.version = "0.13.0"
|
|
7
7
|
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
9
9
|
s.require_paths = ["lib".freeze]
|
|
10
10
|
s.authors = ["Florian Frank".freeze]
|
|
11
|
-
s.date = "
|
|
11
|
+
s.date = "2018-01-26"
|
|
12
12
|
s.description = "This library allows you to access configuration files via a simple interface".freeze
|
|
13
13
|
s.email = "flori@ping.de".freeze
|
|
14
14
|
s.extra_rdoc_files = ["README.md".freeze, "lib/complex_config.rb".freeze, "lib/complex_config/config.rb".freeze, "lib/complex_config/encryption.rb".freeze, "lib/complex_config/errors.rb".freeze, "lib/complex_config/plugins.rb".freeze, "lib/complex_config/plugins/enable.rb".freeze, "lib/complex_config/plugins/money.rb".freeze, "lib/complex_config/plugins/uri.rb".freeze, "lib/complex_config/provider.rb".freeze, "lib/complex_config/provider/shortcuts.rb".freeze, "lib/complex_config/proxy.rb".freeze, "lib/complex_config/railtie.rb".freeze, "lib/complex_config/rude.rb".freeze, "lib/complex_config/settings.rb".freeze, "lib/complex_config/shortcuts.rb".freeze, "lib/complex_config/version.rb".freeze]
|
|
15
|
-
s.files = [".gitignore".freeze, ".rspec".freeze, ".travis.yml".freeze, ".utilsrc".freeze, "COPYING".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "TODO.md".freeze, "VERSION".freeze, "complex_config.gemspec".freeze, "config/products.yml".freeze, "lib/complex_config.rb".freeze, "lib/complex_config/config.rb".freeze, "lib/complex_config/encryption.rb".freeze, "lib/complex_config/errors.rb".freeze, "lib/complex_config/plugins.rb".freeze, "lib/complex_config/plugins/enable.rb".freeze, "lib/complex_config/plugins/money.rb".freeze, "lib/complex_config/plugins/uri.rb".freeze, "lib/complex_config/provider.rb".freeze, "lib/complex_config/provider/shortcuts.rb".freeze, "lib/complex_config/proxy.rb".freeze, "lib/complex_config/railtie.rb".freeze, "lib/complex_config/rude.rb".freeze, "lib/complex_config/settings.rb".freeze, "lib/complex_config/shortcuts.rb".freeze, "lib/complex_config/version.rb".freeze, "spec/complex_config/config_spec.rb".freeze, "spec/complex_config/encryption_spec.rb".freeze, "spec/complex_config/plugins_spec.rb".freeze, "spec/complex_config/provider_spec.rb".freeze, "spec/complex_config/settings_spec.rb".freeze, "spec/complex_config/shortcuts_spec.rb".freeze, "spec/config/broken_config.yml".freeze, "spec/config/config.yml".freeze, "spec/config/with-key-file.yml.enc".freeze, "spec/config/with-key-file.yml.key".freeze, "spec/config/
|
|
15
|
+
s.files = [".gitignore".freeze, ".rspec".freeze, ".travis.yml".freeze, ".utilsrc".freeze, "COPYING".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "TODO.md".freeze, "VERSION".freeze, "complex_config.gemspec".freeze, "config/products.yml".freeze, "lib/complex_config.rb".freeze, "lib/complex_config/config.rb".freeze, "lib/complex_config/encryption.rb".freeze, "lib/complex_config/errors.rb".freeze, "lib/complex_config/plugins.rb".freeze, "lib/complex_config/plugins/enable.rb".freeze, "lib/complex_config/plugins/money.rb".freeze, "lib/complex_config/plugins/uri.rb".freeze, "lib/complex_config/provider.rb".freeze, "lib/complex_config/provider/shortcuts.rb".freeze, "lib/complex_config/proxy.rb".freeze, "lib/complex_config/railtie.rb".freeze, "lib/complex_config/rude.rb".freeze, "lib/complex_config/settings.rb".freeze, "lib/complex_config/shortcuts.rb".freeze, "lib/complex_config/version.rb".freeze, "spec/complex_config/config_spec.rb".freeze, "spec/complex_config/encryption_spec.rb".freeze, "spec/complex_config/plugins_spec.rb".freeze, "spec/complex_config/provider_spec.rb".freeze, "spec/complex_config/settings_spec.rb".freeze, "spec/complex_config/shortcuts_spec.rb".freeze, "spec/config/broken_config.yml".freeze, "spec/config/config.yml".freeze, "spec/config/with-key-file.yml.enc".freeze, "spec/config/with-key-file.yml.key".freeze, "spec/config/without-key-file.yml.enc".freeze, "spec/spec_helper.rb".freeze]
|
|
16
16
|
s.homepage = "https://github.com/flori/complex_config".freeze
|
|
17
17
|
s.licenses = ["Apache-2.0".freeze]
|
|
18
18
|
s.rdoc_options = ["--title".freeze, "ComplexConfig -- configuration library".freeze, "--main".freeze, "README.md".freeze]
|
|
19
|
-
s.rubygems_version = "2.6.
|
|
19
|
+
s.rubygems_version = "2.6.14".freeze
|
|
20
20
|
s.summary = "configuration library".freeze
|
|
21
21
|
s.test_files = ["spec/complex_config/config_spec.rb".freeze, "spec/complex_config/encryption_spec.rb".freeze, "spec/complex_config/plugins_spec.rb".freeze, "spec/complex_config/provider_spec.rb".freeze, "spec/complex_config/settings_spec.rb".freeze, "spec/complex_config/shortcuts_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
22
22
|
|
|
@@ -68,7 +68,7 @@ class ComplexConfig::Provider
|
|
|
68
68
|
datas << IO.binread(pathname)
|
|
69
69
|
end
|
|
70
70
|
if enc_pathname = pathname.to_s + '.enc' and
|
|
71
|
-
File.exist?(enc_pathname) and my_key =
|
|
71
|
+
File.exist?(enc_pathname) and my_key = key_as_bytes(pathname)
|
|
72
72
|
then
|
|
73
73
|
text = IO.binread(enc_pathname)
|
|
74
74
|
datas << ComplexConfig::Encryption.new(my_key).decrypt(text)
|
|
@@ -98,39 +98,35 @@ class ComplexConfig::Provider
|
|
|
98
98
|
end
|
|
99
99
|
memoize method: :[]
|
|
100
100
|
|
|
101
|
-
def write_config(name, value, encrypt: false, store_key: false)
|
|
101
|
+
def write_config(name, value: nil, encrypt: false, store_key: false)
|
|
102
|
+
name, value = interpret_name_value(name, value)
|
|
102
103
|
config_pathname = pathname(name).to_s
|
|
103
|
-
key = case encrypt
|
|
104
|
-
when :random
|
|
105
|
-
SecureRandom.random_bytes(16)
|
|
106
|
-
when true
|
|
107
|
-
key(config_pathname)
|
|
108
|
-
when String
|
|
109
|
-
encrypt
|
|
110
|
-
end
|
|
111
|
-
hex_key = nil
|
|
112
|
-
settings = ComplexConfig::Settings[value]
|
|
113
104
|
if encrypt
|
|
114
|
-
key
|
|
115
|
-
|
|
116
|
-
key.size != 16 and raise ComplexConfig::EncryptionKeyInvalid,
|
|
117
|
-
"encryption keys has to be of 16 bytes lenght"
|
|
105
|
+
key = provide_key(config_pathname, encrypt)
|
|
106
|
+
kb = key_to_bytes(key)
|
|
118
107
|
File.secure_write(config_pathname + '.enc') do |out|
|
|
119
|
-
out.write ComplexConfig::Encryption.new(
|
|
108
|
+
out.write ComplexConfig::Encryption.new(kb).encrypt(prepare_output(value))
|
|
120
109
|
end
|
|
121
|
-
hex_key = key.unpack('H*').first
|
|
122
110
|
if store_key
|
|
123
111
|
File.secure_write(config_pathname + '.key') do |out|
|
|
124
|
-
out.write
|
|
112
|
+
out.write key
|
|
125
113
|
end
|
|
126
114
|
end
|
|
115
|
+
key
|
|
127
116
|
else
|
|
128
117
|
File.secure_write(config_pathname) do |out|
|
|
129
|
-
out.puts
|
|
118
|
+
out.puts prepare_output(value)
|
|
130
119
|
end
|
|
120
|
+
true
|
|
131
121
|
end
|
|
122
|
+
ensure
|
|
132
123
|
flush_cache
|
|
133
|
-
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def prepare_output(value)
|
|
127
|
+
value.each_with_object({}) do |(k, v), h|
|
|
128
|
+
h[k.to_s] = v
|
|
129
|
+
end.to_yaml
|
|
134
130
|
end
|
|
135
131
|
|
|
136
132
|
def exist?(name)
|
|
@@ -162,21 +158,62 @@ class ComplexConfig::Provider
|
|
|
162
158
|
attr_writer :env
|
|
163
159
|
|
|
164
160
|
def key(pathname = nil)
|
|
165
|
-
|
|
161
|
+
[
|
|
166
162
|
@key,
|
|
167
163
|
read_key_from_file(pathname),
|
|
168
164
|
ENV['COMPLEX_CONFIG_KEY'],
|
|
169
165
|
ENV['RAILS_MASTER_KEY'],
|
|
170
|
-
].compact[0, 1].map(&:strip)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
166
|
+
].compact[0, 1].map(&:strip).first
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def key_as_bytes(pathname = nil)
|
|
170
|
+
k = key(pathname) or
|
|
171
|
+
raise ComplexConfig::EncryptionKeyInvalid, "encryption key is missing"
|
|
172
|
+
key_to_bytes(k)
|
|
174
173
|
end
|
|
175
174
|
|
|
176
175
|
attr_writer :key
|
|
177
176
|
|
|
178
177
|
private
|
|
179
178
|
|
|
179
|
+
def interpret_name_value(name, value)
|
|
180
|
+
if ComplexConfig::Settings === name
|
|
181
|
+
if value
|
|
182
|
+
name = name.name_prefix
|
|
183
|
+
else
|
|
184
|
+
value = name.to_h
|
|
185
|
+
name = name.name_prefix
|
|
186
|
+
end
|
|
187
|
+
elsif name.respond_to?(:to_sym)
|
|
188
|
+
value = value.to_h
|
|
189
|
+
else
|
|
190
|
+
raise ArgumentError, "name has to be either string/symbol or ComplexConfig::Settings"
|
|
191
|
+
end
|
|
192
|
+
return name, value
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def provide_key(pathname, encrypt)
|
|
196
|
+
key = case encrypt
|
|
197
|
+
when :random
|
|
198
|
+
SecureRandom.hex(16)
|
|
199
|
+
when true
|
|
200
|
+
key(pathname)
|
|
201
|
+
when String
|
|
202
|
+
if encrypt =~ /\A\h{32}\z/
|
|
203
|
+
encrypt
|
|
204
|
+
else
|
|
205
|
+
raise ComplexConfig::EncryptionKeyInvalid,
|
|
206
|
+
"encryption key has wrong format, has to be hex number of length "\
|
|
207
|
+
"32, was #{encrypt.inspect}"
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
key or raise ComplexConfig::EncryptionKeyInvalid, "encryption key is missing"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def key_to_bytes(key)
|
|
214
|
+
[ key ].pack('H*')
|
|
215
|
+
end
|
|
216
|
+
|
|
180
217
|
def read_key_from_file(pathname)
|
|
181
218
|
if pathname
|
|
182
219
|
IO.binread(pathname.to_s + '.key')
|
|
@@ -9,6 +9,8 @@ RSpec.describe ComplexConfig::Provider do
|
|
|
9
9
|
reset_new_config = -> * {
|
|
10
10
|
provider.config_dir = Pathname.new(__FILE__).dirname.dirname + 'config'
|
|
11
11
|
provider.key = nil
|
|
12
|
+
ENV['COMPLEX_CONFIG_KEY'] = nil
|
|
13
|
+
ENV['RAILS_MASTER_KEY'] = nil
|
|
12
14
|
FileUtils.rm_f(provider.config_dir + 'new_config.yml')
|
|
13
15
|
FileUtils.rm_f(provider.config_dir + 'new_config.yml.enc')
|
|
14
16
|
FileUtils.rm_f(provider.config_dir + 'new_config.yml.key')
|
|
@@ -112,14 +114,14 @@ RSpec.describe ComplexConfig::Provider do
|
|
|
112
114
|
end
|
|
113
115
|
|
|
114
116
|
it 'can be written' do
|
|
115
|
-
provider.write_config('new_config', config)
|
|
117
|
+
provider.write_config('new_config', value: config)
|
|
116
118
|
expect(provider.config(asset('new_config.yml'))).to eq config
|
|
117
119
|
end
|
|
118
120
|
|
|
119
121
|
it 'can be changed and written' do
|
|
120
122
|
provider.deep_freeze = false
|
|
121
123
|
config.development.config.baz = 'something else'
|
|
122
|
-
provider.write_config('new_config', config)
|
|
124
|
+
provider.write_config('new_config', value: config)
|
|
123
125
|
expect(provider.config(asset('new_config.yml')).development.config.baz).to eq 'something else'
|
|
124
126
|
end
|
|
125
127
|
end
|
|
@@ -141,15 +143,12 @@ RSpec.describe ComplexConfig::Provider do
|
|
|
141
143
|
it 'can read when key is in ENV var' do
|
|
142
144
|
ENV['RAILS_MASTER_KEY'] = key
|
|
143
145
|
expect(provider['without-key-file'].development.foo.bar).to eq 'baz'
|
|
146
|
+
ENV['RAILS_MASTER_KEY'] = nil
|
|
144
147
|
end
|
|
145
148
|
|
|
146
149
|
it 'can read when key is stored in file' do
|
|
147
150
|
expect(provider['with-key-file'].development.foo.bar).to eq 'baz'
|
|
148
151
|
end
|
|
149
|
-
|
|
150
|
-
it 'can read when key is obtained by calling shell script' do
|
|
151
|
-
expect(provider['with-shell-script'].development.foo.bar).to eq 'baz'
|
|
152
|
-
end
|
|
153
152
|
end
|
|
154
153
|
|
|
155
154
|
context 'writing encrypted configurations' do
|
|
@@ -163,31 +162,57 @@ RSpec.describe ComplexConfig::Provider do
|
|
|
163
162
|
end
|
|
164
163
|
|
|
165
164
|
it 'can be written with random key' do
|
|
166
|
-
key = provider.write_config('new_config', config, encrypt: :random, store_key: false)
|
|
165
|
+
key = provider.write_config('new_config', value: config, encrypt: :random, store_key: false)
|
|
167
166
|
provider.key = key
|
|
168
167
|
expect(provider.config(asset('new_config.yml'))).to eq config
|
|
169
168
|
end
|
|
170
169
|
|
|
171
170
|
it 'can be written with random key and store key' do
|
|
172
|
-
provider.write_config('new_config', config, encrypt: :random, store_key: true)
|
|
171
|
+
provider.write_config('new_config', value: config, encrypt: :random, store_key: true)
|
|
173
172
|
expect(provider.config(asset('new_config.yml'))).to eq config
|
|
174
173
|
end
|
|
175
174
|
|
|
176
175
|
it 'can be written with passed key' do
|
|
177
|
-
|
|
176
|
+
key = SecureRandom.hex(16)
|
|
177
|
+
provider.write_config('new_config', value: config, encrypt: key)
|
|
178
|
+
provider.key = key
|
|
178
179
|
expect(provider.config(asset('new_config.yml'))).to eq config
|
|
179
180
|
end
|
|
180
181
|
|
|
181
182
|
it 'can be written with configured key' do
|
|
182
|
-
provider.write_config('new_config', config)
|
|
183
|
+
provider.write_config('new_config', value: config)
|
|
184
|
+
expect(provider.config(asset('new_config.yml'))).to eq config
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it 'can be written with COMPLEX_CONFIG_KEY key' do
|
|
188
|
+
ENV['COMPLEX_CONFIG_KEY'] = SecureRandom.hex(16)
|
|
189
|
+
k = provider.write_config('new_config', value: config, encrypt: true)
|
|
190
|
+
expect(k).to eq ENV['COMPLEX_CONFIG_KEY']
|
|
191
|
+
expect(provider.config(asset('new_config.yml'))).to eq config
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'can be written with RAILS_MASTER_KEY key' do
|
|
195
|
+
ENV['RAILS_MASTER_KEY'] = SecureRandom.hex(16)
|
|
196
|
+
k = provider.write_config('new_config', value: config, encrypt: true)
|
|
197
|
+
expect(k).to eq ENV['RAILS_MASTER_KEY']
|
|
183
198
|
expect(provider.config(asset('new_config.yml'))).to eq config
|
|
184
199
|
end
|
|
185
200
|
|
|
186
201
|
it 'can be changed and written' do
|
|
187
202
|
provider.deep_freeze = false
|
|
203
|
+
expect(provider.config(asset('config.yml')).development.config.baz).to eq 'something'
|
|
188
204
|
config.development.config.baz = 'something else'
|
|
189
|
-
provider.write_config('new_config', config)
|
|
205
|
+
provider.write_config('new_config', value: config)
|
|
190
206
|
expect(provider.config(asset('new_config.yml')).development.config.baz).to eq 'something else'
|
|
207
|
+
#
|
|
208
|
+
new_config = provider.config(asset('new_config.yml'), :new_config)
|
|
209
|
+
new_config.development.config.baz = 'something else else'
|
|
210
|
+
provider.write_config new_config
|
|
211
|
+
expect(provider.config(asset('new_config.yml')).development.config.baz).to eq 'something else else'
|
|
212
|
+
#
|
|
213
|
+
new_config = provider.config(asset('new_config.yml'), :new_config)
|
|
214
|
+
provider.write_config(new_config, value: { development: { config: { baz: 'even more else' } } })
|
|
215
|
+
#expect(provider.config(asset('new_config.yml')).development.config.baz).to eq 'something else else'
|
|
191
216
|
end
|
|
192
217
|
end
|
|
193
218
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: complex_config
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-01-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: gem_hadar
|
|
@@ -189,7 +189,6 @@ files:
|
|
|
189
189
|
- spec/config/config.yml
|
|
190
190
|
- spec/config/with-key-file.yml.enc
|
|
191
191
|
- spec/config/with-key-file.yml.key
|
|
192
|
-
- spec/config/with-shell-script.yml.enc
|
|
193
192
|
- spec/config/without-key-file.yml.enc
|
|
194
193
|
- spec/spec_helper.rb
|
|
195
194
|
homepage: https://github.com/flori/complex_config
|
|
@@ -216,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
216
215
|
version: '0'
|
|
217
216
|
requirements: []
|
|
218
217
|
rubyforge_project:
|
|
219
|
-
rubygems_version: 2.6.
|
|
218
|
+
rubygems_version: 2.6.14
|
|
220
219
|
signing_key:
|
|
221
220
|
specification_version: 4
|
|
222
221
|
summary: configuration library
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0MKZ0eU56L2MCkL143wST6kchDW/hnyGq7xm3O2NUMY1xa0PoEnZutzR3+LVGu/eWtk=--zhIiqrnKQu422P/V--p0v54ziCv+LBHmg3GYk16Q==
|