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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 860f5c79218ff3f9dc9c479f53522895d5eb9606
4
- data.tar.gz: 9cc6fad757632f00543711857740c1831745ed25
3
+ metadata.gz: 9d1f7d933962f507ac718b852309d72585130723
4
+ data.tar.gz: 91ec39308815be851342140df5a4c3f7618e2ab8
5
5
  SHA512:
6
- metadata.gz: 26c3c653a850a1de3f43d4f04ed8d5f466e1c3cc1fa738dae837715b778da2e94454617ef0b9ff74231eed03d3960062f817ebdad47a26a75fc0a350f45dbb74
7
- data.tar.gz: e8a4606df8009be3e3140981329db9bac1bc69d8d6afca2af0d55d3f5fbae24931b702d0328417f167dc1ea24feeccaf16b6f620246428069bd7ddc9f219793c
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.12.1
1
+ 0.13.0
@@ -1,22 +1,22 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: complex_config 0.12.1 ruby lib
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.12.1"
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 = "2017-11-17"
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/with-shell-script.yml.enc".freeze, "spec/config/without-key-file.yml.enc".freeze, "spec/spec_helper.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/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.13".freeze
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 = key(pathname)
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 or raise ComplexConfig::EncryptionKeyInvalid,
115
- "encryption key is missing"
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(key).encrypt(settings.to_yaml)
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 hex_key
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 settings.to_yaml
118
+ out.puts prepare_output(value)
130
119
  end
120
+ true
131
121
  end
122
+ ensure
132
123
  flush_cache
133
- hex_key
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
- key = [
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
- unless key.empty?
172
- key.pack('H*')
173
- end
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')
@@ -1,6 +1,6 @@
1
1
  module ComplexConfig
2
2
  # ComplexConfig version
3
- VERSION = '0.12.1'
3
+ VERSION = '0.13.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -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
- provider.write_config('new_config', config)
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.12.1
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: 2017-11-17 00:00:00.000000000 Z
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.13
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==