Project

General

Profile

Bug #34573 » 34573.patch

Proposed patch v1 - Ondřej Ezr, 03/08/2022 01:03 PM

View differences:

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
    (1-1/1)