X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/093bae4c914a872c501c3235f06096092725f015..5e4b8ac7997c68ffa45471b9879789c96068885d:/services/api/test/unit/permission_test.rb diff --git a/services/api/test/unit/permission_test.rb b/services/api/test/unit/permission_test.rb index 20cffdaaa7..128d0ebaa6 100644 --- a/services/api/test/unit/permission_test.rb +++ b/services/api/test/unit/permission_test.rb @@ -1,3 +1,7 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + require 'test_helper' class PermissionTest < ActiveSupport::TestCase @@ -6,7 +10,7 @@ class PermissionTest < ActiveSupport::TestCase test "Grant permissions on an object I own" do set_user_from_auth :active_trustedclient - ob = Specimen.create + ob = Collection.create assert ob.save # Ensure I have permission to manage this group even when its owner changes @@ -20,7 +24,7 @@ class PermissionTest < ActiveSupport::TestCase test "Delete permission links when deleting an object" do set_user_from_auth :active_trustedclient - ob = Specimen.create! + ob = Collection.create! Link.create!(tail_uuid: users(:active).uuid, head_uuid: ob.uuid, link_class: 'permission', @@ -33,7 +37,7 @@ class PermissionTest < ActiveSupport::TestCase test "permission links owned by root" do set_user_from_auth :active_trustedclient - ob = Specimen.create! + ob = Collection.create! perm_link = Link.create!(tail_uuid: users(:active).uuid, head_uuid: ob.uuid, link_class: 'permission', @@ -42,20 +46,20 @@ class PermissionTest < ActiveSupport::TestCase end test "readable_by" do - set_user_from_auth :active_trustedclient + set_user_from_auth :admin - ob = Specimen.create! + ob = Collection.create! Link.create!(tail_uuid: users(:active).uuid, head_uuid: ob.uuid, link_class: 'permission', name: 'can_read') - assert Specimen.readable_by(users(:active)).where(uuid: ob.uuid).any?, "user does not have read permission" + assert Collection.readable_by(users(:active)).where(uuid: ob.uuid).any?, "user does not have read permission" end test "writable_by" do - set_user_from_auth :active_trustedclient + set_user_from_auth :admin - ob = Specimen.create! + ob = Collection.create! Link.create!(tail_uuid: users(:active).uuid, head_uuid: ob.uuid, link_class: 'permission', @@ -63,6 +67,34 @@ class PermissionTest < ActiveSupport::TestCase assert ob.writable_by.include?(users(:active).uuid), "user does not have write permission" end + test "update permission link" do + set_user_from_auth :admin + + grp = Group.create! name: "blah project", group_class: "project" + ob = Collection.create! owner_uuid: grp.uuid + + assert !users(:active).can?(write: ob) + assert !users(:active).can?(read: ob) + + l1 = Link.create!(tail_uuid: users(:active).uuid, + head_uuid: grp.uuid, + link_class: 'permission', + name: 'can_write') + + assert users(:active).can?(write: ob) + assert users(:active).can?(read: ob) + + l1.update_attributes!(name: 'can_read') + + assert !users(:active).can?(write: ob) + assert users(:active).can?(read: ob) + + l1.destroy + + assert !users(:active).can?(write: ob) + assert !users(:active).can?(read: ob) + end + test "writable_by reports requesting user's own uuid for a writable project" do invited_to_write = users(:project_viewer) group = groups(:asubproject) @@ -120,15 +152,16 @@ class PermissionTest < ActiveSupport::TestCase test "user owns group, group can_manage object's group, user can add permissions" do set_user_from_auth :admin - owner_grp = Group.create!(owner_uuid: users(:active).uuid) + owner_grp = Group.create!(owner_uuid: users(:active).uuid, group_class: "role") + + sp_grp = Group.create!(group_class: "project") - sp_grp = Group.create! - sp = Specimen.create!(owner_uuid: sp_grp.uuid) + Link.create!(link_class: 'permission', + name: 'can_manage', + tail_uuid: owner_grp.uuid, + head_uuid: sp_grp.uuid) - manage_perm = Link.create!(link_class: 'permission', - name: 'can_manage', - tail_uuid: owner_grp.uuid, - head_uuid: sp_grp.uuid) + sp = Collection.create!(owner_uuid: sp_grp.uuid) # active user owns owner_grp, which has can_manage permission on sp_grp # user should be able to add permissions on sp. @@ -137,17 +170,15 @@ class PermissionTest < ActiveSupport::TestCase head_uuid: sp.uuid, link_class: 'permission', name: 'can_write') - test_uuid = test_perm.uuid assert test_perm.save, "could not save new permission on target object" assert test_perm.destroy, "could not delete new permission on target object" end - # TODO(twp): fix bug #3091, which should fix this test. - test "can_manage permission on a non-group object" do - skip + # bug #3091 + skip "can_manage permission on a non-group object" do set_user_from_auth :admin - ob = Specimen.create! + ob = Collection.create! # grant can_manage permission to active perm_link = Link.create!(tail_uuid: users(:active).uuid, head_uuid: ob.uuid, @@ -168,7 +199,7 @@ class PermissionTest < ActiveSupport::TestCase test "user without can_manage permission may not modify permission link" do set_user_from_auth :admin - ob = Specimen.create! + ob = Collection.create! # grant can_manage permission to active perm_link = Link.create!(tail_uuid: users(:active).uuid, head_uuid: ob.uuid, @@ -187,16 +218,18 @@ class PermissionTest < ActiveSupport::TestCase end test "manager user gets permission to minions' articles via can_manage link" do + Rails.configuration.Users.ActivatedUsersAreVisibleToOthers = false manager = create :active_user, first_name: "Manage", last_name: "Er" minion = create :active_user, first_name: "Min", last_name: "Ion" minions_specimen = act_as_user minion do - Specimen.create! + g = Group.create! name: "minon project", group_class: "project" + Collection.create! owner_uuid: g.uuid end # Manager creates a group. (Make sure it doesn't magically give # anyone any additional permissions.) g = nil act_as_user manager do - g = create :group, name: "NoBigSecret Lab" + g = create :group, name: "NoBigSecret Lab", group_class: "role" assert_empty(User.readable_by(manager).where(uuid: minion.uuid), "saw a user I shouldn't see") assert_raises(ArvadosModel::PermissionDeniedError, @@ -253,7 +286,7 @@ class PermissionTest < ActiveSupport::TestCase create(:permission_link, name: 'can_manage', tail_uuid: manager.uuid, head_uuid: minion.uuid) end - assert_empty(Specimen + assert_empty(Collection .readable_by(manager) .where(uuid: minions_specimen.uuid), "manager saw the minion's private stuff") @@ -271,7 +304,7 @@ class PermissionTest < ActiveSupport::TestCase act_as_user manager do # Now, manager can read and write Minion's stuff. - assert_not_empty(Specimen + assert_not_empty(Collection .readable_by(manager) .where(uuid: minions_specimen.uuid), "manager could not find minion's specimen by uuid") @@ -282,11 +315,18 @@ class PermissionTest < ActiveSupport::TestCase end test "users with bidirectional read permission in group can see each other, but cannot see each other's private articles" do + Rails.configuration.Users.ActivatedUsersAreVisibleToOthers = false a = create :active_user, first_name: "A" b = create :active_user, first_name: "B" other = create :active_user, first_name: "OTHER" + + assert_empty(User.readable_by(b).where(uuid: a.uuid), + "#{b.first_name} should not be able to see 'a' in the user list") + assert_empty(User.readable_by(a).where(uuid: b.uuid), + "#{a.first_name} should not be able to see 'b' in the user list") + act_as_system_user do - g = create :group + g = create :group, group_class: "role" [a,b].each do |u| create(:permission_link, name: 'can_read', tail_uuid: u.uuid, head_uuid: g.uuid) @@ -294,13 +334,19 @@ class PermissionTest < ActiveSupport::TestCase name: 'can_read', head_uuid: u.uuid, tail_uuid: g.uuid) end end + + assert_not_empty(User.readable_by(b).where(uuid: a.uuid), + "#{b.first_name} should be able to see 'a' in the user list") + assert_not_empty(User.readable_by(a).where(uuid: b.uuid), + "#{a.first_name} should be able to see 'b' in the user list") + a_specimen = act_as_user a do - Specimen.create! + Collection.create! end - assert_not_empty(Specimen.readable_by(a).where(uuid: a_specimen.uuid), - "A cannot read own Specimen, following test probably useless.") - assert_empty(Specimen.readable_by(b).where(uuid: a_specimen.uuid), - "B can read A's Specimen") + assert_not_empty(Collection.readable_by(a).where(uuid: a_specimen.uuid), + "A cannot read own Collection, following test probably useless.") + assert_empty(Collection.readable_by(b).where(uuid: a_specimen.uuid), + "B can read A's Collection") [a,b].each do |u| assert_empty(User.readable_by(u).where(uuid: other.uuid), "#{u.first_name} can see OTHER in the user list") @@ -327,13 +373,13 @@ class PermissionTest < ActiveSupport::TestCase test "cannot create with owner = unwritable user" do set_user_from_auth :rominiadmin assert_raises ArvadosModel::PermissionDeniedError, "created with owner = unwritable user" do - Specimen.create!(owner_uuid: users(:active).uuid) + Collection.create!(owner_uuid: users(:active).uuid) end end test "cannot change owner to unwritable user" do set_user_from_auth :rominiadmin - ob = Specimen.create! + ob = Collection.create! assert_raises ArvadosModel::PermissionDeniedError, "changed owner to unwritable user" do ob.update_attributes!(owner_uuid: users(:active).uuid) end @@ -342,29 +388,217 @@ class PermissionTest < ActiveSupport::TestCase test "cannot create with owner = unwritable group" do set_user_from_auth :rominiadmin assert_raises ArvadosModel::PermissionDeniedError, "created with owner = unwritable group" do - Specimen.create!(owner_uuid: groups(:aproject).uuid) + Collection.create!(owner_uuid: groups(:aproject).uuid) end end test "cannot change owner to unwritable group" do set_user_from_auth :rominiadmin - ob = Specimen.create! + ob = Collection.create! assert_raises ArvadosModel::PermissionDeniedError, "changed owner to unwritable group" do ob.update_attributes!(owner_uuid: groups(:aproject).uuid) end end - test "active user cannot write admin's repo" do - set_user_from_auth :active - assert_raises ArvadosModel::PermissionDeniedError, "pwned" do - repositories(:repository3).update_attributes(name: "kilroy") + def container_logs(container, user) + Log.readable_by(users(user)). + where(object_uuid: containers(container).uuid, event_type: "test") + end + + test "container logs created by dispatch are visible to container requestor" do + set_user_from_auth :dispatch1 + Log.create!(object_uuid: containers(:running).uuid, + event_type: "test") + + assert_not_empty container_logs(:running, :admin) + assert_not_empty container_logs(:running, :active) + assert_empty container_logs(:running, :spectator) + end + + test "container logs created by dispatch are public if container request is public" do + set_user_from_auth :dispatch1 + Log.create!(object_uuid: containers(:running_older).uuid, + event_type: "test") + + assert_not_empty container_logs(:running_older, :anonymous) + end + + test "add user to group, then remove them" do + set_user_from_auth :admin + grp = Group.create!(owner_uuid: system_user_uuid, group_class: "role") + col = Collection.create!(owner_uuid: system_user_uuid) + + l0 = Link.create!(tail_uuid: grp.uuid, + head_uuid: col.uuid, + link_class: 'permission', + name: 'can_read') + + assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid) + assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid) + + l1 = Link.create!(tail_uuid: users(:active).uuid, + head_uuid: grp.uuid, + link_class: 'permission', + name: 'can_read') + l2 = Link.create!(tail_uuid: grp.uuid, + head_uuid: users(:active).uuid, + link_class: 'permission', + name: 'can_read') + + l3 = Link.create!(tail_uuid: users(:project_viewer).uuid, + head_uuid: grp.uuid, + link_class: 'permission', + name: 'can_read') + l4 = Link.create!(tail_uuid: grp.uuid, + head_uuid: users(:project_viewer).uuid, + link_class: 'permission', + name: 'can_read') + + assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first + assert User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid).first + + l1.destroy + l2.destroy + + assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid) + assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid) + + end + + + test "add user to group, then change permission level" do + set_user_from_auth :admin + grp = Group.create!(owner_uuid: system_user_uuid, group_class: "project") + col = Collection.create!(owner_uuid: grp.uuid) + assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid) + assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid) + + l1 = Link.create!(tail_uuid: users(:active).uuid, + head_uuid: grp.uuid, + link_class: 'permission', + name: 'can_manage') + + assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first + assert users(:active).can?(read: col.uuid) + assert users(:active).can?(write: col.uuid) + assert users(:active).can?(manage: col.uuid) + + l1.name = 'can_read' + l1.save! + + assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first + assert users(:active).can?(read: col.uuid) + assert !users(:active).can?(write: col.uuid) + assert !users(:active).can?(manage: col.uuid) + + l1.name = 'can_write' + l1.save! + + assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first + assert users(:active).can?(read: col.uuid) + assert users(:active).can?(write: col.uuid) + assert !users(:active).can?(manage: col.uuid) + end + + + test "add user to group, then add overlapping permission link to group" do + set_user_from_auth :admin + grp = Group.create!(owner_uuid: system_user_uuid, group_class: "project") + col = Collection.create!(owner_uuid: grp.uuid) + assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid) + assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid) + + l1 = Link.create!(tail_uuid: users(:active).uuid, + head_uuid: grp.uuid, + link_class: 'permission', + name: 'can_manage') + + assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first + assert users(:active).can?(read: col.uuid) + assert users(:active).can?(write: col.uuid) + assert users(:active).can?(manage: col.uuid) + + l3 = Link.create!(tail_uuid: users(:active).uuid, + head_uuid: grp.uuid, + link_class: 'permission', + name: 'can_read') + + assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first + assert users(:active).can?(read: col.uuid) + assert users(:active).can?(write: col.uuid) + assert users(:active).can?(manage: col.uuid) + + l3.destroy! + + assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first + assert users(:active).can?(read: col.uuid) + assert users(:active).can?(write: col.uuid) + assert users(:active).can?(manage: col.uuid) + end + + + test "add user to group, then add overlapping permission link to subproject" do + set_user_from_auth :admin + grp = Group.create!(owner_uuid: system_user_uuid, group_class: "role") + prj = Group.create!(owner_uuid: system_user_uuid, group_class: "project") + + l0 = Link.create!(tail_uuid: grp.uuid, + head_uuid: prj.uuid, + link_class: 'permission', + name: 'can_manage') + + assert_empty Group.readable_by(users(:active)).where(uuid: prj.uuid) + assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid) + + l1 = Link.create!(tail_uuid: users(:active).uuid, + head_uuid: grp.uuid, + link_class: 'permission', + name: 'can_manage') + l2 = Link.create!(tail_uuid: grp.uuid, + head_uuid: users(:active).uuid, + link_class: 'permission', + name: 'can_read') + + assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first + assert users(:active).can?(read: prj.uuid) + assert users(:active).can?(write: prj.uuid) + assert users(:active).can?(manage: prj.uuid) + + l3 = Link.create!(tail_uuid: grp.uuid, + head_uuid: prj.uuid, + link_class: 'permission', + name: 'can_read') + + assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first + assert users(:active).can?(read: prj.uuid) + assert users(:active).can?(write: prj.uuid) + assert users(:active).can?(manage: prj.uuid) + + l3.destroy! + + assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first + assert users(:active).can?(read: prj.uuid) + assert users(:active).can?(write: prj.uuid) + assert users(:active).can?(manage: prj.uuid) + end + + [system_user_uuid, anonymous_user_uuid].each do |u| + test "cannot delete system user #{u}" do + act_as_system_user do + assert_raises ArvadosModel::PermissionDeniedError do + User.find_by_uuid(u).destroy + end + end end end - test "active user cannot change repo name via can_manage permission" do - set_user_from_auth :active - assert_raises ArvadosModel::PermissionDeniedError, "pwned" do - repositories(:foo).update_attributes(name: "arvados") + [system_group_uuid, anonymous_group_uuid, public_project_uuid].each do |g| + test "cannot delete system group #{g}" do + act_as_system_user do + assert_raises ArvadosModel::PermissionDeniedError do + Group.find_by_uuid(g).destroy + end + end end end end