X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/49fb55aa1a9fb35d8e7e620717cb42f77d448a43..09cbdc3074b3f1e69c9c537875146f6da0a6ed8f:/services/api/test/integration/users_test.rb diff --git a/services/api/test/integration/users_test.rb b/services/api/test/integration/users_test.rb index 28e43b8450..ca14336389 100644 --- a/services/api/test/integration/users_test.rb +++ b/services/api/test/integration/users_test.rb @@ -11,16 +11,17 @@ class UsersTest < ActionDispatch::IntegrationTest test "setup user multiple times" do repo_name = 'usertestrepo' - post "/arvados/v1/users/setup", { - repo_name: repo_name, - openid_prefix: 'https://www.google.com/accounts/o8/id', - user: { - uuid: 'zzzzz-tpzed-abcdefghijklmno', - first_name: "in_create_test_first_name", - last_name: "test_last_name", - email: "foo@example.com" - } - }, auth(:admin) + post "/arvados/v1/users/setup", + params: { + repo_name: repo_name, + user: { + uuid: 'zzzzz-tpzed-abcdefghijklmno', + first_name: "in_create_test_first_name", + last_name: "test_last_name", + email: "foo@example.com" + } + }, + headers: auth(:admin) assert_response :success @@ -34,14 +35,12 @@ class UsersTest < ActionDispatch::IntegrationTest assert_not_nil created['email'], 'expected non-nil email' assert_nil created['identity_url'], 'expected no identity_url' - # arvados#user, repo link and link add user to 'All users' group - verify_link response_items, 'arvados#user', true, 'permission', 'can_login', - created['uuid'], created['email'], 'arvados#user', false, 'arvados#user' + # repo link and link add user to 'All users' group verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository' - verify_link response_items, 'arvados#group', true, 'permission', 'can_read', + verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login', @@ -50,26 +49,28 @@ class UsersTest < ActionDispatch::IntegrationTest verify_system_group_permission_link_for created['uuid'] # invoke setup again with the same data - post "/arvados/v1/users/setup", { - repo_name: repo_name, - vm_uuid: virtual_machines(:testvm).uuid, - openid_prefix: 'https://www.google.com/accounts/o8/id', - user: { - uuid: 'zzzzz-tpzed-abcdefghijklmno', - first_name: "in_create_test_first_name", - last_name: "test_last_name", - email: "foo@example.com" - } - }, auth(:admin) + post "/arvados/v1/users/setup", + params: { + repo_name: repo_name, + vm_uuid: virtual_machines(:testvm).uuid, + user: { + uuid: 'zzzzz-tpzed-abcdefghijklmno', + first_name: "in_create_test_first_name", + last_name: "test_last_name", + email: "foo@example.com" + } + }, + headers: auth(:admin) assert_response 422 # cannot create another user with same UUID # invoke setup on the same user - post "/arvados/v1/users/setup", { - repo_name: repo_name, - vm_uuid: virtual_machines(:testvm).uuid, - openid_prefix: 'https://www.google.com/accounts/o8/id', - uuid: 'zzzzz-tpzed-abcdefghijklmno', - }, auth(:admin) + post "/arvados/v1/users/setup", + params: { + repo_name: repo_name, + vm_uuid: virtual_machines(:testvm).uuid, + uuid: 'zzzzz-tpzed-abcdefghijklmno', + }, + headers: auth(:admin) response_items = json_response['items'] @@ -84,7 +85,7 @@ class UsersTest < ActionDispatch::IntegrationTest verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository' - verify_link response_items, 'arvados#group', true, 'permission', 'can_read', + verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login', @@ -94,12 +95,13 @@ class UsersTest < ActionDispatch::IntegrationTest end test "setup user in multiple steps and verify response" do - post "/arvados/v1/users/setup", { - openid_prefix: 'http://www.example.com/account', - user: { - email: "foo@example.com" - } - }, auth(:admin) + post "/arvados/v1/users/setup", + params: { + user: { + email: "foo@example.com" + } + }, + headers: auth(:admin) assert_response :success response_items = json_response['items'] @@ -109,22 +111,21 @@ class UsersTest < ActionDispatch::IntegrationTest assert_not_nil created['email'], 'expected non-nil email' assert_equal created['email'], 'foo@example.com', 'expected input email' - # three new links: system_group, arvados#user, and 'All users' group. - verify_link response_items, 'arvados#user', true, 'permission', 'can_login', - created['uuid'], created['email'], 'arvados#user', false, 'arvados#user' + # two new links: system_group, and 'All users' group. - verify_link response_items, 'arvados#group', true, 'permission', 'can_read', + verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login', nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' # invoke setup with a repository - post "/arvados/v1/users/setup", { - openid_prefix: 'http://www.example.com/account', - repo_name: 'newusertestrepo', - uuid: created['uuid'] - }, auth(:admin) + post "/arvados/v1/users/setup", + params: { + repo_name: 'newusertestrepo', + uuid: created['uuid'] + }, + headers: auth(:admin) assert_response :success @@ -134,7 +135,7 @@ class UsersTest < ActionDispatch::IntegrationTest assert_equal 'foo@example.com', created['email'], 'expected input email' # verify links - verify_link response_items, 'arvados#group', true, 'permission', 'can_read', + verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', @@ -144,14 +145,15 @@ class UsersTest < ActionDispatch::IntegrationTest nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' # invoke setup with a vm_uuid - post "/arvados/v1/users/setup", { - vm_uuid: virtual_machines(:testvm).uuid, - openid_prefix: 'http://www.example.com/account', - user: { - email: 'junk_email' + post "/arvados/v1/users/setup", + params: { + vm_uuid: virtual_machines(:testvm).uuid, + user: { + email: 'junk_email' + }, + uuid: created['uuid'] }, - uuid: created['uuid'] - }, auth(:admin) + headers: auth(:admin) assert_response :success @@ -161,7 +163,7 @@ class UsersTest < ActionDispatch::IntegrationTest assert_equal created['email'], 'foo@example.com', 'expected original email' # verify links - verify_link response_items, 'arvados#group', true, 'permission', 'can_read', + verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login', @@ -169,12 +171,13 @@ class UsersTest < ActionDispatch::IntegrationTest end test "setup and unsetup user" do - post "/arvados/v1/users/setup", { - repo_name: 'newusertestrepo', - vm_uuid: virtual_machines(:testvm).uuid, - user: {email: 'foo@example.com'}, - openid_prefix: 'https://www.google.com/accounts/o8/id' - }, auth(:admin) + post "/arvados/v1/users/setup", + params: { + repo_name: 'newusertestrepo', + vm_uuid: virtual_machines(:testvm).uuid, + user: {email: 'foo@example.com'}, + }, + headers: auth(:admin) assert_response :success response_items = json_response['items'] @@ -182,11 +185,9 @@ class UsersTest < ActionDispatch::IntegrationTest assert_not_nil created['uuid'], 'expected uuid for the new user' assert_equal created['email'], 'foo@example.com', 'expected given email' - # five extra links: system_group, login, group, repo and vm - verify_link response_items, 'arvados#user', true, 'permission', 'can_login', - created['uuid'], created['email'], 'arvados#user', false, 'arvados#user' + # four extra links: system_group, login, group, repo and vm - verify_link response_items, 'arvados#group', true, 'permission', 'can_read', + verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', @@ -197,13 +198,39 @@ class UsersTest < ActionDispatch::IntegrationTest verify_link_existence created['uuid'], created['email'], true, true, true, true, false - post "/arvados/v1/users/#{created['uuid']}/unsetup", {}, auth(:admin) + # create a token + token = act_as_system_user do + ApiClientAuthorization.create!(user: User.find_by_uuid(created['uuid']), api_client: ApiClient.all.first).api_token + end + + # share project and collections with the new user + act_as_system_user do + Link.create!(tail_uuid: created['uuid'], + head_uuid: groups(:aproject).uuid, + link_class: 'permission', + name: 'can_manage') + Link.create!(tail_uuid: created['uuid'], + head_uuid: collections(:collection_owned_by_active).uuid, + link_class: 'permission', + name: 'can_read') + Link.create!(tail_uuid: created['uuid'], + head_uuid: collections(:collection_owned_by_active_with_file_stats).uuid, + link_class: 'permission', + name: 'can_write') + end + + assert_equal 1, ApiClientAuthorization.where(user_id: User.find_by_uuid(created['uuid']).id).size, 'expected token not found' + + post "/arvados/v1/users/#{created['uuid']}/unsetup", params: {}, headers: auth(:admin) assert_response :success created2 = json_response assert_not_nil created2['uuid'], 'expected uuid for the newly created user' assert_equal created['uuid'], created2['uuid'], 'expected uuid not found' + assert_equal 0, ApiClientAuthorization.where(user_id: User.find_by_uuid(created['uuid']).id).size, 'token should have been deleted by user unsetup' + # check permissions are deleted + assert_empty Link.where(tail_uuid: created['uuid']) verify_link_existence created['uuid'], created['email'], false, false, false, false, false end @@ -218,37 +245,313 @@ class UsersTest < ActionDispatch::IntegrationTest end test 'merge active into project_viewer account' do - post('/arvados/v1/groups', { - group: { - group_class: 'project', - name: "active user's stuff", - }, - }, auth(:project_viewer)) + post('/arvados/v1/groups', + params: { + group: { + group_class: 'project', + name: "active user's stuff", + }, + }, + headers: auth(:project_viewer)) assert_response(:success) project_uuid = json_response['uuid'] - post('/arvados/v1/users/merge', { - new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token, - new_owner_uuid: project_uuid, - redirect_to_new_user: true, - }, auth(:active_trustedclient)) + post('/arvados/v1/users/merge', + params: { + new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token, + new_owner_uuid: project_uuid, + redirect_to_new_user: true, + }, + headers: auth(:active_trustedclient)) assert_response(:success) - get('/arvados/v1/users/current', {}, auth(:active)) + get('/arvados/v1/users/current', params: {}, headers: auth(:active)) assert_response(:success) assert_equal(users(:project_viewer).uuid, json_response['uuid']) - get('/arvados/v1/authorized_keys/' + authorized_keys(:active).uuid, {}, auth(:active)) + get('/arvados/v1/authorized_keys/' + authorized_keys(:active).uuid, + params: {}, + headers: auth(:active)) assert_response(:success) assert_equal(users(:project_viewer).uuid, json_response['owner_uuid']) assert_equal(users(:project_viewer).uuid, json_response['authorized_user_uuid']) - get('/arvados/v1/repositories/' + repositories(:foo).uuid, {}, auth(:active)) + get('/arvados/v1/repositories/' + repositories(:foo).uuid, + params: {}, + headers: auth(:active)) assert_response(:success) assert_equal(users(:project_viewer).uuid, json_response['owner_uuid']) + assert_equal("#{users(:project_viewer).username}/foo", json_response['name']) - get('/arvados/v1/groups/' + groups(:aproject).uuid, {}, auth(:active)) + get('/arvados/v1/groups/' + groups(:aproject).uuid, + params: {}, + headers: auth(:active)) assert_response(:success) assert_equal(project_uuid, json_response['owner_uuid']) end + + test 'pre-activate user' do + post '/arvados/v1/users', + params: { + "user" => { + "email" => 'foo@example.com', + "is_active" => true, + "username" => "barney" + } + }, + headers: {'HTTP_AUTHORIZATION' => "OAuth2 #{api_token(:admin)}"} + assert_response :success + rp = json_response + assert_not_nil rp["uuid"] + assert_not_nil rp["is_active"] + assert_nil rp["is_admin"] + + get "/arvados/v1/users/#{rp['uuid']}", + params: {format: 'json'}, + headers: auth(:admin) + assert_response :success + assert_equal rp["uuid"], json_response['uuid'] + assert_nil json_response['is_admin'] + assert_equal true, json_response['is_active'] + assert_equal 'foo@example.com', json_response['email'] + assert_equal 'barney', json_response['username'] + end + + test 'merge with repository name conflict' do + post('/arvados/v1/groups', + params: { + group: { + group_class: 'project', + name: "active user's stuff", + }, + }, + headers: auth(:project_viewer)) + assert_response(:success) + project_uuid = json_response['uuid'] + + post('/arvados/v1/repositories/', + params: { :repository => { :name => "#{users(:project_viewer).username}/foo", :owner_uuid => users(:project_viewer).uuid } }, + headers: auth(:project_viewer)) + assert_response(:success) + + post('/arvados/v1/users/merge', + params: { + new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token, + new_owner_uuid: project_uuid, + redirect_to_new_user: true, + }, + headers: auth(:active_trustedclient)) + assert_response(:success) + + get('/arvados/v1/repositories/' + repositories(:foo).uuid, + params: {}, + headers: auth(:active)) + assert_response(:success) + assert_equal(users(:project_viewer).uuid, json_response['owner_uuid']) + assert_equal("#{users(:project_viewer).username}/migratedfoo", json_response['name']) + + end + + test "cannot set is_active to false directly" do + post('/arvados/v1/users', + params: { + user: { + email: "bob@example.com", + username: "bobby" + }, + }, + headers: auth(:admin)) + assert_response(:success) + user = json_response + assert_equal false, user['is_active'] + + token = act_as_system_user do + ApiClientAuthorization.create!(user: User.find_by_uuid(user['uuid']), api_client: ApiClient.all.first).api_token + end + post("/arvados/v1/user_agreements/sign", + params: {uuid: 'zzzzz-4zz18-t68oksiu9m80s4y'}, + headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}) + assert_response :success + + post("/arvados/v1/users/#{user['uuid']}/activate", + params: {}, + headers: auth(:admin)) + assert_response(:success) + user = json_response + assert_equal true, user['is_active'] + + put("/arvados/v1/users/#{user['uuid']}", + params: { + user: {is_active: false} + }, + headers: auth(:admin)) + assert_response 422 + end + + test "cannot self activate when AutoSetupNewUsers is false" do + Rails.configuration.Users.NewUsersAreActive = false + Rails.configuration.Users.AutoSetupNewUsers = false + + user = nil + token = nil + act_as_system_user do + user = User.create!(email: "bob@example.com", username: "bobby") + ap = ApiClientAuthorization.create!(user: user, api_client: ApiClient.all.first) + token = ap.api_token + end + + get("/arvados/v1/users/#{user['uuid']}", + params: {}, + headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}) + assert_response(:success) + user = json_response + assert_equal false, user['is_active'] + + post("/arvados/v1/users/#{user['uuid']}/activate", + params: {}, + headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}) + assert_response 422 + assert_match(/Cannot activate without being invited/, json_response['errors'][0]) + end + + + test "cannot self activate after unsetup" do + Rails.configuration.Users.NewUsersAreActive = false + Rails.configuration.Users.AutoSetupNewUsers = false + + user = nil + token = nil + act_as_system_user do + user = User.create!(email: "bob@example.com", username: "bobby") + ap = ApiClientAuthorization.create!(user: user, api_client_id: 0) + token = ap.api_token + end + + post("/arvados/v1/users/setup", + params: {uuid: user['uuid']}, + headers: auth(:admin)) + assert_response :success + + post("/arvados/v1/users/#{user['uuid']}/activate", + params: {}, + headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}) + assert_response 403 + assert_match(/Cannot activate without user agreements/, json_response['errors'][0]) + + post("/arvados/v1/user_agreements/sign", + params: {uuid: 'zzzzz-4zz18-t68oksiu9m80s4y'}, + headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}) + assert_response :success + + post("/arvados/v1/users/#{user['uuid']}/activate", + params: {}, + headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}) + assert_response :success + + get("/arvados/v1/users/#{user['uuid']}", + params: {}, + headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}) + assert_response(:success) + userJSON = json_response + assert_equal true, userJSON['is_active'] + + post("/arvados/v1/users/#{user['uuid']}/unsetup", + params: {}, + headers: auth(:admin)) + assert_response :success + + # Need to get a new token, the old one was invalidated by the unsetup call + act_as_system_user do + ap = ApiClientAuthorization.create!(user: user, api_client_id: 0) + token = ap.api_token + end + + get("/arvados/v1/users/#{user['uuid']}", + params: {}, + headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}) + assert_response(:success) + userJSON = json_response + assert_equal false, userJSON['is_active'] + + post("/arvados/v1/users/#{user['uuid']}/activate", + params: {}, + headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}) + assert_response 422 + assert_match(/Cannot activate without being invited/, json_response['errors'][0]) + end + + test "bypass_federation only accepted for admins" do + get "/arvados/v1/users", + params: { + bypass_federation: true + }, + headers: auth(:admin) + + assert_response :success + + get "/arvados/v1/users", + params: { + bypass_federation: true + }, + headers: auth(:active) + + assert_response 403 + end + + test "disabling system root user not permitted" do + put("/arvados/v1/users/#{users(:system_user).uuid}", + params: { + user: {is_admin: false} + }, + headers: auth(:admin)) + assert_response 422 + + post("/arvados/v1/users/#{users(:system_user).uuid}/unsetup", + params: {}, + headers: auth(:admin)) + assert_response 422 + end + + test "creating users only accepted for admins" do + assert_equal false, users(:active).is_admin + post '/arvados/v1/users', + params: { + "user" => { + "email" => 'foo@example.com', + "username" => "barney" + } + }, + headers: auth(:active) + assert_response 403 + end + + test "create users assigns the system root user as their owner" do + post '/arvados/v1/users', + params: { + "user" => { + "email" => 'foo@example.com', + "username" => "barney" + } + }, + headers: auth(:admin) + assert_response :success + assert_not_nil json_response["uuid"] + assert_equal users(:system_user).uuid, json_response["owner_uuid"] + end + + test "create users ignores provided owner_uuid field" do + assert_equal false, users(:admin).uuid == users(:system_user).uuid + post '/arvados/v1/users', + params: { + "user" => { + "email" => 'foo@example.com', + "owner_uuid" => users(:admin).uuid, + "username" => "barney" + } + }, + headers: auth(:admin) + assert_response :success + assert_not_nil json_response["uuid"] + assert_equal users(:system_user).uuid, json_response["owner_uuid"] + end end