X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/b91db14a4dced9d6ea124e86be3c796e6f2c8e8c..1a599ec69ad8d533da1f12ad5d2c5789aa1c14e2:/services/api/test/integration/permissions_test.rb diff --git a/services/api/test/integration/permissions_test.rb b/services/api/test/integration/permissions_test.rb index 2ebd62bc8b..eec41aa085 100644 --- a/services/api/test/integration/permissions_test.rb +++ b/services/api/test/integration/permissions_test.rb @@ -1,258 +1,314 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + require 'test_helper' class PermissionsTest < ActionDispatch::IntegrationTest + include DbCurrentTime + include CurrentApiClient # for empty_collection fixtures :users, :groups, :api_client_authorizations, :collections test "adding and removing direct can_read links" do # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 # try to add permission as spectator - post "/arvados/v1/links", { - :format => :json, - :link => { - tail_uuid: users(:spectator).uuid, - link_class: 'permission', - name: 'can_read', - head_uuid: collections(:foo_file).uuid, - properties: {} - } - }, auth(:spectator) + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: users(:spectator).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: collections(:foo_file).uuid, + properties: {} + } + }, + headers: auth(:spectator) assert_response 422 # add permission as admin - post "/arvados/v1/links", { - :format => :json, - :link => { - tail_uuid: users(:spectator).uuid, - link_class: 'permission', - name: 'can_read', - head_uuid: collections(:foo_file).uuid, - properties: {} - } - }, auth(:admin) + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: users(:spectator).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: collections(:foo_file).uuid, + properties: {} + } + }, + headers: auth(:admin) u = json_response['uuid'] assert_response :success # read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response :success # try to delete permission as spectator - delete "/arvados/v1/links/#{u}", {:format => :json}, auth(:spectator) + delete "/arvados/v1/links/#{u}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 403 # delete permission as admin - delete "/arvados/v1/links/#{u}", {:format => :json}, auth(:admin) + delete "/arvados/v1/links/#{u}", + params: {:format => :json}, + headers: auth(:admin) assert_response :success # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 end test "adding can_read links from user to group, group to collection" do # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 # add permission for spectator to read group - post "/arvados/v1/links", { - :format => :json, - :link => { - tail_uuid: users(:spectator).uuid, - link_class: 'permission', - name: 'can_read', - head_uuid: groups(:private).uuid, - properties: {} - } - }, auth(:admin) + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: users(:spectator).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: groups(:private).uuid, + properties: {} + } + }, + headers: auth(:admin) assert_response :success # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 # add permission for group to read collection - post "/arvados/v1/links", { - :format => :json, - :link => { - tail_uuid: groups(:private).uuid, - link_class: 'permission', - name: 'can_read', - head_uuid: collections(:foo_file).uuid, - properties: {} - } - }, auth(:admin) + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: groups(:private).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: collections(:foo_file).uuid, + properties: {} + } + }, + headers: auth(:admin) u = json_response['uuid'] assert_response :success # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response :success # delete permission for group to read collection - delete "/arvados/v1/links/#{u}", {:format => :json}, auth(:admin) + delete "/arvados/v1/links/#{u}", + params: {:format => :json}, + headers: auth(:admin) assert_response :success # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 - + end test "adding can_read links from group to collection, user to group" do # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 # add permission for group to read collection - post "/arvados/v1/links", { - :format => :json, - :link => { - tail_uuid: groups(:private).uuid, - link_class: 'permission', - name: 'can_read', - head_uuid: collections(:foo_file).uuid, - properties: {} - } - }, auth(:admin) + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: groups(:private).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: collections(:foo_file).uuid, + properties: {} + } + }, + headers: auth(:admin) assert_response :success # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 # add permission for spectator to read group - post "/arvados/v1/links", { - :format => :json, - :link => { - tail_uuid: users(:spectator).uuid, - link_class: 'permission', - name: 'can_read', - head_uuid: groups(:private).uuid, - properties: {} - } - }, auth(:admin) + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: users(:spectator).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: groups(:private).uuid, + properties: {} + } + }, + headers: auth(:admin) u = json_response['uuid'] assert_response :success # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response :success # delete permission for spectator to read group - delete "/arvados/v1/links/#{u}", {:format => :json}, auth(:admin) + delete "/arvados/v1/links/#{u}", + params: {:format => :json}, + headers: auth(:admin) assert_response :success # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 - + end test "adding can_read links from user to group, group to group, group to collection" do # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 # add permission for user to read group - post "/arvados/v1/links", { - :format => :json, - :link => { - tail_uuid: users(:spectator).uuid, - link_class: 'permission', - name: 'can_read', - head_uuid: groups(:private).uuid, - properties: {} - } - }, auth(:admin) + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: users(:spectator).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: groups(:private).uuid, + properties: {} + } + }, + headers: auth(:admin) assert_response :success # add permission for group to read group - post "/arvados/v1/links", { - :format => :json, - :link => { - tail_uuid: groups(:private).uuid, - link_class: 'permission', - name: 'can_read', - head_uuid: groups(:empty_lonely_group).uuid, - properties: {} - } - }, auth(:admin) + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: groups(:private).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: groups(:empty_lonely_group).uuid, + properties: {} + } + }, + headers: auth(:admin) assert_response :success # add permission for group to read collection - post "/arvados/v1/links", { - :format => :json, - :link => { - tail_uuid: groups(:empty_lonely_group).uuid, - link_class: 'permission', - name: 'can_read', - head_uuid: collections(:foo_file).uuid, - properties: {} - } - }, auth(:admin) + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: groups(:empty_lonely_group).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: collections(:foo_file).uuid, + properties: {} + } + }, + headers: auth(:admin) u = json_response['uuid'] assert_response :success # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response :success # delete permission for group to read collection - delete "/arvados/v1/links/#{u}", {:format => :json}, auth(:admin) + delete "/arvados/v1/links/#{u}", + params: {:format => :json}, + headers: auth(:admin) assert_response :success # try to read collection as spectator - get "/arvados/v1/collections/#{collections(:foo_file).uuid}", {:format => :json}, auth(:spectator) + get "/arvados/v1/collections/#{collections(:foo_file).uuid}", + params: {:format => :json}, + headers: auth(:spectator) assert_response 404 end - test "read-only group-admin sees correct subset of user list" do - get "/arvados/v1/users", {:format => :json}, auth(:rominiadmin) - assert_response :success - resp_uuids = json_response['items'].collect { |i| i['uuid'] } - [[true, users(:rominiadmin).uuid], - [true, users(:active).uuid], - [false, users(:miniadmin).uuid], - [false, users(:spectator).uuid]].each do |should_find, uuid| - assert_equal should_find, !resp_uuids.index(uuid).nil?, "rominiadmin should #{'not ' if !should_find}see #{uuid} in user list" - end - end - test "read-only group-admin cannot modify administered user" do - put "/arvados/v1/users/#{users(:active).uuid}", { - :user => { - first_name: 'KilroyWasHere' + put "/arvados/v1/users/#{users(:active).uuid}", + params: { + :user => { + first_name: 'KilroyWasHere' + }, + :format => :json }, - :format => :json - }, auth(:rominiadmin) + headers: auth(:rominiadmin) assert_response 403 end test "read-only group-admin cannot read or update non-administered user" do - get "/arvados/v1/users/#{users(:spectator).uuid}", { - :format => :json - }, auth(:rominiadmin) + get "/arvados/v1/users/#{users(:spectator).uuid}", + params: {:format => :json}, + headers: auth(:rominiadmin) assert_response 404 - put "/arvados/v1/users/#{users(:spectator).uuid}", { - :user => { - first_name: 'KilroyWasHere' + put "/arvados/v1/users/#{users(:spectator).uuid}", + params: { + :user => { + first_name: 'KilroyWasHere' + }, + :format => :json }, - :format => :json - }, auth(:rominiadmin) + headers: auth(:rominiadmin) assert_response 404 end test "RO group-admin finds user's specimens, RW group-admin can update" do [[:rominiadmin, false], [:miniadmin, true]].each do |which_user, update_should_succeed| - get "/arvados/v1/specimens", {:format => :json}, auth(which_user) + get "/arvados/v1/specimens", + params: {:format => :json}, + headers: auth(which_user) assert_response :success resp_uuids = json_response['items'].collect { |i| i['uuid'] } [[true, specimens(:owned_by_active_user).uuid], @@ -264,14 +320,16 @@ class PermissionsTest < ActionDispatch::IntegrationTest [which_user.to_s, should_find ? '' : 'not ', uuid]) - put "/arvados/v1/specimens/#{uuid}", { - :specimen => { - properties: { - miniadmin_was_here: true - } + put "/arvados/v1/specimens/#{uuid}", + params: { + :specimen => { + properties: { + miniadmin_was_here: true + } + }, + :format => :json }, - :format => :json - }, auth(which_user) + headers: auth(which_user) if !should_find assert_response 404 elsif !update_should_succeed @@ -283,4 +341,110 @@ class PermissionsTest < ActionDispatch::IntegrationTest end end + test "get_permissions returns list" do + # First confirm that user :active cannot get permissions on group :public + get "/arvados/v1/permissions/#{groups(:public).uuid}", + params: nil, + headers: auth(:active) + assert_response 404 + + # add some permissions, including can_manage + # permission for user :active + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: users(:spectator).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: groups(:public).uuid, + properties: {} + } + }, + headers: auth(:admin) + assert_response :success + can_read_uuid = json_response['uuid'] + + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: users(:inactive).uuid, + link_class: 'permission', + name: 'can_write', + head_uuid: groups(:public).uuid, + properties: {} + } + }, + headers: auth(:admin) + assert_response :success + can_write_uuid = json_response['uuid'] + + post "/arvados/v1/links", + params: { + :format => :json, + :link => { + tail_uuid: users(:active).uuid, + link_class: 'permission', + name: 'can_manage', + head_uuid: groups(:public).uuid, + properties: {} + } + }, + headers: auth(:admin) + assert_response :success + can_manage_uuid = json_response['uuid'] + + # Now user :active should be able to retrieve permissions + # on group :public. + get("/arvados/v1/permissions/#{groups(:public).uuid}", + params: { :format => :json }, + headers: auth(:active)) + assert_response :success + + perm_uuids = json_response['items'].map { |item| item['uuid'] } + assert_includes perm_uuids, can_read_uuid, "can_read_uuid not found" + assert_includes perm_uuids, can_write_uuid, "can_write_uuid not found" + assert_includes perm_uuids, can_manage_uuid, "can_manage_uuid not found" + end + + test "get_permissions returns 404 for nonexistent uuid" do + nonexistent = Group.generate_uuid + # make sure it really doesn't exist + get "/arvados/v1/groups/#{nonexistent}", params: nil, headers: auth(:admin) + assert_response 404 + + get "/arvados/v1/permissions/#{nonexistent}", params: nil, headers: auth(:active) + assert_response 404 + end + + test "get_permissions returns 403 if user can read but not manage" do + post "/arvados/v1/links", + params: { + :link => { + tail_uuid: users(:active).uuid, + link_class: 'permission', + name: 'can_read', + head_uuid: groups(:public).uuid, + properties: {} + } + }, + headers: auth(:admin) + assert_response :success + + get "/arvados/v1/permissions/#{groups(:public).uuid}", + params: nil, + headers: auth(:active) + assert_response 403 + end + + test "active user can read the empty collection" do + # The active user should be able to read the empty collection. + + get("/arvados/v1/collections/#{empty_collection_uuid}", + params: {:format => :json}, + headers: auth(:active)) + assert_response :success + assert_empty json_response['manifest_text'], "empty collection manifest_text is not empty" + end end