19146: Add can_write/can_manage to users#list, fix select=can_*.
[arvados.git] / services / api / test / functional / arvados / v1 / users_controller_test.rb
index a442230a7bd8c3c6167a1e79bc2a69723fb8c2ea..6a7b00a00573f9413a61856d66fd6e6eb3900c65 100644 (file)
@@ -13,6 +13,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     @initial_link_count = Link.count
     @vm_uuid = virtual_machines(:testvm).uuid
     ActionMailer::Base.deliveries = []
+    Rails.configuration.Users.ActivatedUsersAreVisibleToOthers = false
   end
 
   test "activate a user after signing UA" do
@@ -88,13 +89,44 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     assert_nil created['identity_url'], 'expected no identity_url'
   end
 
+  test "create new user with empty username" do
+    authorize_with :admin
+    post :create, params: {
+      user: {
+        first_name: "test_first_name",
+        last_name: "test_last_name",
+        username: ""
+      }
+    }
+    assert_response :success
+    created = JSON.parse(@response.body)
+    assert_equal 'test_first_name', created['first_name']
+    assert_not_nil created['uuid'], 'expected uuid for the newly created user'
+    assert_nil created['email'], 'expected no email'
+    assert_nil created['username'], 'expected no username'
+  end
+
+  test "update user with empty username" do
+    authorize_with :admin
+    user = users('spectator')
+    assert_not_nil user['username']
+    put :update, params: {
+      id: users('spectator')['uuid'],
+      user: {
+        username: ""
+      }
+    }
+    assert_response :success
+    updated = JSON.parse(@response.body)
+    assert_nil updated['username'], 'expected no username'
+  end
+
   test "create user with user, vm and repo as input" do
     authorize_with :admin
     repo_name = 'usertestrepo'
 
     post :setup, params: {
       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",
@@ -149,7 +181,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       user: {uuid: 'bogus_uuid'},
       repo_name: 'usertestrepo',
       vm_uuid: @vm_uuid,
-      openid_prefix: 'https://www.google.com/accounts/o8/id'
     }
     response_body = JSON.parse(@response.body)
     response_errors = response_body['errors']
@@ -164,7 +195,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     post :setup, params: {
       repo_name: 'usertestrepo',
       vm_uuid: @vm_uuid,
-      openid_prefix: 'https://www.google.com/accounts/o8/id'
     }
     response_body = JSON.parse(@response.body)
     response_errors = response_body['errors']
@@ -180,7 +210,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       user: {},
       repo_name: 'usertestrepo',
       vm_uuid: @vm_uuid,
-      openid_prefix: 'https://www.google.com/accounts/o8/id'
     }
     response_body = JSON.parse(@response.body)
     response_errors = response_body['errors']
@@ -243,7 +272,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     post :setup, params: {
       repo_name: 'usertestrepo',
       user: {email: 'foo@example.com'},
-      openid_prefix: 'https://www.google.com/accounts/o8/id'
     }
 
     assert_response :success
@@ -263,7 +291,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       repo_name: 'usertestrepo',
       vm_uuid: 'no_such_vm',
       user: {email: 'foo@example.com'},
-      openid_prefix: 'https://www.google.com/accounts/o8/id'
     }
 
     response_body = JSON.parse(@response.body)
@@ -278,7 +305,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
 
     post :setup, params: {
       repo_name: 'usertestrepo',
-      openid_prefix: 'https://www.google.com/accounts/o8/id',
       vm_uuid: @vm_uuid,
       user: {email: 'foo@example.com'}
     }
@@ -298,7 +324,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
 
     post :setup, params: {
       user: {email: 'foo@example.com'},
-      openid_prefix: 'https://www.google.com/accounts/o8/id'
     }
 
     assert_response :success
@@ -324,7 +349,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     authorize_with :admin
 
     post :setup, params: {
-      openid_prefix: 'https://www.google.com/accounts/o8/id',
       repo_name: 'usertestrepo',
       vm_uuid: @vm_uuid,
       user: {
@@ -350,7 +374,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     inactive_user = users(:inactive)
 
     post :setup, params: {
-      openid_prefix: 'https://www.google.com/accounts/o8/id',
       repo_name: 'usertestrepo',
       user: {
         email: inactive_user['email']
@@ -373,7 +396,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
 
     post :setup, params: {
       repo_name: 'usertestrepo',
-      openid_prefix: 'http://www.example.com/account',
       user: {
         first_name: "in_create_test_first_name",
         last_name: "test_last_name",
@@ -405,25 +427,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
   end
 
-  test "invoke setup with no openid prefix, expect error" do
-    authorize_with :admin
-
-    post :setup, params: {
-      repo_name: 'usertestrepo',
-      user: {
-        first_name: "in_create_test_first_name",
-        last_name: "test_last_name",
-        email: "foo@example.com"
-      }
-    }
-
-    response_body = JSON.parse(@response.body)
-    response_errors = response_body['errors']
-    assert_not_nil response_errors, 'Expected error in response'
-    assert (response_errors.first.include? 'openid_prefix parameter is missing'),
-        'Expected ArgumentError'
-  end
-
   test "setup user with user, vm and repo and verify links" do
     authorize_with :admin
 
@@ -435,7 +438,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
       },
       vm_uuid: @vm_uuid,
       repo_name: 'usertestrepo',
-      openid_prefix: 'https://www.google.com/accounts/o8/id'
     }
 
     assert_response :success
@@ -481,7 +483,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     authorize_with :active
 
     post :setup, params: {
-      openid_prefix: 'https://www.google.com/accounts/o8/id',
       user: {email: 'foo@example.com'}
     }
 
@@ -590,7 +591,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     authorize_with :admin
 
     post :setup, params: {
-      openid_prefix: 'http://www.example.com/account',
       send_notification_email: 'false',
       user: {
         email: "foo@example.com"
@@ -610,8 +610,24 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   test "setup user with send notification param true and verify email" do
     authorize_with :admin
 
+    Rails.configuration.Users.UserSetupMailText = %{
+<% if not @user.full_name.empty? -%>
+<%= @user.full_name %>,
+<% else -%>
+Hi there,
+<% end -%>
+
+Your Arvados shell account has been set up. Please visit the virtual machines page <% if Rails.configuration.Services.Workbench1.ExternalURL %>at
+
+<%= Rails.configuration.Services.Workbench1.ExternalURL %><%= "/" if !Rails.configuration.Services.Workbench1.ExternalURL.to_s.end_with?("/") %>users/<%= @user.uuid%>/virtual_machines <% else %><% end %>
+
+for connection instructions.
+
+Thanks,
+The Arvados team.
+}
+
     post :setup, params: {
-      openid_prefix: 'http://www.example.com/account',
       send_notification_email: 'true',
       user: {
         email: "foo@example.com"
@@ -629,7 +645,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
 
     assert_equal Rails.configuration.Users.UserNotifierEmailFrom, setup_email.from[0]
     assert_equal 'foo@example.com', setup_email.to[0]
-    assert_equal 'Welcome to Arvados - shell account enabled', setup_email.subject
+    assert_equal 'Welcome to Arvados - account enabled', setup_email.subject
     assert (setup_email.body.to_s.include? 'Your Arvados shell account has been set up'),
         'Expected Your Arvados shell account has been set up in email body'
     assert (setup_email.body.to_s.include? "#{Rails.configuration.Services.Workbench1.ExternalURL}users/#{created['uuid']}/virtual_machines"), 'Expected virtual machines url in email body'
@@ -658,11 +674,17 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     get(:index)
     check_non_admin_index
     check_readable_users_index [:spectator], [:inactive, :active]
+    json_response["items"].each do |u|
+      if u["uuid"] == users(:spectator).uuid
+        assert_equal true, u["can_write"]
+        assert_equal true, u["can_manage"]
+      end
+    end
   end
 
   test "non-admin user gets only safe attributes from users#show" do
     g = act_as_system_user do
-      create :group
+      create :group, group_class: "role"
     end
     users = create_list :active_user, 2, join_groups: [g]
     token = create :token, user: users[0]
@@ -674,7 +696,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   [2, 4].each do |limit|
     test "non-admin user can limit index to #{limit}" do
       g = act_as_system_user do
-        create :group
+        create :group, group_class: "role"
       end
       users = create_list :active_user, 4, join_groups: [g]
       token = create :token, user: users[0]
@@ -785,27 +807,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
                     "user's writable_by should include its owner_uuid")
   end
 
-  [
-    [:admin, true],
-    [:active, false],
-  ].each do |auth_user, expect_success|
-    test "update_uuid as #{auth_user}" do
-      authorize_with auth_user
-      orig_uuid = users(:active).uuid
-      post :update_uuid, params: {
-             id: orig_uuid,
-             new_uuid: 'zbbbb-tpzed-abcde12345abcde',
-           }
-      if expect_success
-        assert_response :success
-        assert_empty User.where(uuid: orig_uuid)
-      else
-        assert_response 403
-        assert_not_empty User.where(uuid: orig_uuid)
-      end
-    end
-  end
-
   test "merge with redirect_to_user_uuid=false" do
     authorize_with :project_viewer_trustedclient
     tok = api_client_authorizations(:project_viewer).api_token
@@ -1032,8 +1033,59 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     assert_nil(users(:project_viewer).redirect_to_user_uuid)
   end
 
+  test "batch update fails for non-admin" do
+    authorize_with(:active)
+    patch(:batch_update, params: {updates: {}})
+    assert_response(403)
+  end
+
+  test "batch update" do
+    existinguuid = 'remot-tpzed-foobarbazwazqux'
+    newuuid = 'remot-tpzed-newnarnazwazqux'
+    unchanginguuid = 'remot-tpzed-nochangingattrs'
+    act_as_system_user do
+      User.create!(uuid: existinguuid, email: 'root@existing.example.com')
+      User.create!(uuid: unchanginguuid, email: 'root@unchanging.example.com', prefs: {'foo' => {'bar' => 'baz'}})
+    end
+    assert_equal(1, Log.where(object_uuid: unchanginguuid).count)
+
+    authorize_with(:admin)
+    patch(:batch_update,
+          params: {
+            updates: {
+              existinguuid => {
+                'first_name' => 'root',
+                'email' => 'root@remot.example.com',
+                'is_active' => true,
+                'is_admin' => true,
+                'prefs' => {'foo' => 'bar'},
+              },
+              newuuid => {
+                'first_name' => 'noot',
+                'email' => 'root@remot.example.com',
+                'username' => '',
+              },
+              unchanginguuid => {
+                'email' => 'root@unchanging.example.com',
+                'prefs' => {'foo' => {'bar' => 'baz'}},
+              },
+            }})
+    assert_response(:success)
+
+    assert_equal('root', User.find_by_uuid(existinguuid).first_name)
+    assert_equal('root@remot.example.com', User.find_by_uuid(existinguuid).email)
+    assert_equal(true, User.find_by_uuid(existinguuid).is_active)
+    assert_equal(true, User.find_by_uuid(existinguuid).is_admin)
+    assert_equal({'foo' => 'bar'}, User.find_by_uuid(existinguuid).prefs)
+
+    assert_equal('noot', User.find_by_uuid(newuuid).first_name)
+    assert_equal('root@remot.example.com', User.find_by_uuid(newuuid).email)
+
+    assert_equal(1, Log.where(object_uuid: unchanginguuid).count)
+  end
+
   NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
-                         "last_name", "username"].sort
+                         "last_name", "username", "can_write", "can_manage"].sort
 
   def check_non_admin_index
     assert_response :success