diff --git a/app/models/concerns/host_common.rb b/app/models/concerns/host_common.rb index 076e453621..de7ad92188 100644 --- a/app/models/concerns/host_common.rb +++ b/app/models/concerns/host_common.rb @@ -54,7 +54,8 @@ def lookup_values_attributes=(lookup_values_attributes) lookup_value = lookup_values.to_a.find { |i| i.id.to_i == id.to_i } if lookup_value mark_for_destruction = Foreman::Cast.to_bool(attr.delete(:_destroy)) - lookup_value.attributes = attr + attr.delete(:match) + lookup_value.attributes = attr.merge(:host_or_hostgroup => self) lookup_value.mark_for_destruction if mark_for_destruction end elsif !Foreman::Cast.to_bool(attr.delete(:_destroy)) diff --git a/test/models/host_lookup_value_access_control_test.rb b/test/models/host_lookup_value_access_control_test.rb new file mode 100644 index 0000000000..3a36b07902 --- /dev/null +++ b/test/models/host_lookup_value_access_control_test.rb @@ -0,0 +1,40 @@ +require 'test_helper' + +class HostLookupValueAccessControlTest < ActiveSupport::TestCase + test 'nested lookup_values_attributes cannot retarget existing override match to another host' do + host_source = FactoryBot.create(:host) + host_destination = FactoryBot.create(:host) + source_match = host_source.lookup_value_match + destination_match = host_destination.lookup_value_match + + refute_equal source_match, destination_match, 'fixture hosts must resolve to different fqdn matchers' + + lkey = FactoryBot.create(:lookup_key, :integer, override: true, path: 'fqdn') + + as_admin do + assert_difference('LookupValue.count', 1) do + assert host_source.update!( + lookup_values_attributes: { '0' => { lookup_key_id: lkey.id, value: 111 } } + ) + end + + lvalue = host_source.lookup_values.first + assert_equal source_match, lvalue.match + + assert host_source.update!( + lookup_values_attributes: { + '0' => { + id: lvalue.id, + match: destination_match, + value: 999, + }, + } + ) + end + + lvalue = host_source.lookup_values.first.reload + assert_equal source_match, lvalue.match, + 'nested host update cannot retarget lookup value match to another host - broken access control' + assert_equal 999, lvalue.value + end +end