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 = []
18 test "activate a user after signing UA" do
19 authorize_with :inactive_but_signed_user_agreement
20 post :activate, params: {id: users(:inactive_but_signed_user_agreement).uuid}
21 assert_response :success
22 assert_not_nil assigns(:object)
23 me = JSON.parse(@response.body)
24 assert_equal true, me['is_active']
27 test "refuse to activate a user before signing UA" do
29 required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
34 Collection.uuid_like_pattern).
37 assert required_uuids.length > 0
39 signed_uuids = Link.where(owner_uuid: system_user_uuid,
40 link_class: 'signature',
42 tail_uuid: users(:inactive).uuid,
43 head_uuid: required_uuids).
46 assert_equal 0, signed_uuids.length
49 authorize_with :inactive
50 assert_equal false, users(:inactive).is_active
52 post :activate, params: {id: users(:inactive).uuid}
56 assert resp['errors'].first.include? 'Cannot activate without user agreements'
57 assert_nil resp['is_active']
60 test "activate an already-active user" do
61 authorize_with :active
62 post :activate, params: {id: users(:active).uuid}
63 assert_response :success
64 me = JSON.parse(@response.body)
65 assert_equal true, me['is_active']
68 test "respond 401 if given token exists but user record is missing" do
69 authorize_with :valid_token_deleted_user
70 get :current, {format: :json}
74 test "create new user with user as input" do
76 post :create, params: {
78 first_name: "test_first_name",
79 last_name: "test_last_name",
80 email: "foo@example.com"
83 assert_response :success
84 created = JSON.parse(@response.body)
85 assert_equal 'test_first_name', created['first_name']
86 assert_not_nil created['uuid'], 'expected uuid for the newly created user'
87 assert_not_nil created['email'], 'expected non-nil email'
88 assert_nil created['identity_url'], 'expected no identity_url'
91 test "create new user with empty username" do
93 post :create, params: {
95 first_name: "test_first_name",
96 last_name: "test_last_name",
100 assert_response :success
101 created = JSON.parse(@response.body)
102 assert_equal 'test_first_name', created['first_name']
103 assert_not_nil created['uuid'], 'expected uuid for the newly created user'
104 assert_nil created['email'], 'expected no email'
105 assert_nil created['username'], 'expected no username'
108 test "update user with empty username" do
109 authorize_with :admin
110 user = users('spectator')
111 assert_not_nil user['username']
112 put :update, params: {
113 id: users('spectator')['uuid'],
118 assert_response :success
119 updated = JSON.parse(@response.body)
120 assert_nil updated['username'], 'expected no username'
123 test "create user with user, vm and repo as input" do
124 authorize_with :admin
125 repo_name = 'usertestrepo'
127 post :setup, params: {
128 repo_name: repo_name,
130 uuid: 'zzzzz-tpzed-abcdefghijklmno',
131 first_name: "in_create_test_first_name",
132 last_name: "test_last_name",
133 email: "foo@example.com"
136 assert_response :success
137 response_items = JSON.parse(@response.body)['items']
139 created = find_obj_in_resp response_items, 'User', nil
141 assert_equal 'in_create_test_first_name', created['first_name']
142 assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
143 assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
144 assert_not_nil created['email'], 'expected non-nil email'
145 assert_nil created['identity_url'], 'expected no identity_url'
147 # repo link and link add user to 'All users' group
150 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
151 "foo/#{repo_name}", created['uuid'], 'arvados#repository', true, 'Repository'
153 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
154 'All users', created['uuid'], 'arvados#group', true, 'Group'
156 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
157 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
159 verify_system_group_permission_link_for created['uuid']
162 test "setup user with bogus uuid and expect error" do
163 authorize_with :admin
165 post :setup, params: {
167 repo_name: 'usertestrepo',
170 response_body = JSON.parse(@response.body)
171 response_errors = response_body['errors']
172 assert_not_nil response_errors, 'Expected error in response'
173 assert (response_errors.first.include? 'Path not found'), 'Expected 404'
176 test "setup user with bogus uuid in user and expect error" do
177 authorize_with :admin
179 post :setup, params: {
180 user: {uuid: 'bogus_uuid'},
181 repo_name: 'usertestrepo',
184 response_body = JSON.parse(@response.body)
185 response_errors = response_body['errors']
186 assert_not_nil response_errors, 'Expected error in response'
187 assert (response_errors.first.include? 'ArgumentError: Require user email'),
188 'Expected RuntimeError'
191 test "setup user with no uuid and user, expect error" do
192 authorize_with :admin
194 post :setup, params: {
195 repo_name: 'usertestrepo',
198 response_body = JSON.parse(@response.body)
199 response_errors = response_body['errors']
200 assert_not_nil response_errors, 'Expected error in response'
201 assert (response_errors.first.include? 'Required uuid or user'),
202 'Expected ArgumentError'
205 test "setup user with no uuid and email, expect error" do
206 authorize_with :admin
208 post :setup, params: {
210 repo_name: 'usertestrepo',
213 response_body = JSON.parse(@response.body)
214 response_errors = response_body['errors']
215 assert_not_nil response_errors, 'Expected error in response'
216 assert (response_errors.first.include? '<ArgumentError: Require user email'),
217 'Expected ArgumentError'
220 test "invoke setup with existing uuid, vm and repo and verify links" do
221 authorize_with :admin
222 inactive_user = users(:inactive)
224 post :setup, params: {
225 uuid: users(:inactive).uuid,
226 repo_name: 'usertestrepo',
230 assert_response :success
232 response_items = JSON.parse(@response.body)['items']
233 resp_obj = find_obj_in_resp response_items, 'User', nil
235 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
236 assert_equal inactive_user['uuid'], resp_obj['uuid']
237 assert_equal inactive_user['email'], resp_obj['email'],
238 'expecting inactive user email'
240 # expect repo and vm links
241 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
242 'inactiveuser/usertestrepo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
244 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
245 @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
248 test "invoke setup with existing uuid but different email, expect original email" do
249 authorize_with :admin
250 inactive_user = users(:inactive)
252 post :setup, params: {
253 uuid: inactive_user['uuid'],
254 user: {email: 'junk_email'}
257 assert_response :success
259 response_items = JSON.parse(@response.body)['items']
260 resp_obj = find_obj_in_resp response_items, 'User', nil
262 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
263 assert_equal inactive_user['uuid'], resp_obj['uuid']
264 assert_equal inactive_user['email'], resp_obj['email'],
265 'expecting inactive user email'
268 test "setup user with valid email and repo as input" do
269 authorize_with :admin
271 post :setup, params: {
272 repo_name: 'usertestrepo',
273 user: {email: 'foo@example.com'},
276 assert_response :success
277 response_items = JSON.parse(@response.body)['items']
278 response_object = find_obj_in_resp response_items, 'User', nil
279 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
280 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
282 # three extra links; system_group, group and repo perms
286 test "setup user with fake vm and expect error" do
287 authorize_with :admin
289 post :setup, params: {
290 repo_name: 'usertestrepo',
291 vm_uuid: 'no_such_vm',
292 user: {email: 'foo@example.com'},
295 response_body = JSON.parse(@response.body)
296 response_errors = response_body['errors']
297 assert_not_nil response_errors, 'Expected error in response'
298 assert (response_errors.first.include? "No vm found for no_such_vm"),
299 'Expected RuntimeError: No vm found for no_such_vm'
302 test "setup user with valid email, repo and real vm as input" do
303 authorize_with :admin
305 post :setup, params: {
306 repo_name: 'usertestrepo',
308 user: {email: 'foo@example.com'}
311 assert_response :success
312 response_items = JSON.parse(@response.body)['items']
313 response_object = find_obj_in_resp response_items, 'User', nil
314 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
315 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
317 # four extra links; system_group, group, vm, repo
321 test "setup user with valid email, no vm and no repo as input" do
322 authorize_with :admin
324 post :setup, params: {
325 user: {email: 'foo@example.com'},
328 assert_response :success
329 response_items = JSON.parse(@response.body)['items']
330 response_object = find_obj_in_resp response_items, 'User', nil
331 assert_not_nil response_object['uuid'], 'expected uuid for new user'
332 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
334 # two extra links; system_group, and group
337 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
338 'All users', response_object['uuid'], 'arvados#group', true, 'Group'
340 verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
341 'foo/usertestrepo', response_object['uuid'], 'arvados#repository', true, 'Repository'
343 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
344 nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
347 test "setup user with email, first name, repo name and vm uuid" do
348 authorize_with :admin
350 post :setup, params: {
351 repo_name: 'usertestrepo',
354 first_name: 'test_first_name',
355 email: 'foo@example.com'
359 assert_response :success
360 response_items = JSON.parse(@response.body)['items']
361 response_object = find_obj_in_resp response_items, 'User', nil
362 assert_not_nil response_object['uuid'], 'expected uuid for new user'
363 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
364 assert_equal 'test_first_name', response_object['first_name'],
365 'expecting first name'
367 # four extra links; system_group, group, repo and vm
371 test "setup user with an existing user email and check different object is created" do
372 authorize_with :admin
373 inactive_user = users(:inactive)
375 post :setup, params: {
376 repo_name: 'usertestrepo',
378 email: inactive_user['email']
382 assert_response :success
383 response_items = JSON.parse(@response.body)['items']
384 response_object = find_obj_in_resp response_items, 'User', nil
385 assert_not_nil response_object['uuid'], 'expected uuid for new user'
386 assert_not_equal response_object['uuid'], inactive_user['uuid'],
387 'expected different uuid after create operation'
388 assert_equal inactive_user['email'], response_object['email'], 'expected given email'
389 # system_group, group, and repo. No vm link.
393 test "setup user with openid prefix" do
394 authorize_with :admin
396 post :setup, params: {
397 repo_name: 'usertestrepo',
399 first_name: "in_create_test_first_name",
400 last_name: "test_last_name",
401 email: "foo@example.com"
405 assert_response :success
407 response_items = JSON.parse(@response.body)['items']
408 created = find_obj_in_resp response_items, 'User', nil
410 assert_equal 'in_create_test_first_name', created['first_name']
411 assert_not_nil created['uuid'], 'expected uuid for new user'
412 assert_not_nil created['email'], 'expected non-nil email'
413 assert_nil created['identity_url'], 'expected no identity_url'
416 # three new links: system_group, repo, and 'All users' group.
419 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
420 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
422 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
423 'All users', created['uuid'], 'arvados#group', true, 'Group'
425 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
426 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
429 test "setup user with user, vm and repo and verify links" do
430 authorize_with :admin
432 post :setup, params: {
434 first_name: "in_create_test_first_name",
435 last_name: "test_last_name",
436 email: "foo@example.com"
439 repo_name: 'usertestrepo',
442 assert_response :success
444 response_items = JSON.parse(@response.body)['items']
445 created = find_obj_in_resp response_items, 'User', nil
447 assert_equal 'in_create_test_first_name', created['first_name']
448 assert_not_nil created['uuid'], 'expected uuid for new user'
449 assert_not_nil created['email'], 'expected non-nil email'
450 assert_nil created['identity_url'], 'expected no identity_url'
452 # four new links: system_group, repo, vm and 'All users' group link
455 # system_group isn't part of the response. See User#add_system_group_permission_link
457 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
458 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
460 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
461 'All users', created['uuid'], 'arvados#group', true, 'Group'
463 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
464 @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
467 test "create user as non admin user and expect error" do
468 authorize_with :active
470 post :create, params: {
471 user: {email: 'foo@example.com'}
474 response_body = JSON.parse(@response.body)
475 response_errors = response_body['errors']
476 assert_not_nil response_errors, 'Expected error in response'
477 assert (response_errors.first.include? 'PermissionDenied'),
478 'Expected PermissionDeniedError'
481 test "setup user as non admin user and expect error" do
482 authorize_with :active
484 post :setup, params: {
485 user: {email: 'foo@example.com'}
488 response_body = JSON.parse(@response.body)
489 response_errors = response_body['errors']
490 assert_not_nil response_errors, 'Expected error in response'
491 assert (response_errors.first.include? 'Forbidden'),
492 'Expected Forbidden error'
495 test "setup active user with repo and no vm" do
496 authorize_with :admin
497 active_user = users(:active)
499 # invoke setup with a repository
500 post :setup, params: {
501 repo_name: 'usertestrepo',
502 uuid: active_user['uuid']
505 assert_response :success
507 response_items = JSON.parse(@response.body)['items']
508 created = find_obj_in_resp response_items, 'User', nil
510 assert_equal active_user[:email], created['email'], 'expected input email'
513 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
514 'All users', created['uuid'], 'arvados#group', true, 'Group'
516 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
517 'active/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
519 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
520 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
523 test "setup active user with vm and no repo" do
524 authorize_with :admin
525 active_user = users(:active)
526 repos_query = Repository.where(owner_uuid: active_user.uuid)
527 repo_link_query = Link.where(tail_uuid: active_user.uuid,
528 link_class: "permission", name: "can_manage")
529 repos_count = repos_query.count
530 repo_link_count = repo_link_query.count
532 # invoke setup with a repository
533 post :setup, params: {
535 uuid: active_user['uuid'],
539 assert_response :success
541 response_items = JSON.parse(@response.body)['items']
542 created = find_obj_in_resp response_items, 'User', nil
544 assert_equal active_user['email'], created['email'], 'expected original email'
547 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
548 'All users', created['uuid'], 'arvados#group', true, 'Group'
550 assert_equal(repos_count, repos_query.count)
551 assert_equal(repo_link_count, repo_link_query.count)
553 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
554 @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
557 test "unsetup active user" do
558 active_user = users(:active)
559 assert_not_nil active_user['uuid'], 'expected uuid for the active user'
560 assert active_user['is_active'], 'expected is_active for active user'
562 verify_link_existence active_user['uuid'], active_user['email'],
563 false, true, true, true, true
565 authorize_with :admin
567 # now unsetup this user
568 post :unsetup, params: {id: active_user['uuid']}
569 assert_response :success
571 response_user = JSON.parse(@response.body)
572 assert_not_nil response_user['uuid'], 'expected uuid for the upsetup user'
573 assert_equal active_user['uuid'], response_user['uuid'], 'expected uuid not found'
574 assert !response_user['is_active'], 'expected user to be inactive'
575 assert !response_user['is_invited'], 'expected user to be uninvited'
577 verify_link_existence response_user['uuid'], response_user['email'],
578 false, false, false, false, false
580 active_user = User.find_by_uuid(users(:active).uuid)
581 readable_groups = active_user.groups_i_can(:read)
582 all_users_group = Group.all.collect(&:uuid).select { |g| g.match(/-f+$/) }
583 refute_includes(readable_groups, all_users_group,
584 "active user can read All Users group after being deactivated")
585 assert_equal(false, active_user.is_invited,
586 "active user is_invited after being deactivated & reloaded")
589 test "setup user with send notification param false and verify no email" do
590 authorize_with :admin
592 post :setup, params: {
593 send_notification_email: 'false',
595 email: "foo@example.com"
599 assert_response :success
600 response_items = JSON.parse(@response.body)['items']
601 created = find_obj_in_resp response_items, 'User', nil
602 assert_not_nil created['uuid'], 'expected uuid for the new user'
603 assert_equal created['email'], 'foo@example.com', 'expected given email'
605 setup_email = ActionMailer::Base.deliveries.last
606 assert_nil setup_email, 'expected no setup email'
609 test "setup user with send notification param true and verify email" do
610 authorize_with :admin
612 post :setup, params: {
613 send_notification_email: 'true',
615 email: "foo@example.com"
619 assert_response :success
620 response_items = JSON.parse(@response.body)['items']
621 created = find_obj_in_resp response_items, 'User', nil
622 assert_not_nil created['uuid'], 'expected uuid for the new user'
623 assert_equal created['email'], 'foo@example.com', 'expected given email'
625 setup_email = ActionMailer::Base.deliveries.last
626 assert_not_nil setup_email, 'Expected email after setup'
628 assert_equal Rails.configuration.Users.UserNotifierEmailFrom, setup_email.from[0]
629 assert_equal 'foo@example.com', setup_email.to[0]
630 assert_equal 'Welcome to Arvados - account enabled', setup_email.subject
631 assert (setup_email.body.to_s.include? 'Your Arvados shell account has been set up'),
632 'Expected Your Arvados shell account has been set up in email body'
633 assert (setup_email.body.to_s.include? "#{Rails.configuration.Services.Workbench1.ExternalURL}users/#{created['uuid']}/virtual_machines"), 'Expected virtual machines url in email body'
636 test "setup inactive user by changing is_active to true" do
637 authorize_with :admin
638 active_user = users(:active)
640 # invoke setup with a repository
641 put :update, params: {
642 id: active_user['uuid'],
647 assert_response :success
648 assert_equal active_user['uuid'], json_response['uuid']
649 updated = User.where(uuid: active_user['uuid']).first
650 assert_equal(true, updated.is_active)
651 assert_equal({read: true}, updated.group_permissions[all_users_group_uuid])
654 test "non-admin user can get basic information about readable users" do
655 authorize_with :spectator
657 check_non_admin_index
658 check_readable_users_index [:spectator], [:inactive, :active]
661 test "non-admin user gets only safe attributes from users#show" do
662 g = act_as_system_user do
665 users = create_list :active_user, 2, join_groups: [g]
666 token = create :token, user: users[0]
667 authorize_with_token token
668 get :show, params: {id: users[1].uuid}
672 [2, 4].each do |limit|
673 test "non-admin user can limit index to #{limit}" do
674 g = act_as_system_user do
677 users = create_list :active_user, 4, join_groups: [g]
678 token = create :token, user: users[0]
680 authorize_with_token token
681 get(:index, params: {limit: limit})
682 check_non_admin_index
683 assert_equal(limit, json_response["items"].size,
684 "non-admin index limit was ineffective")
688 test "admin has full index powers" do
689 authorize_with :admin
690 check_inactive_user_findable
693 test "reader token can grant admin index powers" do
694 authorize_with :spectator
695 check_inactive_user_findable(reader_tokens: [api_token(:admin)])
698 test "admin can filter on user.is_active" do
699 authorize_with :admin
700 get(:index, params: {filters: [["is_active", "=", "true"]]})
701 assert_response :success
702 check_readable_users_index [:active, :spectator], [:inactive]
705 test "admin can search where user.is_active" do
706 authorize_with :admin
707 get(:index, params: {where: {is_active: true}})
708 assert_response :success
709 check_readable_users_index [:active, :spectator], [:inactive]
712 test "update active_no_prefs user profile and expect notification email" do
713 authorize_with :admin
715 put :update, params: {
716 id: users(:active_no_prefs).uuid,
718 prefs: {:profile => {'organization' => 'example.com'}}
721 assert_response :success
724 ActionMailer::Base.deliveries.andand.each do |email|
725 if email.subject == "Profile created by #{users(:active_no_prefs).email}"
730 assert_equal true, found_email, 'Expected email after creating profile'
733 test "update active_no_prefs_profile user profile and expect notification email" do
734 authorize_with :admin
737 user[:prefs] = users(:active_no_prefs_profile_no_getting_started_shown).prefs
738 user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
739 put :update, params: {
740 id: users(:active_no_prefs_profile_no_getting_started_shown).uuid,
743 assert_response :success
746 ActionMailer::Base.deliveries.andand.each do |email|
747 if email.subject == "Profile created by #{users(:active_no_prefs_profile_no_getting_started_shown).email}"
752 assert_equal true, found_email, 'Expected email after creating profile'
755 test "update active user profile and expect no notification email" do
756 authorize_with :admin
758 put :update, params: {
759 id: users(:active).uuid,
761 prefs: {:profile => {'organization' => 'anotherexample.com'}}
764 assert_response :success
767 ActionMailer::Base.deliveries.andand.each do |email|
768 if email.subject == "Profile created by #{users(:active).email}"
773 assert_equal false, found_email, 'Expected no email after updating profile'
776 test "user API response includes writable_by" do
777 authorize_with :active
779 assert_response :success
780 assert_includes(json_response["writable_by"], users(:active).uuid,
781 "user's writable_by should include self")
782 assert_includes(json_response["writable_by"], users(:active).owner_uuid,
783 "user's writable_by should include its owner_uuid")
789 ].each do |auth_user, expect_success|
790 test "update_uuid as #{auth_user}" do
791 authorize_with auth_user
792 orig_uuid = users(:active).uuid
793 post :update_uuid, params: {
795 new_uuid: 'zbbbb-tpzed-abcde12345abcde',
798 assert_response :success
799 assert_empty User.where(uuid: orig_uuid)
802 assert_not_empty User.where(uuid: orig_uuid)
807 test "merge with redirect_to_user_uuid=false" do
808 authorize_with :project_viewer_trustedclient
809 tok = api_client_authorizations(:project_viewer).api_token
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: false,
815 assert_response(:success)
816 assert_nil(User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
818 # because redirect_to_new_user=false, token owned by
819 # project_viewer should be deleted
820 auth = ApiClientAuthorization.validate(token: tok)
824 test "merge remote to local as admin" do
825 authorize_with :admin
827 remoteuser = User.create!(uuid: "zbbbb-tpzed-remotremotremot")
828 tok = ApiClientAuthorization.create!(user: remoteuser, api_client: api_clients(:untrusted)).api_token
830 auth = ApiClientAuthorization.validate(token: tok)
832 assert_nil(remoteuser.redirect_to_user_uuid)
834 post :merge, params: {
835 new_user_uuid: users(:active).uuid,
836 old_user_uuid: remoteuser.uuid,
837 new_owner_uuid: users(:active).uuid,
838 redirect_to_new_user: true,
840 assert_response(:success)
842 assert_equal(users(:active).uuid, remoteuser.redirect_to_user_uuid)
844 # token owned by remoteuser should be deleted
845 auth = ApiClientAuthorization.validate(token: tok)
849 test "refuse to merge user into self" do
850 authorize_with(:active_trustedclient)
851 post(:merge, params: {
852 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
853 new_owner_uuid: users(:active).uuid,
854 redirect_to_new_user: true,
859 [[:active, :project_viewer_trustedclient],
860 [:active_trustedclient, :project_viewer]].each do |src, dst|
861 test "refuse to merge with untrusted token (#{src} -> #{dst})" do
863 post(:merge, params: {
864 new_user_token: api_client_authorizations(dst).api_token,
865 new_owner_uuid: api_client_authorizations(dst).user.uuid,
866 redirect_to_new_user: true,
872 [[:expired_trustedclient, :project_viewer_trustedclient],
873 [:project_viewer_trustedclient, :expired_trustedclient]].each do |src, dst|
874 test "refuse to merge with expired token (#{src} -> #{dst})" do
876 post(:merge, params: {
877 new_user_token: api_client_authorizations(dst).api_token,
878 new_owner_uuid: api_client_authorizations(dst).user.uuid,
879 redirect_to_new_user: true,
885 [['src', :active_trustedclient],
886 ['dst', :project_viewer_trustedclient]].each do |which_scoped, auth|
887 test "refuse to merge with scoped #{which_scoped} token" do
888 act_as_system_user do
889 api_client_authorizations(auth).update_attributes(scopes: ["GET /", "POST /", "PUT /"])
891 authorize_with(:active_trustedclient)
892 post(:merge, params: {
893 new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token,
894 new_owner_uuid: users(:project_viewer).uuid,
895 redirect_to_new_user: true,
901 test "refuse to merge if new_owner_uuid is not writable" do
902 authorize_with(:project_viewer_trustedclient)
903 post(:merge, params: {
904 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
905 new_owner_uuid: groups(:anonymously_accessible_project).uuid,
906 redirect_to_new_user: true,
911 test "refuse to merge if new_owner_uuid is empty" do
912 authorize_with(:project_viewer_trustedclient)
913 post(:merge, params: {
914 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
916 redirect_to_new_user: true,
921 test "refuse to merge if new_owner_uuid is not provided" do
922 authorize_with(:project_viewer_trustedclient)
923 post(:merge, params: {
924 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
925 redirect_to_new_user: true,
930 test "refuse to update redirect_to_user_uuid directly" do
931 authorize_with(:active_trustedclient)
932 patch(:update, params: {
933 id: users(:active).uuid,
935 redirect_to_user_uuid: users(:active).uuid,
941 test "merge 'project_viewer' account into 'active' account" do
942 authorize_with(:project_viewer_trustedclient)
943 post(:merge, params: {
944 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
945 new_owner_uuid: users(:active).uuid,
946 redirect_to_new_user: true,
948 assert_response(:success)
949 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
951 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
953 assert_not_nil(auth.user)
954 assert_equal(users(:active).uuid, auth.user.uuid)
958 test "merge 'project_viewer' account into 'active' account using uuids" do
959 authorize_with(:admin)
960 post(:merge, params: {
961 old_user_uuid: users(:project_viewer).uuid,
962 new_user_uuid: users(:active).uuid,
963 new_owner_uuid: users(:active).uuid,
964 redirect_to_new_user: true,
966 assert_response(:success)
967 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
969 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
971 assert_not_nil(auth.user)
972 assert_equal(users(:active).uuid, auth.user.uuid)
975 test "merge 'project_viewer' account into 'active' account using uuids denied for non-admin" do
976 authorize_with(:active)
977 post(:merge, params: {
978 old_user_uuid: users(:project_viewer).uuid,
979 new_user_uuid: users(:active).uuid,
980 new_owner_uuid: users(:active).uuid,
981 redirect_to_new_user: true,
984 assert_nil(users(:project_viewer).redirect_to_user_uuid)
987 test "merge 'project_viewer' account into 'active' account using uuids denied missing old_user_uuid" do
988 authorize_with(:admin)
989 post(:merge, params: {
990 new_user_uuid: users(:active).uuid,
991 new_owner_uuid: users(:active).uuid,
992 redirect_to_new_user: true,
995 assert_nil(users(:project_viewer).redirect_to_user_uuid)
998 test "merge 'project_viewer' account into 'active' account using uuids denied missing new_user_uuid" do
999 authorize_with(:admin)
1000 post(:merge, params: {
1001 old_user_uuid: users(:project_viewer).uuid,
1002 new_owner_uuid: users(:active).uuid,
1003 redirect_to_new_user: true,
1005 assert_response(422)
1006 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1009 test "merge 'project_viewer' account into 'active' account using uuids denied bogus old_user_uuid" do
1010 authorize_with(:admin)
1011 post(:merge, params: {
1012 old_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
1013 new_user_uuid: users(:active).uuid,
1014 new_owner_uuid: users(:active).uuid,
1015 redirect_to_new_user: true,
1017 assert_response(422)
1018 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1021 test "merge 'project_viewer' account into 'active' account using uuids denied bogus new_user_uuid" do
1022 authorize_with(:admin)
1023 post(:merge, params: {
1024 old_user_uuid: users(:project_viewer).uuid,
1025 new_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
1026 new_owner_uuid: users(:active).uuid,
1027 redirect_to_new_user: true,
1029 assert_response(422)
1030 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1033 test "batch update fails for non-admin" do
1034 authorize_with(:active)
1035 patch(:batch_update, params: {updates: {}})
1036 assert_response(403)
1039 test "batch update" do
1040 existinguuid = 'remot-tpzed-foobarbazwazqux'
1041 newuuid = 'remot-tpzed-newnarnazwazqux'
1042 act_as_system_user do
1043 User.create!(uuid: existinguuid, email: 'root@existing.example.com')
1046 authorize_with(:admin)
1047 patch(:batch_update,
1051 'first_name' => 'root',
1052 'email' => 'root@remot.example.com',
1053 'is_active' => true,
1055 'prefs' => {'foo' => 'bar'},
1058 'first_name' => 'noot',
1059 'email' => 'root@remot.example.com',
1063 assert_response(:success)
1065 assert_equal('root', User.find_by_uuid(existinguuid).first_name)
1066 assert_equal('root@remot.example.com', User.find_by_uuid(existinguuid).email)
1067 assert_equal(true, User.find_by_uuid(existinguuid).is_active)
1068 assert_equal(true, User.find_by_uuid(existinguuid).is_admin)
1069 assert_equal({'foo' => 'bar'}, User.find_by_uuid(existinguuid).prefs)
1071 assert_equal('noot', User.find_by_uuid(newuuid).first_name)
1072 assert_equal('root@remot.example.com', User.find_by_uuid(newuuid).email)
1075 NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
1076 "last_name", "username"].sort
1078 def check_non_admin_index
1079 assert_response :success
1080 response_items = json_response["items"]
1081 assert_not_nil response_items
1082 response_items.each do |user_data|
1083 check_non_admin_item user_data
1084 assert(user_data["is_active"], "non-admin index returned inactive user")
1088 def check_non_admin_show
1089 assert_response :success
1090 check_non_admin_item json_response
1093 def check_non_admin_item user_data
1094 assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
1095 "data in response had missing or extra attributes")
1096 assert_equal("arvados#user", user_data["kind"])
1100 def check_readable_users_index expect_present, expect_missing
1101 response_uuids = json_response["items"].map { |u| u["uuid"] }
1102 expect_present.each do |user_key|
1103 assert_includes(response_uuids, users(user_key).uuid,
1104 "#{user_key} missing from index")
1106 expect_missing.each do |user_key|
1107 refute_includes(response_uuids, users(user_key).uuid,
1108 "#{user_key} included in index")
1112 def check_inactive_user_findable(params={})
1113 inactive_user = users(:inactive)
1114 get(:index, params: params.merge(filters: [["email", "=", inactive_user.email]]))
1115 assert_response :success
1116 user_list = json_response["items"]
1117 assert_equal(1, user_list.andand.count)
1118 # This test needs to check a column non-admins have no access to,
1119 # to ensure that admins see all user information.
1120 assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
1121 "admin's filtered index did not return inactive user")
1124 def verify_links_added more
1125 assert_equal @initial_link_count+more, Link.count,
1126 "Started with #{@initial_link_count} links, expected #{more} more"
1129 def find_obj_in_resp (response_items, object_type, head_kind=nil)
1131 response_items.each { |x|
1136 if object_type == 'User'
1137 if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
1141 else # looking for a link
1142 if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind