19501: Remove all sharing permissions during unsetup.
[arvados.git] / services / api / test / integration / users_test.rb
index 0288e887f94e83361e59f60a7beba6a7cf62a493..ca143363892cad7065e65d704d1c76bbd7551c83 100644 (file)
@@ -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
@@ -217,4 +244,314 @@ class UsersTest < ActionDispatch::IntegrationTest
     nil
   end
 
+  test 'merge active into project_viewer account' 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/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', 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,
+      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,
+      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,
+      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