X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/442e5c6553061ef1bbb8d9194bb5b8d9cdb68545..849f35d1cafa1b58e55832426436689b95d69ac5:/services/api/test/unit/log_test.rb diff --git a/services/api/test/unit/log_test.rb b/services/api/test/unit/log_test.rb index 39b45a326f..632271e98c 100644 --- a/services/api/test/unit/log_test.rb +++ b/services/api/test/unit/log_test.rb @@ -9,14 +9,15 @@ class LogTest < ActiveSupport::TestCase :destroy => [nil, :assert_not_nil, :assert_nil], } - def setup + setup do @start_time = Time.now @log_count = 1 end def assert_properties(test_method, event, props, *keys) - verb = (test_method == :assert_nil) ? 'not include' : 'include' + verb = (test_method == :assert_nil) ? 'have nil' : 'define' keys.each do |prop_name| + assert_includes(props, prop_name, "log properties missing #{prop_name}") self.send(test_method, props[prop_name], "#{event.to_s} log should #{verb} #{prop_name}") end @@ -38,7 +39,6 @@ class LogTest < ActiveSupport::TestCase "log is not 'modified by' current user") assert_equal(current_api_client.andand.uuid, log.modified_by_client_uuid, "log is not 'modified by' current client") - assert_equal(thing.kind, log.object_kind, "log kind mismatch") assert_equal(thing.uuid, log.object_uuid, "log UUID mismatch") assert_equal(event_type.to_s, log.event_type, "log event type mismatch") time_method, old_props_test, new_props_test = EVENT_TEST_METHODS[event_type] @@ -54,11 +54,16 @@ class LogTest < ActiveSupport::TestCase yield props if block_given? end - def set_user_from_auth(auth_name) - client_auth = api_client_authorizations(auth_name) - Thread.current[:api_client_authorization] = client_auth - Thread.current[:api_client] = client_auth.api_client - Thread.current[:user] = client_auth.user + def assert_logged_with_clean_properties(obj, event_type, excluded_attr) + assert_logged(obj, event_type) do |props| + ['old_attributes', 'new_attributes'].map do |logattr| + attributes = props[logattr] + next if attributes.nil? + refute_includes(attributes, excluded_attr, + "log #{logattr} includes #{excluded_attr}") + end + yield props if block_given? + end end test "creating a user makes a log" do @@ -90,11 +95,26 @@ class LogTest < ActiveSupport::TestCase end end + test "old_attributes preserves values deep inside a hash" do + set_user_from_auth :active + it = specimens(:owned_by_active_user) + it.properties = {'foo' => {'bar' => ['baz', 'qux', {'quux' => 'bleat'}]}} + it.save! + @log_count += 1 + it.properties['foo']['bar'][2]['quux'] = 'blert' + it.save! + assert_logged it, :update do |props| + assert_equal 'bleat', props['old_attributes']['properties']['foo']['bar'][2]['quux'] + assert_equal 'blert', props['new_attributes']['properties']['foo']['bar'][2]['quux'] + end + end + test "destroying an authorization makes a log" do set_user_from_auth :admin_trustedclient auth = api_client_authorizations(:spectator) orig_etag = auth.etag orig_attrs = auth.attributes + orig_attrs.delete 'api_token' auth.destroy assert_logged(auth, :destroy) do |props| assert_equal(orig_etag, props['old_etag'], "destroyed auth etag mismatch") @@ -196,7 +216,95 @@ class LogTest < ActiveSupport::TestCase "log count changed after 'using' ApiClientAuthorization") auth.created_by_ip_address = '::1' auth.save! - assert_equal(start_log_count + 1, get_logs_about(auth).size, - "no log after changed stable ApiClientAuthorization attribute") + assert_logged(auth, :update) + end + + test "token isn't included in ApiClientAuthorization logs" do + set_user_from_auth :admin_trustedclient + auth = ApiClientAuthorization.new + auth.user = users(:spectator) + auth.api_client = api_clients(:untrusted) + auth.save! + assert_logged_with_clean_properties(auth, :create, 'api_token') + auth.expires_at = Time.now + auth.save! + assert_logged_with_clean_properties(auth, :update, 'api_token') + auth.destroy + assert_logged_with_clean_properties(auth, :destroy, 'api_token') + end + + test "use ownership and permission links to determine which logs a user can see" do + known_logs = [:noop, + :admin_changes_repository2, + :admin_changes_specimen, + :system_adds_foo_file, + :system_adds_baz, + :log_owned_by_active, + :crunchstat_for_running_job] + + c = Log.readable_by(users(:admin)).order("id asc").each.to_a + assert_log_result c, known_logs, known_logs + + c = Log.readable_by(users(:active)).order("id asc").each.to_a + assert_log_result c, known_logs, [:admin_changes_repository2, # owned by active + :system_adds_foo_file, # readable via link + :system_adds_baz, # readable via 'all users' group + :log_owned_by_active, # log owned by active + :crunchstat_for_running_job] # log & job owned by active + + c = Log.readable_by(users(:spectator)).order("id asc").each.to_a + assert_log_result c, known_logs, [:noop, # object_uuid is spectator + :admin_changes_specimen, # object_uuid is a specimen owned by spectator + :system_adds_baz] # readable via 'all users' group + end + + def assert_log_result result, known_logs, expected_logs + # All of expected_logs must appear in result. Additional logs can + # appear too, but only if they are _not_ listed in known_logs + # (i.e., we do not make any assertions about logs not mentioned in + # either "known" or "expected".) + result_ids = result.collect &:id + expected_logs.each do |want| + assert_includes result_ids, logs(want).id + end + (known_logs - expected_logs).each do |notwant| + refute_includes result_ids, logs(notwant).id + end + end + + test "non-empty configuration.unlogged_attributes" do + Rails.configuration.unlogged_attributes = ["manifest_text"] + txt = ". acbd18db4cc2f85cedef654fccc4a4d8+3 0:3:foo\n" + + act_as_system_user do + coll = Collection.create(manifest_text: txt) + assert_logged_with_clean_properties(coll, :create, 'manifest_text') + coll.name = "testing" + coll.save! + assert_logged_with_clean_properties(coll, :update, 'manifest_text') + coll.destroy + assert_logged_with_clean_properties(coll, :destroy, 'manifest_text') + end + end + + test "empty configuration.unlogged_attributes" do + Rails.configuration.unlogged_attributes = [] + txt = ". acbd18db4cc2f85cedef654fccc4a4d8+3 0:3:foo\n" + + act_as_system_user do + coll = Collection.create(manifest_text: txt) + assert_logged(coll, :create) do |props| + assert_equal(txt, props['new_attributes']['manifest_text']) + end + coll.update_attributes!(name: "testing") + assert_logged(coll, :update) do |props| + assert_equal(txt, props['old_attributes']['manifest_text']) + assert_equal(txt, props['new_attributes']['manifest_text']) + end + coll.destroy + assert_logged(coll, :destroy) do |props| + assert_equal(txt, props['old_attributes']['manifest_text']) + end + end end end