1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
6 require 'helpers/users_test_helper'
8 class Arvados::V1::UsersControllerTest < ActionController::TestCase
9 include CurrentApiClient
10 include UsersTestHelper
13 @initial_link_count = Link.count
14 @vm_uuid = virtual_machines(:testvm).uuid
15 ActionMailer::Base.deliveries = []
16 Rails.configuration.Users.ActivatedUsersAreVisibleToOthers = false
19 test "activate a user after signing UA" do
20 authorize_with :inactive_but_signed_user_agreement
21 post :activate, params: {id: users(:inactive_but_signed_user_agreement).uuid}
22 assert_response :success
23 assert_not_nil assigns(:object)
24 me = JSON.parse(@response.body)
25 assert_equal true, me['is_active']
28 test "refuse to activate a user before signing UA" do
30 required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
35 Collection.uuid_like_pattern).
38 assert required_uuids.length > 0
40 signed_uuids = Link.where(owner_uuid: system_user_uuid,
41 link_class: 'signature',
43 tail_uuid: users(:inactive).uuid,
44 head_uuid: required_uuids).
47 assert_equal 0, signed_uuids.length
50 authorize_with :inactive
51 assert_equal false, users(:inactive).is_active
53 post :activate, params: {id: users(:inactive).uuid}
57 assert resp['errors'].first.include? 'Cannot activate without user agreements'
58 assert_nil resp['is_active']
61 test "activate an already-active user" do
62 authorize_with :active
63 post :activate, params: {id: users(:active).uuid}
64 assert_response :success
65 me = JSON.parse(@response.body)
66 assert_equal true, me['is_active']
69 test "respond 401 if given token exists but user record is missing" do
70 authorize_with :valid_token_deleted_user
71 get :current, format: :json
75 test "create new user with user as input" do
77 post :create, params: {
79 first_name: "test_first_name",
80 last_name: "test_last_name",
81 email: "foo@example.com"
84 assert_response :success
85 created = JSON.parse(@response.body)
86 assert_equal 'test_first_name', created['first_name']
87 assert_not_nil created['uuid'], 'expected uuid for the newly created user'
88 assert_not_nil created['email'], 'expected non-nil email'
89 assert_nil created['identity_url'], 'expected no identity_url'
92 test "create new user with empty username" do
94 post :create, params: {
96 first_name: "test_first_name",
97 last_name: "test_last_name",
101 assert_response :success
102 created = JSON.parse(@response.body)
103 assert_equal 'test_first_name', created['first_name']
104 assert_not_nil created['uuid'], 'expected uuid for the newly created user'
105 assert_nil created['email'], 'expected no email'
106 assert_nil created['username'], 'expected no username'
109 test "update user with empty username" do
110 authorize_with :admin
111 user = users('spectator')
112 assert_not_nil user['username']
113 put :update, params: {
114 id: users('spectator')['uuid'],
119 assert_response :success
120 updated = JSON.parse(@response.body)
121 assert_nil updated['username'], 'expected no username'
124 test "create user with user and vm as input" do
125 authorize_with :admin
127 post :setup, params: {
129 uuid: 'zzzzz-tpzed-abcdefghijklmno',
130 first_name: "in_create_test_first_name",
131 last_name: "test_last_name",
132 email: "foo@example.com"
135 assert_response :success
136 response_items = JSON.parse(@response.body)['items']
138 created = find_obj_in_resp response_items, 'User', nil
140 assert_equal 'in_create_test_first_name', created['first_name']
141 assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
142 assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
143 assert_not_nil created['email'], 'expected non-nil email'
144 assert_nil created['identity_url'], 'expected no identity_url'
146 # added links: vm permission, 'all users' group
149 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
150 'All users', created['uuid'], 'arvados#group', true, 'Group'
152 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
153 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
155 verify_system_group_permission_link_for created['uuid']
158 test "setup user with bogus uuid and expect error" do
159 authorize_with :admin
161 post :setup, params: {
165 response_body = JSON.parse(@response.body)
166 response_errors = response_body['errors']
167 assert_not_nil response_errors, 'Expected error in response'
168 assert (response_errors.first.include? 'Path not found'), 'Expected 404'
171 test "setup user with bogus uuid in user and expect error" do
172 authorize_with :admin
174 post :setup, params: {
175 user: {uuid: 'bogus_uuid'},
178 response_body = JSON.parse(@response.body)
179 response_errors = response_body['errors']
180 assert_not_nil response_errors, 'Expected error in response'
181 assert (response_errors.first.include? 'ArgumentError: Require user email'),
182 'Expected RuntimeError'
185 test "setup user with no uuid and user, expect error" do
186 authorize_with :admin
188 post :setup, params: {
191 response_body = JSON.parse(@response.body)
192 response_errors = response_body['errors']
193 assert_not_nil response_errors, 'Expected error in response'
194 assert (response_errors.first.include? 'Required uuid or user'),
195 'Expected ArgumentError'
198 test "setup user with no uuid and email, expect error" do
199 authorize_with :admin
201 post :setup, params: {
205 response_body = JSON.parse(@response.body)
206 response_errors = response_body['errors']
207 assert_not_nil response_errors, 'Expected error in response'
208 assert (response_errors.first.include? '<ArgumentError: Require user email'),
209 'Expected ArgumentError'
212 test "invoke setup with existing uuid and vm permission, and verify links" do
213 authorize_with :admin
214 inactive_user = users(:inactive)
216 post :setup, params: {
217 uuid: users(:inactive).uuid,
221 assert_response :success
223 response_items = JSON.parse(@response.body)['items']
224 resp_obj = find_obj_in_resp response_items, 'User', nil
226 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
227 assert_equal inactive_user['uuid'], resp_obj['uuid']
228 assert_equal inactive_user['email'], resp_obj['email'],
229 'expecting inactive user email'
231 # expect vm permission link
232 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
233 @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
236 test "invoke setup with existing uuid but different email, expect original email" do
237 authorize_with :admin
238 inactive_user = users(:inactive)
240 post :setup, params: {
241 uuid: inactive_user['uuid'],
242 user: {email: 'junk_email'}
245 assert_response :success
247 response_items = JSON.parse(@response.body)['items']
248 resp_obj = find_obj_in_resp response_items, 'User', nil
250 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
251 assert_equal inactive_user['uuid'], resp_obj['uuid']
252 assert_equal inactive_user['email'], resp_obj['email'],
253 'expecting inactive user email'
256 test "setup user with valid email and repo(ignored) as input" do
257 authorize_with :admin
259 post :setup, params: {
260 repo_name: 'usertestrepo',
261 user: {email: 'foo@example.com'},
264 assert_response :success
265 response_items = JSON.parse(@response.body)['items']
266 response_object = find_obj_in_resp response_items, 'User', nil
267 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
268 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
270 # added links: system_group, 'all users' group.
274 test "setup user with fake vm and expect error" do
275 authorize_with :admin
277 post :setup, params: {
278 vm_uuid: 'no_such_vm',
279 user: {email: 'foo@example.com'},
282 response_body = JSON.parse(@response.body)
283 response_errors = response_body['errors']
284 assert_not_nil response_errors, 'Expected error in response'
285 assert (response_errors.first.include? "No vm found for no_such_vm"),
286 'Expected RuntimeError: No vm found for no_such_vm'
289 test "setup user with valid email and real vm as input" do
290 authorize_with :admin
292 post :setup, params: {
294 user: {email: 'foo@example.com'}
297 assert_response :success
298 response_items = JSON.parse(@response.body)['items']
299 response_object = find_obj_in_resp response_items, 'User', nil
300 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
301 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
303 # added links; system_group, 'all users' group, vm.
307 test "setup user with valid email, no vm and no repo as input" do
308 authorize_with :admin
310 post :setup, params: {
311 user: {email: 'foo@example.com'},
314 assert_response :success
315 response_items = JSON.parse(@response.body)['items']
316 response_object = find_obj_in_resp response_items, 'User', nil
317 assert_not_nil response_object['uuid'], 'expected uuid for new user'
318 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
320 # added links; system_group, 'all users' group.
323 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
324 'All users', response_object['uuid'], 'arvados#group', true, 'Group'
326 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
327 nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
330 test "setup user with email, first name, and vm uuid" do
331 authorize_with :admin
333 post :setup, params: {
336 first_name: 'test_first_name',
337 email: 'foo@example.com'
341 assert_response :success
342 response_items = JSON.parse(@response.body)['items']
343 response_object = find_obj_in_resp response_items, 'User', nil
344 assert_not_nil response_object['uuid'], 'expected uuid for new user'
345 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
346 assert_equal 'test_first_name', response_object['first_name'],
347 'expecting first name'
349 # added links: system_group, 'all users' group, vm.
353 test "setup user with an existing user email and check different object is created" do
354 authorize_with :admin
355 inactive_user = users(:inactive)
357 post :setup, params: {
359 email: inactive_user['email']
363 assert_response :success
364 response_items = JSON.parse(@response.body)['items']
365 response_object = find_obj_in_resp response_items, 'User', nil
366 assert_not_nil response_object['uuid'], 'expected uuid for new user'
367 assert_not_equal response_object['uuid'], inactive_user['uuid'],
368 'expected different uuid after create operation'
369 assert_equal inactive_user['email'], response_object['email'], 'expected given email'
370 # added links: system_group, 'all users' group.
374 test "setup user with openid prefix" do
375 authorize_with :admin
377 post :setup, params: {
379 first_name: "in_create_test_first_name",
380 last_name: "test_last_name",
381 email: "foo@example.com"
385 assert_response :success
387 response_items = JSON.parse(@response.body)['items']
388 created = find_obj_in_resp response_items, 'User', nil
390 assert_equal 'in_create_test_first_name', created['first_name']
391 assert_not_nil created['uuid'], 'expected uuid for new user'
392 assert_not_nil created['email'], 'expected non-nil email'
393 assert_nil created['identity_url'], 'expected no identity_url'
395 # added links: system_group, 'all users' group.
398 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
399 'All users', created['uuid'], 'arvados#group', true, 'Group'
401 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
402 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
405 test "setup user with user and vm, and verify links" do
406 authorize_with :admin
408 post :setup, params: {
410 first_name: "in_create_test_first_name",
411 last_name: "test_last_name",
412 email: "foo@example.com"
417 assert_response :success
419 response_items = JSON.parse(@response.body)['items']
420 created = find_obj_in_resp response_items, 'User', nil
422 assert_equal 'in_create_test_first_name', created['first_name']
423 assert_not_nil created['uuid'], 'expected uuid for new user'
424 assert_not_nil created['email'], 'expected non-nil email'
425 assert_nil created['identity_url'], 'expected no identity_url'
427 # added links: system_group, 'all users' group, vm
430 # system_group isn't part of the response. See User#add_system_group_permission_link
432 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
433 'All users', created['uuid'], 'arvados#group', true, 'Group'
435 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
436 @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
439 test "create user as non admin user and expect error" do
440 authorize_with :active
442 post :create, params: {
443 user: {email: 'foo@example.com'}
446 response_body = JSON.parse(@response.body)
447 response_errors = response_body['errors']
448 assert_not_nil response_errors, 'Expected error in response'
449 assert (response_errors.first.include? 'PermissionDenied'),
450 'Expected PermissionDeniedError'
453 test "setup user as non admin user and expect error" do
454 authorize_with :active
456 post :setup, params: {
457 user: {email: 'foo@example.com'}
460 response_body = JSON.parse(@response.body)
461 response_errors = response_body['errors']
462 assert_not_nil response_errors, 'Expected error in response'
463 assert (response_errors.first.include? 'Forbidden'),
464 'Expected Forbidden error'
467 test "setup active user with no vm" do
468 authorize_with :admin
469 active_user = users(:active)
471 post :setup, params: {
472 uuid: active_user['uuid']
475 assert_response :success
477 response_items = JSON.parse(@response.body)['items']
478 created = find_obj_in_resp response_items, 'User', nil
480 assert_equal active_user[:email], created['email'], 'expected input email'
483 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
484 'All users', created['uuid'], 'arvados#group', true, 'Group'
486 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
487 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
490 test "setup active user with vm and no repo" do
491 authorize_with :admin
492 active_user = users(:active)
494 post :setup, params: {
496 uuid: active_user['uuid'],
500 assert_response :success
502 response_items = JSON.parse(@response.body)['items']
503 created = find_obj_in_resp response_items, 'User', nil
505 assert_equal active_user['email'], created['email'], 'expected original email'
508 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
509 'All users', created['uuid'], 'arvados#group', true, 'Group'
511 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
512 @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
515 test "unsetup active user" do
516 active_user = users(:active)
517 assert_not_nil active_user['uuid'], 'expected uuid for the active user'
518 assert active_user['is_active'], 'expected is_active for active user'
520 verify_link_existence active_user['uuid'], active_user['email'],
521 false, true, true, true, true
523 authorize_with :admin
525 # now unsetup this user
526 post :unsetup, params: {id: active_user['uuid']}
527 assert_response :success
529 response_user = JSON.parse(@response.body)
530 assert_not_nil response_user['uuid'], 'expected uuid for the upsetup user'
531 assert_equal active_user['uuid'], response_user['uuid'], 'expected uuid not found'
532 assert !response_user['is_active'], 'expected user to be inactive'
533 assert !response_user['is_invited'], 'expected user to be uninvited'
535 verify_link_existence response_user['uuid'], response_user['email'],
536 false, false, false, false, false
538 active_user = User.find_by_uuid(users(:active).uuid)
539 readable_groups = active_user.groups_i_can(:read)
540 all_users_group = Group.all.collect(&:uuid).select { |g| g.match(/-f+$/) }
541 refute_includes(readable_groups, all_users_group,
542 "active user can read All Users group after being deactivated")
543 assert_equal(false, active_user.is_invited,
544 "active user is_invited after being deactivated & reloaded")
547 test "setup user with send notification param false and verify no email" do
548 authorize_with :admin
550 post :setup, params: {
551 send_notification_email: 'false',
553 email: "foo@example.com"
557 assert_response :success
558 response_items = JSON.parse(@response.body)['items']
559 created = find_obj_in_resp response_items, 'User', nil
560 assert_not_nil created['uuid'], 'expected uuid for the new user'
561 assert_equal created['email'], 'foo@example.com', 'expected given email'
563 setup_email = ActionMailer::Base.deliveries.last
564 assert_nil setup_email, 'expected no setup email'
567 test "setup user with send notification param true and verify email" do
568 authorize_with :admin
570 Rails.configuration.Users.UserSetupMailText = %{
571 <% if not @user.full_name.empty? -%>
572 <%= @user.full_name %>,
577 Your Arvados shell account has been set up. Please visit the virtual machines page <% if Rails.configuration.Services.Workbench1.ExternalURL %>at
579 <%= Rails.configuration.Services.Workbench1.ExternalURL %><%= "/" if !Rails.configuration.Services.Workbench1.ExternalURL.to_s.end_with?("/") %>users/<%= @user.uuid%>/virtual_machines <% else %><% end %>
581 for connection instructions.
587 post :setup, params: {
588 send_notification_email: 'true',
590 email: "foo@example.com"
594 assert_response :success
595 response_items = JSON.parse(@response.body)['items']
596 created = find_obj_in_resp response_items, 'User', nil
597 assert_not_nil created['uuid'], 'expected uuid for the new user'
598 assert_equal created['email'], 'foo@example.com', 'expected given email'
600 setup_email = ActionMailer::Base.deliveries.last
601 assert_not_nil setup_email, 'Expected email after setup'
603 assert_equal Rails.configuration.Users.UserNotifierEmailFrom, setup_email.from[0]
604 assert_equal 'foo@example.com', setup_email.to[0]
605 assert_equal 'Welcome to Arvados - account enabled', setup_email.subject
606 assert (setup_email.body.to_s.include? 'Your Arvados shell account has been set up'),
607 'Expected Your Arvados shell account has been set up in email body'
608 assert (setup_email.body.to_s.include? "#{Rails.configuration.Services.Workbench1.ExternalURL}users/#{created['uuid']}/virtual_machines"), 'Expected virtual machines url in email body'
611 test "setup inactive user by changing is_active to true" do
612 authorize_with :admin
613 active_user = users(:active)
615 put :update, params: {
616 id: active_user['uuid'],
621 assert_response :success
622 assert_equal active_user['uuid'], json_response['uuid']
623 updated = User.where(uuid: active_user['uuid']).first
624 assert_equal(true, updated.is_active)
625 assert_equal({read: true, write: true}, updated.group_permissions[all_users_group_uuid])
628 test "non-admin user can get basic information about readable users" do
629 authorize_with :spectator
631 check_non_admin_index
632 check_readable_users_index [:spectator], [:inactive, :active]
633 json_response["items"].each do |u|
634 if u["uuid"] == users(:spectator).uuid
635 assert_equal true, u["can_write"]
636 assert_equal true, u["can_manage"]
641 test "non-admin user gets only safe attributes from users#show" do
642 g = act_as_system_user do
643 create :group, group_class: "role"
645 users = create_list :active_user, 2, join_groups: [g]
646 token = create :token, user: users[0]
647 authorize_with_token token
648 get :show, params: {id: users[1].uuid}
652 [2, 4].each do |limit|
653 test "non-admin user can limit index to #{limit}" do
654 g = act_as_system_user do
655 create :group, group_class: "role"
657 users = create_list :active_user, 4, join_groups: [g]
658 token = create :token, user: users[0]
660 authorize_with_token token
661 get(:index, params: {limit: limit})
662 check_non_admin_index
663 assert_equal(limit, json_response["items"].size,
664 "non-admin index limit was ineffective")
668 test "admin has full index powers" do
669 authorize_with :admin
670 check_inactive_user_findable
673 test "reader token can grant admin index powers" do
674 authorize_with :spectator
675 check_inactive_user_findable(reader_tokens: [api_token(:admin)])
678 test "admin can filter on user.is_active" do
679 authorize_with :admin
680 get(:index, params: {filters: [["is_active", "=", "true"]]})
681 assert_response :success
682 check_readable_users_index [:active, :spectator], [:inactive]
685 test "admin can search where user.is_active" do
686 authorize_with :admin
687 get(:index, params: {where: {is_active: true}})
688 assert_response :success
689 check_readable_users_index [:active, :spectator], [:inactive]
692 test "update active_no_prefs user profile and expect notification email" do
693 authorize_with :admin
695 put :update, params: {
696 id: users(:active_no_prefs).uuid,
698 prefs: {:profile => {'organization' => 'example.com'}}
701 assert_response :success
704 ActionMailer::Base.deliveries.andand.each do |email|
705 if email.subject == "Profile created by #{users(:active_no_prefs).email}"
710 assert_equal true, found_email, 'Expected email after creating profile'
713 test "update active_no_prefs_profile user profile and expect notification email" do
714 authorize_with :admin
717 user[:prefs] = users(:active_no_prefs_profile_no_getting_started_shown).prefs
718 user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
719 put :update, params: {
720 id: users(:active_no_prefs_profile_no_getting_started_shown).uuid,
723 assert_response :success
726 ActionMailer::Base.deliveries.andand.each do |email|
727 if email.subject == "Profile created by #{users(:active_no_prefs_profile_no_getting_started_shown).email}"
732 assert_equal true, found_email, 'Expected email after creating profile'
735 test "update active user profile and expect no notification email" do
736 authorize_with :admin
738 put :update, params: {
739 id: users(:active).uuid,
741 prefs: {:profile => {'organization' => 'anotherexample.com'}}
744 assert_response :success
747 ActionMailer::Base.deliveries.andand.each do |email|
748 if email.subject == "Profile created by #{users(:active).email}"
753 assert_equal false, found_email, 'Expected no email after updating profile'
756 test "user API response includes writable_by" do
757 authorize_with :active
759 assert_response :success
760 assert_includes(json_response["writable_by"], users(:active).uuid,
761 "user's writable_by should include self")
762 assert_includes(json_response["writable_by"], users(:active).owner_uuid,
763 "user's writable_by should include its owner_uuid")
766 test "merge with redirect_to_user_uuid=false" do
767 authorize_with :project_viewer_trustedclient
768 tok = api_client_authorizations(:project_viewer).api_token
769 post :merge, params: {
770 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
771 new_owner_uuid: users(:active).uuid,
772 redirect_to_new_user: false,
774 assert_response(:success)
775 assert_nil(User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
777 # because redirect_to_new_user=false, token owned by
778 # project_viewer should be deleted
779 auth = ApiClientAuthorization.validate(token: tok)
783 test "merge remote to local as admin" do
784 authorize_with :admin
786 remoteuser = User.create!(uuid: "zbbbb-tpzed-remotremotremot")
787 tok = ApiClientAuthorization.create!(user: remoteuser, api_client: api_clients(:untrusted)).api_token
789 auth = ApiClientAuthorization.validate(token: tok)
791 assert_nil(remoteuser.redirect_to_user_uuid)
793 post :merge, params: {
794 new_user_uuid: users(:active).uuid,
795 old_user_uuid: remoteuser.uuid,
796 new_owner_uuid: users(:active).uuid,
797 redirect_to_new_user: true,
799 assert_response(:success)
801 assert_equal(users(:active).uuid, remoteuser.redirect_to_user_uuid)
803 # token owned by remoteuser should be deleted
804 auth = ApiClientAuthorization.validate(token: tok)
808 test "refuse to merge user into self" do
809 authorize_with(:active_trustedclient)
810 post(:merge, params: {
811 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
812 new_owner_uuid: users(:active).uuid,
813 redirect_to_new_user: true,
818 [[:active, :project_viewer_trustedclient],
819 [:active_trustedclient, :project_viewer]].each do |src, dst|
820 test "refuse to merge with untrusted token (#{src} -> #{dst})" do
822 post(:merge, params: {
823 new_user_token: api_client_authorizations(dst).api_token,
824 new_owner_uuid: api_client_authorizations(dst).user.uuid,
825 redirect_to_new_user: true,
831 [[:expired_trustedclient, :project_viewer_trustedclient],
832 [:project_viewer_trustedclient, :expired_trustedclient]].each do |src, dst|
833 test "refuse to merge with expired token (#{src} -> #{dst})" do
835 post(:merge, params: {
836 new_user_token: api_client_authorizations(dst).api_token,
837 new_owner_uuid: api_client_authorizations(dst).user.uuid,
838 redirect_to_new_user: true,
844 [['src', :active_trustedclient],
845 ['dst', :project_viewer_trustedclient]].each do |which_scoped, auth|
846 test "refuse to merge with scoped #{which_scoped} token" do
847 act_as_system_user do
848 api_client_authorizations(auth).update(scopes: ["GET /", "POST /", "PUT /"])
850 authorize_with(:active_trustedclient)
851 post(:merge, params: {
852 new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token,
853 new_owner_uuid: users(:project_viewer).uuid,
854 redirect_to_new_user: true,
860 test "refuse to merge if new_owner_uuid is not writable" do
861 authorize_with(:project_viewer_trustedclient)
862 post(:merge, params: {
863 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
864 new_owner_uuid: groups(:anonymously_accessible_project).uuid,
865 redirect_to_new_user: true,
870 test "refuse to merge if new_owner_uuid is empty" do
871 authorize_with(:project_viewer_trustedclient)
872 post(:merge, params: {
873 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
875 redirect_to_new_user: true,
880 test "refuse to merge if new_owner_uuid is not provided" do
881 authorize_with(:project_viewer_trustedclient)
882 post(:merge, params: {
883 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
884 redirect_to_new_user: true,
889 test "refuse to update redirect_to_user_uuid directly" do
890 authorize_with(:active_trustedclient)
891 patch(:update, params: {
892 id: users(:active).uuid,
894 redirect_to_user_uuid: users(:active).uuid,
900 test "merge 'project_viewer' account into 'active' account" do
901 authorize_with(:project_viewer_trustedclient)
902 post(:merge, params: {
903 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
904 new_owner_uuid: users(:active).uuid,
905 redirect_to_new_user: true,
907 assert_response(:success)
908 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
910 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
912 assert_not_nil(auth.user)
913 assert_equal(users(:active).uuid, auth.user.uuid)
917 test "merge 'project_viewer' account into 'active' account using uuids" do
918 authorize_with(:admin)
919 post(:merge, params: {
920 old_user_uuid: users(:project_viewer).uuid,
921 new_user_uuid: users(:active).uuid,
922 new_owner_uuid: users(:active).uuid,
923 redirect_to_new_user: true,
925 assert_response(:success)
926 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
928 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
930 assert_not_nil(auth.user)
931 assert_equal(users(:active).uuid, auth.user.uuid)
934 test "merge 'project_viewer' account into 'active' account using uuids denied for non-admin" do
935 authorize_with(:active)
936 post(:merge, params: {
937 old_user_uuid: users(:project_viewer).uuid,
938 new_user_uuid: users(:active).uuid,
939 new_owner_uuid: users(:active).uuid,
940 redirect_to_new_user: true,
943 assert_nil(users(:project_viewer).redirect_to_user_uuid)
946 test "merge 'project_viewer' account into 'active' account using uuids denied missing old_user_uuid" do
947 authorize_with(:admin)
948 post(:merge, params: {
949 new_user_uuid: users(:active).uuid,
950 new_owner_uuid: users(:active).uuid,
951 redirect_to_new_user: true,
954 assert_nil(users(:project_viewer).redirect_to_user_uuid)
957 test "merge 'project_viewer' account into 'active' account using uuids denied missing new_user_uuid" do
958 authorize_with(:admin)
959 post(:merge, params: {
960 old_user_uuid: users(:project_viewer).uuid,
961 new_owner_uuid: users(:active).uuid,
962 redirect_to_new_user: true,
965 assert_nil(users(:project_viewer).redirect_to_user_uuid)
968 test "merge 'project_viewer' account into 'active' account using uuids denied bogus old_user_uuid" do
969 authorize_with(:admin)
970 post(:merge, params: {
971 old_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
972 new_user_uuid: users(:active).uuid,
973 new_owner_uuid: users(:active).uuid,
974 redirect_to_new_user: true,
977 assert_nil(users(:project_viewer).redirect_to_user_uuid)
980 test "merge 'project_viewer' account into 'active' account using uuids denied bogus new_user_uuid" do
981 authorize_with(:admin)
982 post(:merge, params: {
983 old_user_uuid: users(:project_viewer).uuid,
984 new_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
985 new_owner_uuid: users(:active).uuid,
986 redirect_to_new_user: true,
989 assert_nil(users(:project_viewer).redirect_to_user_uuid)
992 test "batch update fails for non-admin" do
993 authorize_with(:active)
994 patch(:batch_update, params: {updates: {}})
998 test "batch update" do
999 existinguuid = 'remot-tpzed-foobarbazwazqux'
1000 newuuid = 'remot-tpzed-newnarnazwazqux'
1001 unchanginguuid = 'remot-tpzed-nochangingattrs'
1002 conflictinguuid1 = 'remot-tpzed-conflictingnam1'
1003 conflictinguuid2 = 'remot-tpzed-conflictingnam2'
1004 act_as_system_user do
1005 User.create!(uuid: existinguuid, email: 'root@existing.example.com')
1006 User.create!(uuid: unchanginguuid, email: 'root@unchanging.example.com', prefs: {'foo' => {'bar' => 'baz'}})
1008 assert_equal(1, Log.where(object_uuid: unchanginguuid).count)
1010 Rails.configuration.Login.LoginCluster = 'remot'
1012 authorize_with(:admin)
1013 patch(:batch_update,
1017 'first_name' => 'root',
1018 'email' => 'root@remot.example.com',
1019 'is_active' => true,
1021 'prefs' => {'foo' => 'bar'},
1022 'is_invited' => true
1025 'first_name' => 'noot',
1026 'email' => 'root@remot.example.com',
1028 'is_invited' => true
1031 'email' => 'root@unchanging.example.com',
1032 'prefs' => {'foo' => {'bar' => 'baz'}},
1033 'is_invited' => true
1035 conflictinguuid1 => {
1036 'email' => 'root@conflictingname1.example.com',
1037 'username' => 'active',
1038 'is_invited' => true
1040 conflictinguuid2 => {
1041 'email' => 'root@conflictingname2.example.com',
1042 'username' => 'federatedactive',
1043 'is_invited' => true
1046 assert_response(:success)
1048 assert_equal('root', User.find_by_uuid(existinguuid).first_name)
1049 assert_equal('root@remot.example.com', User.find_by_uuid(existinguuid).email)
1050 assert_equal(true, User.find_by_uuid(existinguuid).is_active)
1051 assert_equal(true, User.find_by_uuid(existinguuid).is_admin)
1052 assert_equal({'foo' => 'bar'}, User.find_by_uuid(existinguuid).prefs)
1054 assert_equal('noot', User.find_by_uuid(newuuid).first_name)
1055 assert_equal('root@remot.example.com', User.find_by_uuid(newuuid).email)
1057 assert_equal(1, Log.where(object_uuid: unchanginguuid).count)
1060 test 'batch update does not produce spurious log events' do
1061 # test for bug #21304
1063 existinguuid = 'remot-tpzed-foobarbazwazqux'
1064 act_as_system_user do
1065 User.create!(uuid: existinguuid,
1070 assert_equal(1, Log.where(object_uuid: existinguuid).count)
1072 Rails.configuration.Login.LoginCluster = 'remot'
1074 authorize_with(:admin)
1075 patch(:batch_update,
1079 'first_name' => 'root',
1082 'is_active' => true,
1083 'is_invited' => true
1086 assert_response(:success)
1088 assert_equal(1, Log.where(object_uuid: existinguuid).count)
1091 NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "is_admin", "is_invited", "email", "first_name",
1092 "last_name", "username", "can_write", "can_manage"].sort
1094 def check_non_admin_index
1095 assert_response :success
1096 response_items = json_response["items"]
1097 assert_not_nil response_items
1098 response_items.each do |user_data|
1099 check_non_admin_item user_data
1100 assert(user_data["is_active"], "non-admin index returned inactive user")
1104 def check_non_admin_show
1105 assert_response :success
1106 check_non_admin_item json_response
1109 def check_non_admin_item user_data
1110 assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
1111 "data in response had missing or extra attributes")
1112 assert_equal("arvados#user", user_data["kind"])
1116 def check_readable_users_index expect_present, expect_missing
1117 response_uuids = json_response["items"].map { |u| u["uuid"] }
1118 expect_present.each do |user_key|
1119 assert_includes(response_uuids, users(user_key).uuid,
1120 "#{user_key} missing from index")
1122 expect_missing.each do |user_key|
1123 refute_includes(response_uuids, users(user_key).uuid,
1124 "#{user_key} included in index")
1128 def check_inactive_user_findable(params={})
1129 inactive_user = users(:inactive)
1130 get(:index, params: params.merge(filters: [["email", "=", inactive_user.email]]))
1131 assert_response :success
1132 user_list = json_response["items"]
1133 assert_equal(1, user_list.andand.count)
1134 # This test needs to check a column non-admins have no access to,
1135 # to ensure that admins see all user information.
1136 assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
1137 "admin's filtered index did not return inactive user")
1140 def verify_links_added more
1141 assert_equal @initial_link_count+more, Link.count,
1142 "Started with #{@initial_link_count} links, expected #{more} more"
1145 def find_obj_in_resp (response_items, object_type, head_kind=nil)
1147 response_items.each { |x|
1152 if object_type == 'User'
1153 if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
1157 else # looking for a link
1158 if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind