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 user with user, vm and repo as input" do
93 repo_name = 'usertestrepo'
95 post :setup, params: {
98 uuid: 'zzzzz-tpzed-abcdefghijklmno',
99 first_name: "in_create_test_first_name",
100 last_name: "test_last_name",
101 email: "foo@example.com"
104 assert_response :success
105 response_items = JSON.parse(@response.body)['items']
107 created = find_obj_in_resp response_items, 'User', nil
109 assert_equal 'in_create_test_first_name', created['first_name']
110 assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
111 assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
112 assert_not_nil created['email'], 'expected non-nil email'
113 assert_nil created['identity_url'], 'expected no identity_url'
115 # repo link and link add user to 'All users' group
118 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
119 "foo/#{repo_name}", created['uuid'], 'arvados#repository', true, 'Repository'
121 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
122 'All users', created['uuid'], 'arvados#group', true, 'Group'
124 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
125 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
127 verify_system_group_permission_link_for created['uuid']
130 test "setup user with bogus uuid and expect error" do
131 authorize_with :admin
133 post :setup, params: {
135 repo_name: 'usertestrepo',
138 response_body = JSON.parse(@response.body)
139 response_errors = response_body['errors']
140 assert_not_nil response_errors, 'Expected error in response'
141 assert (response_errors.first.include? 'Path not found'), 'Expected 404'
144 test "setup user with bogus uuid in user and expect error" do
145 authorize_with :admin
147 post :setup, params: {
148 user: {uuid: 'bogus_uuid'},
149 repo_name: 'usertestrepo',
152 response_body = JSON.parse(@response.body)
153 response_errors = response_body['errors']
154 assert_not_nil response_errors, 'Expected error in response'
155 assert (response_errors.first.include? 'ArgumentError: Require user email'),
156 'Expected RuntimeError'
159 test "setup user with no uuid and user, expect error" do
160 authorize_with :admin
162 post :setup, params: {
163 repo_name: 'usertestrepo',
166 response_body = JSON.parse(@response.body)
167 response_errors = response_body['errors']
168 assert_not_nil response_errors, 'Expected error in response'
169 assert (response_errors.first.include? 'Required uuid or user'),
170 'Expected ArgumentError'
173 test "setup user with no uuid and email, expect error" do
174 authorize_with :admin
176 post :setup, params: {
178 repo_name: 'usertestrepo',
181 response_body = JSON.parse(@response.body)
182 response_errors = response_body['errors']
183 assert_not_nil response_errors, 'Expected error in response'
184 assert (response_errors.first.include? '<ArgumentError: Require user email'),
185 'Expected ArgumentError'
188 test "invoke setup with existing uuid, vm and repo and verify links" do
189 authorize_with :admin
190 inactive_user = users(:inactive)
192 post :setup, params: {
193 uuid: users(:inactive).uuid,
194 repo_name: 'usertestrepo',
198 assert_response :success
200 response_items = JSON.parse(@response.body)['items']
201 resp_obj = find_obj_in_resp response_items, 'User', nil
203 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
204 assert_equal inactive_user['uuid'], resp_obj['uuid']
205 assert_equal inactive_user['email'], resp_obj['email'],
206 'expecting inactive user email'
208 # expect repo and vm links
209 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
210 'inactiveuser/usertestrepo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
212 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
213 @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
216 test "invoke setup with existing uuid but different email, expect original email" do
217 authorize_with :admin
218 inactive_user = users(:inactive)
220 post :setup, params: {
221 uuid: inactive_user['uuid'],
222 user: {email: 'junk_email'}
225 assert_response :success
227 response_items = JSON.parse(@response.body)['items']
228 resp_obj = find_obj_in_resp response_items, 'User', nil
230 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
231 assert_equal inactive_user['uuid'], resp_obj['uuid']
232 assert_equal inactive_user['email'], resp_obj['email'],
233 'expecting inactive user email'
236 test "setup user with valid email and repo as input" do
237 authorize_with :admin
239 post :setup, params: {
240 repo_name: 'usertestrepo',
241 user: {email: 'foo@example.com'},
244 assert_response :success
245 response_items = JSON.parse(@response.body)['items']
246 response_object = find_obj_in_resp response_items, 'User', nil
247 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
248 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
250 # three extra links; system_group, group and repo perms
254 test "setup user with fake vm and expect error" do
255 authorize_with :admin
257 post :setup, params: {
258 repo_name: 'usertestrepo',
259 vm_uuid: 'no_such_vm',
260 user: {email: 'foo@example.com'},
263 response_body = JSON.parse(@response.body)
264 response_errors = response_body['errors']
265 assert_not_nil response_errors, 'Expected error in response'
266 assert (response_errors.first.include? "No vm found for no_such_vm"),
267 'Expected RuntimeError: No vm found for no_such_vm'
270 test "setup user with valid email, repo and real vm as input" do
271 authorize_with :admin
273 post :setup, params: {
274 repo_name: 'usertestrepo',
276 user: {email: 'foo@example.com'}
279 assert_response :success
280 response_items = JSON.parse(@response.body)['items']
281 response_object = find_obj_in_resp response_items, 'User', nil
282 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
283 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
285 # four extra links; system_group, group, vm, repo
289 test "setup user with valid email, no vm and no repo as input" do
290 authorize_with :admin
292 post :setup, params: {
293 user: {email: 'foo@example.com'},
296 assert_response :success
297 response_items = JSON.parse(@response.body)['items']
298 response_object = find_obj_in_resp response_items, 'User', nil
299 assert_not_nil response_object['uuid'], 'expected uuid for new user'
300 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
302 # two extra links; system_group, and group
305 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
306 'All users', response_object['uuid'], 'arvados#group', true, 'Group'
308 verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
309 'foo/usertestrepo', response_object['uuid'], 'arvados#repository', true, 'Repository'
311 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
312 nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
315 test "setup user with email, first name, repo name and vm uuid" do
316 authorize_with :admin
318 post :setup, params: {
319 repo_name: 'usertestrepo',
322 first_name: 'test_first_name',
323 email: 'foo@example.com'
327 assert_response :success
328 response_items = JSON.parse(@response.body)['items']
329 response_object = find_obj_in_resp response_items, 'User', nil
330 assert_not_nil response_object['uuid'], 'expected uuid for new user'
331 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
332 assert_equal 'test_first_name', response_object['first_name'],
333 'expecting first name'
335 # four extra links; system_group, group, repo and vm
339 test "setup user with an existing user email and check different object is created" do
340 authorize_with :admin
341 inactive_user = users(:inactive)
343 post :setup, params: {
344 repo_name: 'usertestrepo',
346 email: inactive_user['email']
350 assert_response :success
351 response_items = JSON.parse(@response.body)['items']
352 response_object = find_obj_in_resp response_items, 'User', nil
353 assert_not_nil response_object['uuid'], 'expected uuid for new user'
354 assert_not_equal response_object['uuid'], inactive_user['uuid'],
355 'expected different uuid after create operation'
356 assert_equal inactive_user['email'], response_object['email'], 'expected given email'
357 # system_group, group, and repo. No vm link.
361 test "setup user with openid prefix" do
362 authorize_with :admin
364 post :setup, params: {
365 repo_name: 'usertestrepo',
367 first_name: "in_create_test_first_name",
368 last_name: "test_last_name",
369 email: "foo@example.com"
373 assert_response :success
375 response_items = JSON.parse(@response.body)['items']
376 created = find_obj_in_resp response_items, 'User', nil
378 assert_equal 'in_create_test_first_name', created['first_name']
379 assert_not_nil created['uuid'], 'expected uuid for new user'
380 assert_not_nil created['email'], 'expected non-nil email'
381 assert_nil created['identity_url'], 'expected no identity_url'
384 # three new links: system_group, repo, and 'All users' group.
387 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
388 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
390 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
391 'All users', created['uuid'], 'arvados#group', true, 'Group'
393 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
394 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
397 test "setup user with user, vm and repo and verify links" do
398 authorize_with :admin
400 post :setup, params: {
402 first_name: "in_create_test_first_name",
403 last_name: "test_last_name",
404 email: "foo@example.com"
407 repo_name: 'usertestrepo',
410 assert_response :success
412 response_items = JSON.parse(@response.body)['items']
413 created = find_obj_in_resp response_items, 'User', nil
415 assert_equal 'in_create_test_first_name', created['first_name']
416 assert_not_nil created['uuid'], 'expected uuid for new user'
417 assert_not_nil created['email'], 'expected non-nil email'
418 assert_nil created['identity_url'], 'expected no identity_url'
420 # four new links: system_group, repo, vm and 'All users' group link
423 # system_group isn't part of the response. See User#add_system_group_permission_link
425 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
426 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
428 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
429 'All users', created['uuid'], 'arvados#group', true, 'Group'
431 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
432 @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
435 test "create user as non admin user and expect error" do
436 authorize_with :active
438 post :create, params: {
439 user: {email: 'foo@example.com'}
442 response_body = JSON.parse(@response.body)
443 response_errors = response_body['errors']
444 assert_not_nil response_errors, 'Expected error in response'
445 assert (response_errors.first.include? 'PermissionDenied'),
446 'Expected PermissionDeniedError'
449 test "setup user as non admin user and expect error" do
450 authorize_with :active
452 post :setup, params: {
453 user: {email: 'foo@example.com'}
456 response_body = JSON.parse(@response.body)
457 response_errors = response_body['errors']
458 assert_not_nil response_errors, 'Expected error in response'
459 assert (response_errors.first.include? 'Forbidden'),
460 'Expected Forbidden error'
463 test "setup active user with repo and no vm" do
464 authorize_with :admin
465 active_user = users(:active)
467 # invoke setup with a repository
468 post :setup, params: {
469 repo_name: 'usertestrepo',
470 uuid: active_user['uuid']
473 assert_response :success
475 response_items = JSON.parse(@response.body)['items']
476 created = find_obj_in_resp response_items, 'User', nil
478 assert_equal active_user[:email], created['email'], 'expected input email'
481 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
482 'All users', created['uuid'], 'arvados#group', true, 'Group'
484 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
485 'active/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
487 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
488 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
491 test "setup active user with vm and no repo" do
492 authorize_with :admin
493 active_user = users(:active)
494 repos_query = Repository.where(owner_uuid: active_user.uuid)
495 repo_link_query = Link.where(tail_uuid: active_user.uuid,
496 link_class: "permission", name: "can_manage")
497 repos_count = repos_query.count
498 repo_link_count = repo_link_query.count
500 # invoke setup with a repository
501 post :setup, params: {
503 uuid: active_user['uuid'],
507 assert_response :success
509 response_items = JSON.parse(@response.body)['items']
510 created = find_obj_in_resp response_items, 'User', nil
512 assert_equal active_user['email'], created['email'], 'expected original email'
515 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
516 'All users', created['uuid'], 'arvados#group', true, 'Group'
518 assert_equal(repos_count, repos_query.count)
519 assert_equal(repo_link_count, repo_link_query.count)
521 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
522 @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
525 test "unsetup active user" do
526 active_user = users(:active)
527 assert_not_nil active_user['uuid'], 'expected uuid for the active user'
528 assert active_user['is_active'], 'expected is_active for active user'
530 verify_link_existence active_user['uuid'], active_user['email'],
531 false, true, true, true, true
533 authorize_with :admin
535 # now unsetup this user
536 post :unsetup, params: {id: active_user['uuid']}
537 assert_response :success
539 response_user = JSON.parse(@response.body)
540 assert_not_nil response_user['uuid'], 'expected uuid for the upsetup user'
541 assert_equal active_user['uuid'], response_user['uuid'], 'expected uuid not found'
542 assert !response_user['is_active'], 'expected user to be inactive'
543 assert !response_user['is_invited'], 'expected user to be uninvited'
545 verify_link_existence response_user['uuid'], response_user['email'],
546 false, false, false, false, false
548 active_user = User.find_by_uuid(users(:active).uuid)
549 readable_groups = active_user.groups_i_can(:read)
550 all_users_group = Group.all.collect(&:uuid).select { |g| g.match(/-f+$/) }
551 refute_includes(readable_groups, all_users_group,
552 "active user can read All Users group after being deactivated")
553 assert_equal(false, active_user.is_invited,
554 "active user is_invited after being deactivated & reloaded")
557 test "setup user with send notification param false and verify no email" do
558 authorize_with :admin
560 post :setup, params: {
561 send_notification_email: 'false',
563 email: "foo@example.com"
567 assert_response :success
568 response_items = JSON.parse(@response.body)['items']
569 created = find_obj_in_resp response_items, 'User', nil
570 assert_not_nil created['uuid'], 'expected uuid for the new user'
571 assert_equal created['email'], 'foo@example.com', 'expected given email'
573 setup_email = ActionMailer::Base.deliveries.last
574 assert_nil setup_email, 'expected no setup email'
577 test "setup user with send notification param true and verify email" do
578 authorize_with :admin
580 post :setup, params: {
581 send_notification_email: 'true',
583 email: "foo@example.com"
587 assert_response :success
588 response_items = JSON.parse(@response.body)['items']
589 created = find_obj_in_resp response_items, 'User', nil
590 assert_not_nil created['uuid'], 'expected uuid for the new user'
591 assert_equal created['email'], 'foo@example.com', 'expected given email'
593 setup_email = ActionMailer::Base.deliveries.last
594 assert_not_nil setup_email, 'Expected email after setup'
596 assert_equal Rails.configuration.Users.UserNotifierEmailFrom, setup_email.from[0]
597 assert_equal 'foo@example.com', setup_email.to[0]
598 assert_equal 'Welcome to Arvados - account enabled', setup_email.subject
599 assert (setup_email.body.to_s.include? 'Your Arvados shell account has been set up'),
600 'Expected Your Arvados shell account has been set up in email body'
601 assert (setup_email.body.to_s.include? "#{Rails.configuration.Services.Workbench1.ExternalURL}users/#{created['uuid']}/virtual_machines"), 'Expected virtual machines url in email body'
604 test "setup inactive user by changing is_active to true" do
605 authorize_with :admin
606 active_user = users(:active)
608 # invoke setup with a repository
609 put :update, params: {
610 id: active_user['uuid'],
615 assert_response :success
616 assert_equal active_user['uuid'], json_response['uuid']
617 updated = User.where(uuid: active_user['uuid']).first
618 assert_equal(true, updated.is_active)
619 assert_equal({read: true}, updated.group_permissions[all_users_group_uuid])
622 test "non-admin user can get basic information about readable users" do
623 authorize_with :spectator
625 check_non_admin_index
626 check_readable_users_index [:spectator], [:inactive, :active]
629 test "non-admin user gets only safe attributes from users#show" do
630 g = act_as_system_user do
633 users = create_list :active_user, 2, join_groups: [g]
634 token = create :token, user: users[0]
635 authorize_with_token token
636 get :show, params: {id: users[1].uuid}
640 [2, 4].each do |limit|
641 test "non-admin user can limit index to #{limit}" do
642 g = act_as_system_user do
645 users = create_list :active_user, 4, join_groups: [g]
646 token = create :token, user: users[0]
648 authorize_with_token token
649 get(:index, params: {limit: limit})
650 check_non_admin_index
651 assert_equal(limit, json_response["items"].size,
652 "non-admin index limit was ineffective")
656 test "admin has full index powers" do
657 authorize_with :admin
658 check_inactive_user_findable
661 test "reader token can grant admin index powers" do
662 authorize_with :spectator
663 check_inactive_user_findable(reader_tokens: [api_token(:admin)])
666 test "admin can filter on user.is_active" do
667 authorize_with :admin
668 get(:index, params: {filters: [["is_active", "=", "true"]]})
669 assert_response :success
670 check_readable_users_index [:active, :spectator], [:inactive]
673 test "admin can search where user.is_active" do
674 authorize_with :admin
675 get(:index, params: {where: {is_active: true}})
676 assert_response :success
677 check_readable_users_index [:active, :spectator], [:inactive]
680 test "update active_no_prefs user profile and expect notification email" do
681 authorize_with :admin
683 put :update, params: {
684 id: users(:active_no_prefs).uuid,
686 prefs: {:profile => {'organization' => 'example.com'}}
689 assert_response :success
692 ActionMailer::Base.deliveries.andand.each do |email|
693 if email.subject == "Profile created by #{users(:active_no_prefs).email}"
698 assert_equal true, found_email, 'Expected email after creating profile'
701 test "update active_no_prefs_profile user profile and expect notification email" do
702 authorize_with :admin
705 user[:prefs] = users(:active_no_prefs_profile_no_getting_started_shown).prefs
706 user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
707 put :update, params: {
708 id: users(:active_no_prefs_profile_no_getting_started_shown).uuid,
711 assert_response :success
714 ActionMailer::Base.deliveries.andand.each do |email|
715 if email.subject == "Profile created by #{users(:active_no_prefs_profile_no_getting_started_shown).email}"
720 assert_equal true, found_email, 'Expected email after creating profile'
723 test "update active user profile and expect no notification email" do
724 authorize_with :admin
726 put :update, params: {
727 id: users(:active).uuid,
729 prefs: {:profile => {'organization' => 'anotherexample.com'}}
732 assert_response :success
735 ActionMailer::Base.deliveries.andand.each do |email|
736 if email.subject == "Profile created by #{users(:active).email}"
741 assert_equal false, found_email, 'Expected no email after updating profile'
744 test "user API response includes writable_by" do
745 authorize_with :active
747 assert_response :success
748 assert_includes(json_response["writable_by"], users(:active).uuid,
749 "user's writable_by should include self")
750 assert_includes(json_response["writable_by"], users(:active).owner_uuid,
751 "user's writable_by should include its owner_uuid")
757 ].each do |auth_user, expect_success|
758 test "update_uuid as #{auth_user}" do
759 authorize_with auth_user
760 orig_uuid = users(:active).uuid
761 post :update_uuid, params: {
763 new_uuid: 'zbbbb-tpzed-abcde12345abcde',
766 assert_response :success
767 assert_empty User.where(uuid: orig_uuid)
770 assert_not_empty User.where(uuid: orig_uuid)
775 test "merge with redirect_to_user_uuid=false" do
776 authorize_with :project_viewer_trustedclient
777 tok = api_client_authorizations(:project_viewer).api_token
778 post :merge, params: {
779 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
780 new_owner_uuid: users(:active).uuid,
781 redirect_to_new_user: false,
783 assert_response(:success)
784 assert_nil(User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
786 # because redirect_to_new_user=false, token owned by
787 # project_viewer should be deleted
788 auth = ApiClientAuthorization.validate(token: tok)
792 test "merge remote to local as admin" do
793 authorize_with :admin
795 remoteuser = User.create!(uuid: "zbbbb-tpzed-remotremotremot")
796 tok = ApiClientAuthorization.create!(user: remoteuser, api_client: api_clients(:untrusted)).api_token
798 auth = ApiClientAuthorization.validate(token: tok)
800 assert_nil(remoteuser.redirect_to_user_uuid)
802 post :merge, params: {
803 new_user_uuid: users(:active).uuid,
804 old_user_uuid: remoteuser.uuid,
805 new_owner_uuid: users(:active).uuid,
806 redirect_to_new_user: true,
808 assert_response(:success)
810 assert_equal(users(:active).uuid, remoteuser.redirect_to_user_uuid)
812 # token owned by remoteuser should be deleted
813 auth = ApiClientAuthorization.validate(token: tok)
817 test "refuse to merge user into self" do
818 authorize_with(:active_trustedclient)
819 post(:merge, params: {
820 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
821 new_owner_uuid: users(:active).uuid,
822 redirect_to_new_user: true,
827 [[:active, :project_viewer_trustedclient],
828 [:active_trustedclient, :project_viewer]].each do |src, dst|
829 test "refuse to merge with untrusted token (#{src} -> #{dst})" do
831 post(:merge, params: {
832 new_user_token: api_client_authorizations(dst).api_token,
833 new_owner_uuid: api_client_authorizations(dst).user.uuid,
834 redirect_to_new_user: true,
840 [[:expired_trustedclient, :project_viewer_trustedclient],
841 [:project_viewer_trustedclient, :expired_trustedclient]].each do |src, dst|
842 test "refuse to merge with expired token (#{src} -> #{dst})" do
844 post(:merge, params: {
845 new_user_token: api_client_authorizations(dst).api_token,
846 new_owner_uuid: api_client_authorizations(dst).user.uuid,
847 redirect_to_new_user: true,
853 [['src', :active_trustedclient],
854 ['dst', :project_viewer_trustedclient]].each do |which_scoped, auth|
855 test "refuse to merge with scoped #{which_scoped} token" do
856 act_as_system_user do
857 api_client_authorizations(auth).update_attributes(scopes: ["GET /", "POST /", "PUT /"])
859 authorize_with(:active_trustedclient)
860 post(:merge, params: {
861 new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token,
862 new_owner_uuid: users(:project_viewer).uuid,
863 redirect_to_new_user: true,
869 test "refuse to merge if new_owner_uuid is not writable" do
870 authorize_with(:project_viewer_trustedclient)
871 post(:merge, params: {
872 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
873 new_owner_uuid: groups(:anonymously_accessible_project).uuid,
874 redirect_to_new_user: true,
879 test "refuse to merge if new_owner_uuid is empty" do
880 authorize_with(:project_viewer_trustedclient)
881 post(:merge, params: {
882 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
884 redirect_to_new_user: true,
889 test "refuse to merge if new_owner_uuid is not provided" do
890 authorize_with(:project_viewer_trustedclient)
891 post(:merge, params: {
892 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
893 redirect_to_new_user: true,
898 test "refuse to update redirect_to_user_uuid directly" do
899 authorize_with(:active_trustedclient)
900 patch(:update, params: {
901 id: users(:active).uuid,
903 redirect_to_user_uuid: users(:active).uuid,
909 test "merge 'project_viewer' account into 'active' account" do
910 authorize_with(:project_viewer_trustedclient)
911 post(:merge, params: {
912 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
913 new_owner_uuid: users(:active).uuid,
914 redirect_to_new_user: true,
916 assert_response(:success)
917 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
919 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
921 assert_not_nil(auth.user)
922 assert_equal(users(:active).uuid, auth.user.uuid)
926 test "merge 'project_viewer' account into 'active' account using uuids" do
927 authorize_with(:admin)
928 post(:merge, params: {
929 old_user_uuid: users(:project_viewer).uuid,
930 new_user_uuid: users(:active).uuid,
931 new_owner_uuid: users(:active).uuid,
932 redirect_to_new_user: true,
934 assert_response(:success)
935 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
937 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
939 assert_not_nil(auth.user)
940 assert_equal(users(:active).uuid, auth.user.uuid)
943 test "merge 'project_viewer' account into 'active' account using uuids denied for non-admin" do
944 authorize_with(:active)
945 post(:merge, params: {
946 old_user_uuid: users(:project_viewer).uuid,
947 new_user_uuid: users(:active).uuid,
948 new_owner_uuid: users(:active).uuid,
949 redirect_to_new_user: true,
952 assert_nil(users(:project_viewer).redirect_to_user_uuid)
955 test "merge 'project_viewer' account into 'active' account using uuids denied missing old_user_uuid" do
956 authorize_with(:admin)
957 post(:merge, params: {
958 new_user_uuid: users(:active).uuid,
959 new_owner_uuid: users(:active).uuid,
960 redirect_to_new_user: true,
963 assert_nil(users(:project_viewer).redirect_to_user_uuid)
966 test "merge 'project_viewer' account into 'active' account using uuids denied missing new_user_uuid" do
967 authorize_with(:admin)
968 post(:merge, params: {
969 old_user_uuid: users(:project_viewer).uuid,
970 new_owner_uuid: users(:active).uuid,
971 redirect_to_new_user: true,
974 assert_nil(users(:project_viewer).redirect_to_user_uuid)
977 test "merge 'project_viewer' account into 'active' account using uuids denied bogus old_user_uuid" do
978 authorize_with(:admin)
979 post(:merge, params: {
980 old_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
981 new_user_uuid: users(:active).uuid,
982 new_owner_uuid: users(:active).uuid,
983 redirect_to_new_user: true,
986 assert_nil(users(:project_viewer).redirect_to_user_uuid)
989 test "merge 'project_viewer' account into 'active' account using uuids denied bogus new_user_uuid" do
990 authorize_with(:admin)
991 post(:merge, params: {
992 old_user_uuid: users(:project_viewer).uuid,
993 new_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
994 new_owner_uuid: users(:active).uuid,
995 redirect_to_new_user: true,
998 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1001 test "batch update fails for non-admin" do
1002 authorize_with(:active)
1003 patch(:batch_update, params: {updates: {}})
1004 assert_response(403)
1007 test "batch update" do
1008 existinguuid = 'remot-tpzed-foobarbazwazqux'
1009 newuuid = 'remot-tpzed-newnarnazwazqux'
1010 act_as_system_user do
1011 User.create!(uuid: existinguuid, email: 'root@existing.example.com')
1014 authorize_with(:admin)
1015 patch(:batch_update,
1019 'first_name' => 'root',
1020 'email' => 'root@remot.example.com',
1021 'is_active' => true,
1023 'prefs' => {'foo' => 'bar'},
1026 'first_name' => 'noot',
1027 'email' => 'root@remot.example.com',
1030 assert_response(:success)
1032 assert_equal('root', User.find_by_uuid(existinguuid).first_name)
1033 assert_equal('root@remot.example.com', User.find_by_uuid(existinguuid).email)
1034 assert_equal(true, User.find_by_uuid(existinguuid).is_active)
1035 assert_equal(true, User.find_by_uuid(existinguuid).is_admin)
1036 assert_equal({'foo' => 'bar'}, User.find_by_uuid(existinguuid).prefs)
1038 assert_equal('noot', User.find_by_uuid(newuuid).first_name)
1039 assert_equal('root@remot.example.com', User.find_by_uuid(newuuid).email)
1042 NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
1043 "last_name", "username"].sort
1045 def check_non_admin_index
1046 assert_response :success
1047 response_items = json_response["items"]
1048 assert_not_nil response_items
1049 response_items.each do |user_data|
1050 check_non_admin_item user_data
1051 assert(user_data["is_active"], "non-admin index returned inactive user")
1055 def check_non_admin_show
1056 assert_response :success
1057 check_non_admin_item json_response
1060 def check_non_admin_item user_data
1061 assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
1062 "data in response had missing or extra attributes")
1063 assert_equal("arvados#user", user_data["kind"])
1067 def check_readable_users_index expect_present, expect_missing
1068 response_uuids = json_response["items"].map { |u| u["uuid"] }
1069 expect_present.each do |user_key|
1070 assert_includes(response_uuids, users(user_key).uuid,
1071 "#{user_key} missing from index")
1073 expect_missing.each do |user_key|
1074 refute_includes(response_uuids, users(user_key).uuid,
1075 "#{user_key} included in index")
1079 def check_inactive_user_findable(params={})
1080 inactive_user = users(:inactive)
1081 get(:index, params: params.merge(filters: [["email", "=", inactive_user.email]]))
1082 assert_response :success
1083 user_list = json_response["items"]
1084 assert_equal(1, user_list.andand.count)
1085 # This test needs to check a column non-admins have no access to,
1086 # to ensure that admins see all user information.
1087 assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
1088 "admin's filtered index did not return inactive user")
1091 def verify_links_added more
1092 assert_equal @initial_link_count+more, Link.count,
1093 "Started with #{@initial_link_count} links, expected #{more} more"
1096 def find_obj_in_resp (response_items, object_type, head_kind=nil)
1098 response_items.each { |x|
1103 if object_type == 'User'
1104 if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
1108 else # looking for a link
1109 if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind