Bug #34573 » 34573.patch
app/models/setting.rb | ||
---|---|---|
def value=(v)
|
||
v = v.to_yaml unless v.nil?
|
||
# the has_attribute is for enabling DB migrations on older versions
|
||
if has_attribute?(:encrypted) && encrypted
|
||
if setting_definition&.encrypted?
|
||
# Don't re-write the attribute if the current encrypted value is identical to the new one
|
||
current_value = self[:value]
|
||
unless is_decryptable?(current_value) && decrypt_field(current_value) == v
|
||
... | ... | |
readonly! if !new_record? && has_readonly_value?
|
||
end
|
||
def refresh_registry_value
|
||
def setting_definition
|
||
return unless Foreman.settings.ready?
|
||
Foreman.settings.find(name)&.tap do |definition|
|
||
Foreman.settings.find(name)
|
||
end
|
||
def refresh_registry_value
|
||
setting_definition&.tap do |definition|
|
||
definition.updated_at = updated_at
|
||
definition.value_from_db = value
|
||
end
|
test/models/setting_test.rb | ||
---|---|---|
end
|
||
test "encrypted value is saved encrypted when created" do
|
||
setting = Setting.create(:name => "foo", :value => 5, :default => 5, :description => "test foo", :encrypted => true)
|
||
setting.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
||
setting.value = "123456"
|
||
Setting.any_instance.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
||
setting = Foreman.settings.set_user_value('root_pass', '123456')
|
||
as_admin do
|
||
assert setting.save
|
||
end
|
||
... | ... | |
end
|
||
test "#value= with previously unencrypted value is encrypted when set" do
|
||
setting = Setting.create(name: 'encrypted', value: 'first', default: 'test', description: 'Test', encrypted: false)
|
||
setting.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
||
setting.encrypted = true
|
||
setting.value = 'new'
|
||
Setting['foreman_url'] = 'http://unencrypted-foreman.example.net'
|
||
Setting.any_instance.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
||
Foreman.settings.find('foreman_url').encrypted = true
|
||
setting = Foreman.settings.set_user_value('foreman_url', 'http://new.example.net')
|
||
assert_difference 'setting.audits.count' do
|
||
as_admin { setting.save! }
|
||
end
|
||
assert_includes setting.read_attribute(:value), EncryptValue::ENCRYPTION_PREFIX
|
||
assert_equal 'new', setting.value
|
||
assert_equal 'http://new.example.net', setting.value
|
||
end
|
||
test "update an encrypted value should saved encrypted in db with audit, and decrypted while reading" do
|
||
setting = settings(:attributes63)
|
||
setting.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
||
setting.value = '123456'
|
||
Setting['foreman_url'] = 'http://unencrypted-foreman.example.net'
|
||
Setting.any_instance.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
||
Foreman.settings.find('foreman_url').encrypted = true
|
||
setting = Foreman.settings.set_user_value('foreman_url', 'http://new.example.net')
|
||
assert_difference 'setting.audits.count' do
|
||
as_admin { assert setting.save }
|
||
end
|
||
... | ... | |
end
|
||
test "#value= with unchanged value on encrypted setting does not modify DB or create audit" do
|
||
setting = Setting.create(name: 'encrypted', value: 'first', default: 'test', description: 'Test', encrypted: true)
|
||
Setting['root_pass'] = 'somepass'
|
||
setting = Setting.find_by(name: 'root_pass')
|
||
setting.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
||
setting.value = 'new'
|
||
as_admin { setting.save! }
|
||
db_value = setting.read_attribute(:value)
|
||
assert_includes db_value, EncryptValue::ENCRYPTION_PREFIX
|
||
assert_no_difference 'setting.audits.count' do
|
||
setting.value = 'new'
|
||
setting.value = 'somepass'
|
||
setting.save!
|
||
assert_equal db_value, setting.read_attribute(:value)
|
||
end
|
||
assert_equal db_value, setting.read_attribute(:value)
|
||
end
|
||
test 'proxy the value get to the registry' do
|
test/unit/setting_registry_test.rb | ||
---|---|---|
end
|
||
describe '#set_user_value' do
|
||
setup do
|
||
registry._add('test',
|
||
category: 'Setting',
|
||
default: default,
|
||
type: :integer,
|
||
full_name: 'Test Foo',
|
||
description: 'test update',
|
||
context: :test)
|
||
end
|
||
context 'integer setting' do
|
||
setup do
|
||
registry._add('test',
|
||
category: 'Setting',
|
||
default: default,
|
||
type: :integer,
|
||
full_name: 'Test Foo',
|
||
description: 'test update',
|
||
context: :test)
|
||
end
|
||
it 'initiates the DB model if none exists yet' do
|
||
model = registry.set_user_value('test', '10')
|
||
assert_not_nil model
|
||
assert model.valid?
|
||
assert model.save
|
||
assert_equal 10, model.reload.value
|
||
it 'initiates the DB model if none exists yet' do
|
||
model = registry.set_user_value('test', '10')
|
||
assert_not_nil model
|
||
assert model.valid?
|
||
assert model.save
|
||
assert_equal 10, model.reload.value
|
||
end
|
||
it 'updates the DB model if already exists' do
|
||
model = Setting.create(registry.find('test').attributes.merge(value: setting_value))
|
||
registry.set_user_value('test', '10').save
|
||
assert_equal 10, model.reload.value
|
||
end
|
||
end
|
||
it 'updates the DB model if already exists' do
|
||
model = Setting.create(registry.find('test').attributes.merge(value: setting_value))
|
||
registry.set_user_value('test', '10').save
|
||
assert_equal 10, model.reload.value
|
||
context 'encrypted setting' do
|
||
setup do
|
||
registry._add('test',
|
||
category: 'Setting',
|
||
default: 'foo',
|
||
type: :string,
|
||
full_name: 'Test Encrypted Foo',
|
||
description: 'test update',
|
||
encrypted: true,
|
||
context: :test)
|
||
Setting.any_instance.expects(:encryption_key).at_least_once.returns('25d224dd383e92a7e0c82b8bf7c985e815f34cf5')
|
||
end
|
||
it 'encrypts the value' do
|
||
Setting.any_instance.stubs(:setting_definition).returns(registry.find('test'))
|
||
model = registry.set_user_value('test', 'foobar')
|
||
model.save
|
||
assert_includes model.read_attribute(:value), EncryptValue::ENCRYPTION_PREFIX
|
||
end
|
||
end
|
||
end
|
||