15209: Fixes pysdk dependency strings on pam, fuse & nodemanager.
[arvados.git] / services / api / test / unit / permission_test.rb
index 24399f500e224151d175f94049cb0eb4181cf129..275d2a651b8d2edc0dabbb16c55e55cccef15bc2 100644 (file)
@@ -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
 require 'test_helper'
 
 class PermissionTest < ActiveSupport::TestCase
@@ -63,6 +67,60 @@ class PermissionTest < ActiveSupport::TestCase
     assert ob.writable_by.include?(users(:active).uuid), "user does not have write permission"
   end
 
     assert ob.writable_by.include?(users(:active).uuid), "user does not have write permission"
   end
 
+  test "writable_by reports requesting user's own uuid for a writable project" do
+    invited_to_write = users(:project_viewer)
+    group = groups(:asubproject)
+
+    # project_view can read, but cannot see write or see writers list
+    set_user_from_auth :project_viewer
+    assert_equal([group.owner_uuid],
+                 group.writable_by,
+                 "writers list should just have owner_uuid")
+
+    # allow project_viewer to write for the remainder of the test
+    set_user_from_auth :admin
+    Link.create!(tail_uuid: invited_to_write.uuid,
+                 head_uuid: group.uuid,
+                 link_class: 'permission',
+                 name: 'can_write')
+    group.permissions.reload
+
+    # project_viewer should see self in writers list (but not all writers)
+    set_user_from_auth :project_viewer
+    assert_not_nil(group.writable_by,
+                    "can write but cannot see writers list")
+    assert_includes(group.writable_by, invited_to_write.uuid,
+                    "self missing from writers list")
+    assert_includes(group.writable_by, group.owner_uuid,
+                    "project owner missing from writers list")
+    refute_includes(group.writable_by, users(:active).uuid,
+                    "saw :active user in writers list")
+
+    # active user should see full writers list
+    set_user_from_auth :active
+    assert_includes(group.writable_by, invited_to_write.uuid,
+                    "permission just added, but missing from writers list")
+
+    # allow project_viewer to manage for the remainder of the test
+    set_user_from_auth :admin
+    Link.create!(tail_uuid: invited_to_write.uuid,
+                 head_uuid: group.uuid,
+                 link_class: 'permission',
+                 name: 'can_manage')
+    # invite another writer we can test for
+    Link.create!(tail_uuid: users(:spectator).uuid,
+                 head_uuid: group.uuid,
+                 link_class: 'permission',
+                 name: 'can_write')
+    group.permissions.reload
+
+    set_user_from_auth :project_viewer
+    assert_not_nil(group.writable_by,
+                    "can manage but cannot see writers list")
+    assert_includes(group.writable_by, users(:spectator).uuid,
+                    ":spectator missing from writers list")
+  end
+
   test "user owns group, group can_manage object's group, user can add permissions" do
     set_user_from_auth :admin
 
   test "user owns group, group can_manage object's group, user can add permissions" do
     set_user_from_auth :admin
 
@@ -71,10 +129,10 @@ class PermissionTest < ActiveSupport::TestCase
     sp_grp = Group.create!
     sp = Specimen.create!(owner_uuid: sp_grp.uuid)
 
     sp_grp = Group.create!
     sp = Specimen.create!(owner_uuid: sp_grp.uuid)
 
-    manage_perm = Link.create!(link_class: 'permission',
-                               name: 'can_manage',
-                               tail_uuid: owner_grp.uuid,
-                               head_uuid: sp_grp.uuid)
+    Link.create!(link_class: 'permission',
+                 name: 'can_manage',
+                 tail_uuid: owner_grp.uuid,
+                 head_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.
 
     # active user owns owner_grp, which has can_manage permission on sp_grp
     # user should be able to add permissions on sp.
@@ -83,14 +141,12 @@ class PermissionTest < ActiveSupport::TestCase
                             head_uuid: sp.uuid,
                             link_class: 'permission',
                             name: 'can_write')
                             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
 
     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!
     set_user_from_auth :admin
 
     ob = Specimen.create!
@@ -132,10 +188,105 @@ class PermissionTest < ActiveSupport::TestCase
     end
   end
 
     end
   end
 
+  test "manager user gets permission to minions' articles via can_manage link" do
+    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!
+    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"
+      assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
+                   "saw a user I shouldn't see")
+      assert_raises(ArvadosModel::PermissionDeniedError,
+                    ActiveRecord::RecordInvalid,
+                    "gave can_read permission to a user I shouldn't see") do
+        create(:permission_link,
+               name: 'can_read', tail_uuid: minion.uuid, head_uuid: g.uuid)
+      end
+      %w(can_manage can_write can_read).each do |perm_type|
+        assert_raises(ArvadosModel::PermissionDeniedError,
+                      ActiveRecord::RecordInvalid,
+                      "escalated privileges") do
+          create(:permission_link,
+                 name: perm_type, tail_uuid: g.uuid, head_uuid: minion.uuid)
+        end
+      end
+      assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
+                   "manager saw minion too soon")
+      assert_empty(User.readable_by(minion).where(uuid: manager.uuid),
+                   "minion saw manager too soon")
+      assert_empty(Group.readable_by(minion).where(uuid: g.uuid),
+                   "minion saw manager's new NoBigSecret Lab group too soon")
+
+      # Manager declares everybody on the system should be able to see
+      # the NoBigSecret Lab group.
+      create(:permission_link,
+             name: 'can_read',
+             tail_uuid: 'zzzzz-j7d0g-fffffffffffffff',
+             head_uuid: g.uuid)
+      # ...but nobody has joined the group yet. Manager still can't see
+      # minion.
+      assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
+                   "manager saw minion too soon")
+    end
+
+    act_as_user minion do
+      # Minion can see the group.
+      assert_not_empty(Group.readable_by(minion).where(uuid: g.uuid),
+                       "minion could not see the NoBigSecret Lab group")
+      # Minion joins the group.
+      create(:permission_link,
+             name: 'can_read',
+             tail_uuid: g.uuid,
+             head_uuid: minion.uuid)
+    end
+
+    act_as_user manager do
+      # Now, manager can see minion.
+      assert_not_empty(User.readable_by(manager).where(uuid: minion.uuid),
+                       "manager could not see minion")
+      # But cannot obtain further privileges this way.
+      assert_raises(ArvadosModel::PermissionDeniedError,
+                    "escalated privileges") do
+        create(:permission_link,
+               name: 'can_manage', tail_uuid: manager.uuid, head_uuid: minion.uuid)
+      end
+      assert_empty(Specimen
+                     .readable_by(manager)
+                     .where(uuid: minions_specimen.uuid),
+                   "manager saw the minion's private stuff")
+      assert_raises(ArvadosModel::PermissionDeniedError,
+                   "manager could update minion's private stuff") do
+        minions_specimen.update_attributes(properties: {'x' => 'y'})
+      end
+    end
+
+    act_as_system_user do
+      # Root can give Manager more privileges over Minion.
+      create(:permission_link,
+             name: 'can_manage', tail_uuid: g.uuid, head_uuid: minion.uuid)
+    end
+
+    act_as_user manager do
+      # Now, manager can read and write Minion's stuff.
+      assert_not_empty(Specimen
+                         .readable_by(manager)
+                         .where(uuid: minions_specimen.uuid),
+                       "manager could not find minion's specimen by uuid")
+      assert_equal(true,
+                   minions_specimen.update_attributes(properties: {'x' => 'y'}),
+                   "manager could not update minion's specimen object")
+    end
+  end
+
   test "users with bidirectional read permission in group can see each other, but cannot see each other's private articles" do
   test "users with bidirectional read permission in group can see each other, but cannot see each other's private articles" do
-    a = create :active_user first_name: "A"
-    b = create :active_user first_name: "B"
-    other = create :active_user first_name: "OTHER"
+    a = create :active_user, first_name: "A"
+    b = create :active_user, first_name: "B"
+    other = create :active_user, first_name: "OTHER"
     act_as_system_user do
       g = create :group
       [a,b].each do |u|
     act_as_system_user do
       g = create :group
       [a,b].each do |u|
@@ -161,15 +312,16 @@ class PermissionTest < ActiveSupport::TestCase
         assert_raises ArvadosModel::PermissionDeniedError, "wrote without perm" do
           other.update_attributes!(prefs: {'pwned' => true})
         end
         assert_raises ArvadosModel::PermissionDeniedError, "wrote without perm" do
           other.update_attributes!(prefs: {'pwned' => true})
         end
-        assert_equal true, u.update_attributes!(prefs: {'thisisme' => true})
+        assert_equal(true, u.update_attributes!(prefs: {'thisisme' => true}),
+                     "#{u.first_name} can't update its own prefs")
       end
       act_as_user other do
       end
       act_as_user other do
-        ([other, a, b] - [u]).each do |x|
-          assert_raises ArvadosModel::PermissionDeniedError, "wrote without perm" do
-            x.update_attributes!(prefs: {'pwned' => true})
-          end
+        assert_raises(ArvadosModel::PermissionDeniedError,
+                        "OTHER wrote #{u.first_name} without perm") do
+          u.update_attributes!(prefs: {'pwned' => true})
         end
         end
-        assert_equal true, other.update_attributes!(prefs: {'thisisme' => true})
+        assert_equal(true, other.update_attributes!(prefs: {'thisisme' => true}),
+                     "OTHER can't update its own prefs")
       end
     end
   end
       end
     end
   end
@@ -204,4 +356,26 @@ class PermissionTest < ActiveSupport::TestCase
     end
   end
 
     end
   end
 
+  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
 end
 end