super_settings 0.0.0.rc1 → 0.0.1.rc1
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/CHANGELOG.md +2 -1
- data/README.md +65 -62
- data/VERSION +1 -1
- data/config/routes.rb +3 -1
- data/lib/super_settings/application/api.js +8 -1
- data/lib/super_settings/application/helper.rb +2 -1
- data/lib/super_settings/application/index.html.erb +3 -3
- data/lib/super_settings/application/scripts.js +50 -12
- data/lib/super_settings/application/styles.css +5 -0
- data/lib/super_settings/application.rb +3 -1
- data/lib/super_settings/coerce.rb +6 -2
- data/lib/super_settings/configuration.rb +34 -15
- data/lib/super_settings/engine.rb +0 -5
- data/lib/super_settings/history_item.rb +10 -2
- data/lib/super_settings/local_cache.rb +14 -3
- data/lib/super_settings/{rack_middleware.rb → rack_application.rb} +66 -36
- data/lib/super_settings/rest_api.rb +98 -97
- data/lib/super_settings/setting.rb +96 -73
- data/lib/super_settings/storage/active_record_storage.rb +28 -10
- data/lib/super_settings/storage/http_storage.rb +7 -17
- data/lib/super_settings/storage/redis_storage.rb +20 -33
- data/lib/super_settings/storage/test_storage.rb +3 -10
- data/lib/super_settings/storage.rb +49 -24
- data/lib/super_settings.rb +33 -20
- data/super_settings.gemspec +1 -3
- metadata +4 -20
- data/lib/super_settings/encryption.rb +0 -76
- data/lib/tasks/super_settings.rake +0 -9
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
require "json"
|
4
4
|
|
5
|
-
# :nocov:
|
6
5
|
module SuperSettings
|
7
6
|
module Storage
|
8
7
|
# Implementation of the SuperSettings::Storage model for running unit tests.
|
9
8
|
class TestStorage
|
9
|
+
# :nocov:
|
10
|
+
|
10
11
|
include Storage
|
11
12
|
|
12
13
|
attr_reader :key, :raw_value, :description, :value_type, :updated_at, :created_at
|
@@ -127,14 +128,6 @@ module SuperSettings
|
|
127
128
|
!!(defined?(@persisted) && @persisted)
|
128
129
|
end
|
129
130
|
|
130
|
-
protected
|
131
|
-
|
132
|
-
def redact_history!
|
133
|
-
self.class.history(key).each do |item|
|
134
|
-
item[:value] = nil
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
131
|
private
|
139
132
|
|
140
133
|
def set_persisted!
|
@@ -153,6 +146,6 @@ module SuperSettings
|
|
153
146
|
}
|
154
147
|
end
|
155
148
|
end
|
149
|
+
# :nocov:
|
156
150
|
end
|
157
151
|
end
|
158
|
-
# :nocov:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module SuperSettings
|
4
4
|
# Abstraction over how a setting is stored and retrieved from the storage engine. Models
|
5
|
-
# must implement the methods module in this module that raise
|
5
|
+
# must implement the methods module in this module that raise NotImplementedError.
|
6
6
|
module Storage
|
7
7
|
class RecordInvalid < StandardError
|
8
8
|
end
|
@@ -14,6 +14,7 @@ module SuperSettings
|
|
14
14
|
|
15
15
|
module ClassMethods
|
16
16
|
# Storage classes must implent this method to return all settings included deleted ones.
|
17
|
+
#
|
17
18
|
# @return [Array<SuperSetting::Setting::Storage>]
|
18
19
|
def all
|
19
20
|
# :nocov:
|
@@ -22,6 +23,7 @@ module SuperSettings
|
|
22
23
|
end
|
23
24
|
|
24
25
|
# Return all non-deleted settings.
|
26
|
+
#
|
25
27
|
# @return [Array<SuperSetting::Setting::Storage>]
|
26
28
|
def active
|
27
29
|
all.reject(&:deleted?)
|
@@ -29,6 +31,7 @@ module SuperSettings
|
|
29
31
|
|
30
32
|
# Storage classes must implement this method to return all settings updates since the
|
31
33
|
# specified timestamp.
|
34
|
+
#
|
32
35
|
# @return [Array<SuperSetting::Setting::Storage>]
|
33
36
|
def updated_since(timestamp)
|
34
37
|
# :nocov:
|
@@ -37,6 +40,7 @@ module SuperSettings
|
|
37
40
|
end
|
38
41
|
|
39
42
|
# Storage classes must implement this method to return a settings by it's key.
|
43
|
+
#
|
40
44
|
# @return [SuperSetting::Setting::Storage]
|
41
45
|
def find_by_key(key)
|
42
46
|
# :nocov:
|
@@ -46,6 +50,7 @@ module SuperSettings
|
|
46
50
|
|
47
51
|
# Storage classes must implement this method to return most recent time that any
|
48
52
|
# setting was updated.
|
53
|
+
#
|
49
54
|
# @return [Time]
|
50
55
|
def last_updated_at
|
51
56
|
# :nocov:
|
@@ -54,18 +59,24 @@ module SuperSettings
|
|
54
59
|
end
|
55
60
|
|
56
61
|
# Implementing classes can override this method to setup a thread safe connection within a block.
|
62
|
+
#
|
63
|
+
# @return [void]
|
57
64
|
def with_connection(&block)
|
58
65
|
yield
|
59
66
|
end
|
60
67
|
|
61
68
|
# Implementing classes can override this method to wrap an operation in an atomic transaction.
|
69
|
+
#
|
70
|
+
# @return [void]
|
62
71
|
def transaction(&block)
|
63
72
|
yield
|
64
73
|
end
|
65
74
|
|
66
|
-
#
|
75
|
+
# Return true if it's safe to load setting asynchronously in a background thread.
|
76
|
+
#
|
77
|
+
# @return [Boolean]
|
67
78
|
def load_asynchronous?
|
68
|
-
!!(defined?(@load_asynchronous) && !@load_asynchronous.nil? ? @load_asynchronous : default_load_asynchronous?)
|
79
|
+
!!((defined?(@load_asynchronous) && !@load_asynchronous.nil?) ? @load_asynchronous : default_load_asynchronous?)
|
69
80
|
end
|
70
81
|
|
71
82
|
# Set to true to force loading setting asynchronously in a background thread.
|
@@ -80,7 +91,9 @@ module SuperSettings
|
|
80
91
|
end
|
81
92
|
end
|
82
93
|
|
83
|
-
#
|
94
|
+
# The key for the setting
|
95
|
+
#
|
96
|
+
# @return [String]
|
84
97
|
def key
|
85
98
|
# :nocov:
|
86
99
|
raise NotImplementedError
|
@@ -88,6 +101,7 @@ module SuperSettings
|
|
88
101
|
end
|
89
102
|
|
90
103
|
# Set the key for the setting.
|
104
|
+
#
|
91
105
|
# @param val [String]
|
92
106
|
# @return [void]
|
93
107
|
def key=(val)
|
@@ -96,7 +110,9 @@ module SuperSettings
|
|
96
110
|
# :nocov:
|
97
111
|
end
|
98
112
|
|
99
|
-
#
|
113
|
+
# The raw value for the setting before it is type cast.
|
114
|
+
#
|
115
|
+
# @return [String]
|
100
116
|
def raw_value
|
101
117
|
# :nocov:
|
102
118
|
raise NotImplementedError
|
@@ -104,6 +120,7 @@ module SuperSettings
|
|
104
120
|
end
|
105
121
|
|
106
122
|
# Set the raw value for the setting.
|
123
|
+
#
|
107
124
|
# @param val [String]
|
108
125
|
# @return [void]
|
109
126
|
def raw_value=(val)
|
@@ -112,7 +129,9 @@ module SuperSettings
|
|
112
129
|
# :nocov:
|
113
130
|
end
|
114
131
|
|
115
|
-
#
|
132
|
+
# The value type for the setting.
|
133
|
+
#
|
134
|
+
# @return [String]
|
116
135
|
def value_type
|
117
136
|
# :nocov:
|
118
137
|
raise NotImplementedError
|
@@ -120,7 +139,8 @@ module SuperSettings
|
|
120
139
|
end
|
121
140
|
|
122
141
|
# Set the value type for the setting.
|
123
|
-
#
|
142
|
+
#
|
143
|
+
# @param val [String] one of string, integer, float, boolean, datetime, or array
|
124
144
|
# @return [void]
|
125
145
|
def value_type=(val)
|
126
146
|
# :nocov:
|
@@ -128,7 +148,8 @@ module SuperSettings
|
|
128
148
|
# :nocov:
|
129
149
|
end
|
130
150
|
|
131
|
-
#
|
151
|
+
# The description for the setting.
|
152
|
+
# @return [String]
|
132
153
|
def description
|
133
154
|
# :nocov:
|
134
155
|
raise NotImplementedError
|
@@ -136,6 +157,7 @@ module SuperSettings
|
|
136
157
|
end
|
137
158
|
|
138
159
|
# Set the description for the setting.
|
160
|
+
|
139
161
|
# @param val [String]
|
140
162
|
# @return [void]
|
141
163
|
def description=(val)
|
@@ -144,7 +166,9 @@ module SuperSettings
|
|
144
166
|
# :nocov:
|
145
167
|
end
|
146
168
|
|
147
|
-
#
|
169
|
+
# Return true if the setting marked as deleted.
|
170
|
+
#
|
171
|
+
# @return [Boolean]
|
148
172
|
def deleted?
|
149
173
|
# :nocov:
|
150
174
|
raise NotImplementedError
|
@@ -153,6 +177,7 @@ module SuperSettings
|
|
153
177
|
|
154
178
|
# Set the deleted flag for the setting. Settings should not actually be deleted since
|
155
179
|
# the record is needed to keep the local cache up to date.
|
180
|
+
#
|
156
181
|
# @param val [Boolean]
|
157
182
|
# @return [void]
|
158
183
|
def deleted=(val)
|
@@ -161,7 +186,9 @@ module SuperSettings
|
|
161
186
|
# :nocov:
|
162
187
|
end
|
163
188
|
|
164
|
-
#
|
189
|
+
# Return the time the setting was last updated
|
190
|
+
#
|
191
|
+
# @return [Time]
|
165
192
|
def updated_at
|
166
193
|
# :nocov:
|
167
194
|
raise NotImplementedError
|
@@ -169,6 +196,7 @@ module SuperSettings
|
|
169
196
|
end
|
170
197
|
|
171
198
|
# Set the last updated time for the setting.
|
199
|
+
#
|
172
200
|
# @param val [Time]
|
173
201
|
# @return [void]
|
174
202
|
def updated_at=(val)
|
@@ -177,7 +205,9 @@ module SuperSettings
|
|
177
205
|
# :nocov:
|
178
206
|
end
|
179
207
|
|
180
|
-
#
|
208
|
+
# Return the time the setting was created.
|
209
|
+
#
|
210
|
+
# @return [Time]
|
181
211
|
def created_at
|
182
212
|
# :nocov:
|
183
213
|
raise NotImplementedError
|
@@ -185,6 +215,7 @@ module SuperSettings
|
|
185
215
|
end
|
186
216
|
|
187
217
|
# Set the created time for the setting.
|
218
|
+
#
|
188
219
|
# @param val [Time]
|
189
220
|
# @return [void]
|
190
221
|
def created_at=(val)
|
@@ -195,6 +226,7 @@ module SuperSettings
|
|
195
226
|
|
196
227
|
# Return array of history items reflecting changes made to the setting over time. Items
|
197
228
|
# should be returned in reverse chronological order so that the most recent changes are first.
|
229
|
+
#
|
198
230
|
# @return [Array<SuperSettings::History>]
|
199
231
|
def history(limit: nil, offset: 0)
|
200
232
|
# :nocov:
|
@@ -202,7 +234,9 @@ module SuperSettings
|
|
202
234
|
# :nocov:
|
203
235
|
end
|
204
236
|
|
205
|
-
# Create a history item for the setting
|
237
|
+
# Create a history item for the setting.
|
238
|
+
#
|
239
|
+
# @return [void]
|
206
240
|
def create_history(changed_by:, created_at:, value: nil, deleted: false)
|
207
241
|
# :nocov:
|
208
242
|
raise NotImplementedError
|
@@ -210,6 +244,7 @@ module SuperSettings
|
|
210
244
|
end
|
211
245
|
|
212
246
|
# Persist the record to storage.
|
247
|
+
#
|
213
248
|
# @return [void]
|
214
249
|
def save!
|
215
250
|
# :nocov:
|
@@ -217,7 +252,8 @@ module SuperSettings
|
|
217
252
|
# :nocov:
|
218
253
|
end
|
219
254
|
|
220
|
-
#
|
255
|
+
# Return true if the record has been stored.
|
256
|
+
# @return [Boolean]
|
221
257
|
def persisted?
|
222
258
|
# :nocov:
|
223
259
|
raise NotImplementedError
|
@@ -227,17 +263,6 @@ module SuperSettings
|
|
227
263
|
def ==(other)
|
228
264
|
other.is_a?(self.class) && other.key == key
|
229
265
|
end
|
230
|
-
|
231
|
-
protected
|
232
|
-
|
233
|
-
# Remove the value stored on history records if the setting is changed to a secret since
|
234
|
-
# these are not stored encrypted in the database. Implementing classes must redefine this
|
235
|
-
# method.
|
236
|
-
def redact_history!
|
237
|
-
# :nocov:
|
238
|
-
raise NotImplementedError
|
239
|
-
# :nocov:
|
240
|
-
end
|
241
266
|
end
|
242
267
|
end
|
243
268
|
|
data/lib/super_settings.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "secret_keys"
|
4
|
-
|
5
3
|
require_relative "super_settings/application"
|
6
4
|
require_relative "super_settings/coerce"
|
7
5
|
require_relative "super_settings/configuration"
|
8
6
|
require_relative "super_settings/local_cache"
|
9
|
-
require_relative "super_settings/encryption"
|
10
7
|
require_relative "super_settings/rest_api"
|
11
|
-
require_relative "super_settings/
|
8
|
+
require_relative "super_settings/rack_application"
|
12
9
|
require_relative "super_settings/controller_actions"
|
13
10
|
require_relative "super_settings/attributes"
|
14
11
|
require_relative "super_settings/setting"
|
@@ -65,6 +62,15 @@ module SuperSettings
|
|
65
62
|
Coerce.boolean(val.nil? ? default : val)
|
66
63
|
end
|
67
64
|
|
65
|
+
# Return true if a setting cast as a boolean evaluates to false.
|
66
|
+
#
|
67
|
+
# @param key [String, Symbol]
|
68
|
+
# @param default [Boolean] value to return if the setting value is nil
|
69
|
+
# @return [Boolean]
|
70
|
+
def disabled?(key, default = true)
|
71
|
+
!enabled?(key, !default)
|
72
|
+
end
|
73
|
+
|
68
74
|
# Get a setting value cast to a Time.
|
69
75
|
#
|
70
76
|
# @param key [String, Symbol]
|
@@ -91,13 +97,15 @@ module SuperSettings
|
|
91
97
|
# store into a structured data store. It uses a delimiter to define how keys are nested which
|
92
98
|
# defaults to a dot.
|
93
99
|
#
|
94
|
-
# If, for example, you have three keys in you settings
|
100
|
+
# If, for example, you have three keys in you settings +A.B1.C1 = 1+, +A.B1.C2 = 2+, and +A.B2.C3 = 3+, the
|
95
101
|
# nested structure will be:
|
96
102
|
#
|
97
|
-
#
|
103
|
+
# +{"A" => {"B1" => {"C1" => 1, "C2" => 2}, "B2" => {"C3" => 3}}}+
|
104
|
+
#
|
105
|
+
# This whole hash would be returned if you called +hash+ without any key. If you called it with the
|
106
|
+
# key "A.B1", it would return
|
98
107
|
#
|
99
|
-
#
|
100
|
-
# key "A.B1", it would return `{"C1" => 1, "C2" => 2}`.
|
108
|
+
# +{"C1" => 1, "C2" => 2}+
|
101
109
|
#
|
102
110
|
# @param key [String, Symbol] the prefix patter to fetch keys for; default to returning all settings
|
103
111
|
# @param default [Hash] value to return if the setting value is nil
|
@@ -146,6 +154,8 @@ module SuperSettings
|
|
146
154
|
end
|
147
155
|
|
148
156
|
# Load the settings from the database into the in memory cache.
|
157
|
+
#
|
158
|
+
# @return [void]
|
149
159
|
def load_settings
|
150
160
|
local_cache.load_settings
|
151
161
|
local_cache.wait_for_load
|
@@ -153,6 +163,8 @@ module SuperSettings
|
|
153
163
|
end
|
154
164
|
|
155
165
|
# Force refresh the settings in the in memory cache to be in sync with the database.
|
166
|
+
#
|
167
|
+
# @return [void]
|
156
168
|
def refresh_settings
|
157
169
|
local_cache.refresh
|
158
170
|
nil
|
@@ -160,6 +172,8 @@ module SuperSettings
|
|
160
172
|
|
161
173
|
# Reset the in memory cache. The cache will be automatically reloaded the next time
|
162
174
|
# you access a setting.
|
175
|
+
#
|
176
|
+
# @return [void]
|
163
177
|
def clear_cache
|
164
178
|
local_cache.reset
|
165
179
|
nil
|
@@ -176,7 +190,8 @@ module SuperSettings
|
|
176
190
|
# object. You should use this method to configure the gem from an Rails initializer since
|
177
191
|
# it will handle ensuring all the appropriate frameworks are loaded first.
|
178
192
|
#
|
179
|
-
# yieldparam config [SuperSettings::Configuration]
|
193
|
+
# @yieldparam config [SuperSettings::Configuration]
|
194
|
+
# @return [void]
|
180
195
|
def configure(&block)
|
181
196
|
Configuration.instance.defer(&block)
|
182
197
|
unless defined?(Rails::Engine)
|
@@ -188,21 +203,19 @@ module SuperSettings
|
|
188
203
|
# This setting aids in performance since it throttles the number of times the database is queried
|
189
204
|
# for changes. However, changes made to the settings in the databae will take up to the number of
|
190
205
|
# seconds in the refresh interval to be updated in the cache.
|
206
|
+
#
|
207
|
+
# @return [void]
|
191
208
|
def refresh_interval=(value)
|
192
209
|
local_cache.refresh_interval = value
|
193
210
|
end
|
194
211
|
|
195
|
-
#
|
196
|
-
#
|
197
|
-
|
198
|
-
|
199
|
-
#
|
200
|
-
#
|
201
|
-
|
202
|
-
def secret=(value)
|
203
|
-
Encryption.secret = value
|
204
|
-
load_settings if loaded?
|
205
|
-
end
|
212
|
+
# URL for authenticating access to the application. This would normally be some kind of
|
213
|
+
# login page. Browsers will be redirected here if they are denied access to the web UI.
|
214
|
+
attr_accessor :authentication_url
|
215
|
+
|
216
|
+
# Javascript to inject into the settings application HTML page. This can be used, for example,
|
217
|
+
# to set authorization credentials stored client side to access the settings API.
|
218
|
+
attr_accessor :web_ui_javascript
|
206
219
|
|
207
220
|
private
|
208
221
|
|
data/super_settings.gemspec
CHANGED
@@ -16,10 +16,10 @@ Gem::Specification.new do |spec|
|
|
16
16
|
Gemfile
|
17
17
|
Gemfile.lock
|
18
18
|
Rakefile
|
19
|
+
assets/
|
19
20
|
bin/
|
20
21
|
gemfiles/
|
21
22
|
spec/
|
22
|
-
web_ui.png
|
23
23
|
]
|
24
24
|
spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
|
25
25
|
`git ls-files -z`.split("\x0").reject { |f| ignore_files.any? { |path| f.start_with?(path) } }
|
@@ -27,8 +27,6 @@ Gem::Specification.new do |spec|
|
|
27
27
|
|
28
28
|
spec.require_paths = ["lib"]
|
29
29
|
|
30
|
-
spec.add_dependency "secret_keys", ">= 1.0"
|
31
|
-
|
32
30
|
spec.add_development_dependency "bundler"
|
33
31
|
|
34
32
|
spec.required_ruby_version = ">= 2.5"
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: super_settings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Durand
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: secret_keys
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,11 +57,10 @@ files:
|
|
71
57
|
- lib/super_settings/coerce.rb
|
72
58
|
- lib/super_settings/configuration.rb
|
73
59
|
- lib/super_settings/controller_actions.rb
|
74
|
-
- lib/super_settings/encryption.rb
|
75
60
|
- lib/super_settings/engine.rb
|
76
61
|
- lib/super_settings/history_item.rb
|
77
62
|
- lib/super_settings/local_cache.rb
|
78
|
-
- lib/super_settings/
|
63
|
+
- lib/super_settings/rack_application.rb
|
79
64
|
- lib/super_settings/rest_api.rb
|
80
65
|
- lib/super_settings/setting.rb
|
81
66
|
- lib/super_settings/storage.rb
|
@@ -84,7 +69,6 @@ files:
|
|
84
69
|
- lib/super_settings/storage/redis_storage.rb
|
85
70
|
- lib/super_settings/storage/test_storage.rb
|
86
71
|
- lib/super_settings/version.rb
|
87
|
-
- lib/tasks/super_settings.rake
|
88
72
|
- super_settings.gemspec
|
89
73
|
homepage: https://github.com/bdurand/super_settings
|
90
74
|
licenses:
|
@@ -105,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
89
|
- !ruby/object:Gem::Version
|
106
90
|
version: 1.3.1
|
107
91
|
requirements: []
|
108
|
-
rubygems_version: 3.
|
92
|
+
rubygems_version: 3.4.5
|
109
93
|
signing_key:
|
110
94
|
specification_version: 4
|
111
95
|
summary: Fast access runtime settings for a Rails application with an included UI
|
@@ -1,76 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SuperSettings
|
4
|
-
module Encryption
|
5
|
-
SALT = "0c54a781"
|
6
|
-
private_constant :SALT
|
7
|
-
|
8
|
-
# Error thrown when the secret is invalid
|
9
|
-
class InvalidSecretError < StandardError
|
10
|
-
def initialize
|
11
|
-
super("Cannot decrypt. Invalid secret provided.")
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class << self
|
16
|
-
# Set the secret key used for encrypting secret values. If this is not set,
|
17
|
-
# the value will be loaded from the `SUPER_SETTINGS_SECRET` environment
|
18
|
-
# variable. If that value is not set, arguments will not be encrypted.
|
19
|
-
#
|
20
|
-
# You can set multiple secrets by passing an array if you need to roll your secrets.
|
21
|
-
# The left most value in the array will be used as the encryption secret, but
|
22
|
-
# all the values will be tried when decrypting. That way if you have existing keys
|
23
|
-
# that were encrypted with a different secret, you can still make it available
|
24
|
-
# when decrypting. If you are using the environment variable, separate the keys
|
25
|
-
# with spaces.
|
26
|
-
#
|
27
|
-
# @param value [String] One or more secrets to use for encrypting arguments.
|
28
|
-
# @return [void]
|
29
|
-
def secret=(value)
|
30
|
-
@encryptors = make_encryptors(value)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Encrypt a value for use with secret settings.
|
34
|
-
# @api private
|
35
|
-
def encrypt(value)
|
36
|
-
return nil if Coerce.blank?(value)
|
37
|
-
encryptor = encryptors.first
|
38
|
-
return value if encryptor.nil?
|
39
|
-
encryptor.encrypt(value)
|
40
|
-
end
|
41
|
-
|
42
|
-
# Decrypt a value for use with secret settings.
|
43
|
-
# @api private
|
44
|
-
def decrypt(value)
|
45
|
-
return nil if Coerce.blank?(value)
|
46
|
-
return value if encryptors.empty? || encryptors == [nil]
|
47
|
-
encryptors.each do |encryptor|
|
48
|
-
begin
|
49
|
-
return encryptor.decrypt(value) if encryptor
|
50
|
-
rescue OpenSSL::Cipher::CipherError
|
51
|
-
# Not the right key, try the next one
|
52
|
-
end
|
53
|
-
end
|
54
|
-
raise InvalidSecretError
|
55
|
-
end
|
56
|
-
|
57
|
-
# @return [Boolean] true if the value is encrypted in the storage engine.
|
58
|
-
def encrypted?(value)
|
59
|
-
SecretKeys::Encryptor.encrypted?(value)
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def encryptors
|
65
|
-
if !defined?(@encryptors) || @encryptors.empty?
|
66
|
-
@encryptors = make_encryptors(ENV["SUPER_SETTINGS_SECRET"].to_s.split)
|
67
|
-
end
|
68
|
-
@encryptors
|
69
|
-
end
|
70
|
-
|
71
|
-
def make_encryptors(secrets)
|
72
|
-
Array(secrets).map { |val| val.nil? ? nil : SecretKeys::Encryptor.from_password(val, SALT) }
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|