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: {
97 openid_prefix: 'https://www.google.com/accounts/o8/id',
99 uuid: 'zzzzz-tpzed-abcdefghijklmno',
100 first_name: "in_create_test_first_name",
101 last_name: "test_last_name",
102 email: "foo@example.com"
105 assert_response :success
106 response_items = JSON.parse(@response.body)['items']
108 created = find_obj_in_resp response_items, 'User', nil
110 assert_equal 'in_create_test_first_name', created['first_name']
111 assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
112 assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
113 assert_not_nil created['email'], 'expected non-nil email'
114 assert_nil created['identity_url'], 'expected no identity_url'
116 # repo link and link add user to 'All users' group
119 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
120 "foo/#{repo_name}", created['uuid'], 'arvados#repository', true, 'Repository'
122 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
123 'All users', created['uuid'], 'arvados#group', true, 'Group'
125 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
126 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
128 verify_system_group_permission_link_for created['uuid']
131 test "setup user with bogus uuid and expect error" do
132 authorize_with :admin
134 post :setup, params: {
136 repo_name: 'usertestrepo',
139 response_body = JSON.parse(@response.body)
140 response_errors = response_body['errors']
141 assert_not_nil response_errors, 'Expected error in response'
142 assert (response_errors.first.include? 'Path not found'), 'Expected 404'
145 test "setup user with bogus uuid in user and expect error" do
146 authorize_with :admin
148 post :setup, params: {
149 user: {uuid: 'bogus_uuid'},
150 repo_name: 'usertestrepo',
152 openid_prefix: 'https://www.google.com/accounts/o8/id'
154 response_body = JSON.parse(@response.body)
155 response_errors = response_body['errors']
156 assert_not_nil response_errors, 'Expected error in response'
157 assert (response_errors.first.include? 'ArgumentError: Require user email'),
158 'Expected RuntimeError'
161 test "setup user with no uuid and user, expect error" do
162 authorize_with :admin
164 post :setup, params: {
165 repo_name: 'usertestrepo',
167 openid_prefix: 'https://www.google.com/accounts/o8/id'
169 response_body = JSON.parse(@response.body)
170 response_errors = response_body['errors']
171 assert_not_nil response_errors, 'Expected error in response'
172 assert (response_errors.first.include? 'Required uuid or user'),
173 'Expected ArgumentError'
176 test "setup user with no uuid and email, expect error" do
177 authorize_with :admin
179 post :setup, params: {
181 repo_name: 'usertestrepo',
183 openid_prefix: 'https://www.google.com/accounts/o8/id'
185 response_body = JSON.parse(@response.body)
186 response_errors = response_body['errors']
187 assert_not_nil response_errors, 'Expected error in response'
188 assert (response_errors.first.include? '<ArgumentError: Require user email'),
189 'Expected ArgumentError'
192 test "invoke setup with existing uuid, vm and repo and verify links" do
193 authorize_with :admin
194 inactive_user = users(:inactive)
196 post :setup, params: {
197 uuid: users(:inactive).uuid,
198 repo_name: 'usertestrepo',
202 assert_response :success
204 response_items = JSON.parse(@response.body)['items']
205 resp_obj = find_obj_in_resp response_items, 'User', nil
207 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
208 assert_equal inactive_user['uuid'], resp_obj['uuid']
209 assert_equal inactive_user['email'], resp_obj['email'],
210 'expecting inactive user email'
212 # expect repo and vm links
213 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
214 'inactiveuser/usertestrepo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
216 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
217 @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
220 test "invoke setup with existing uuid but different email, expect original email" do
221 authorize_with :admin
222 inactive_user = users(:inactive)
224 post :setup, params: {
225 uuid: inactive_user['uuid'],
226 user: {email: 'junk_email'}
229 assert_response :success
231 response_items = JSON.parse(@response.body)['items']
232 resp_obj = find_obj_in_resp response_items, 'User', nil
234 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
235 assert_equal inactive_user['uuid'], resp_obj['uuid']
236 assert_equal inactive_user['email'], resp_obj['email'],
237 'expecting inactive user email'
240 test "setup user with valid email and repo as input" do
241 authorize_with :admin
243 post :setup, params: {
244 repo_name: 'usertestrepo',
245 user: {email: 'foo@example.com'},
246 openid_prefix: 'https://www.google.com/accounts/o8/id'
249 assert_response :success
250 response_items = JSON.parse(@response.body)['items']
251 response_object = find_obj_in_resp response_items, 'User', nil
252 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
253 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
255 # three extra links; system_group, group and repo perms
259 test "setup user with fake vm and expect error" do
260 authorize_with :admin
262 post :setup, params: {
263 repo_name: 'usertestrepo',
264 vm_uuid: 'no_such_vm',
265 user: {email: 'foo@example.com'},
266 openid_prefix: 'https://www.google.com/accounts/o8/id'
269 response_body = JSON.parse(@response.body)
270 response_errors = response_body['errors']
271 assert_not_nil response_errors, 'Expected error in response'
272 assert (response_errors.first.include? "No vm found for no_such_vm"),
273 'Expected RuntimeError: No vm found for no_such_vm'
276 test "setup user with valid email, repo and real vm as input" do
277 authorize_with :admin
279 post :setup, params: {
280 repo_name: 'usertestrepo',
281 openid_prefix: 'https://www.google.com/accounts/o8/id',
283 user: {email: 'foo@example.com'}
286 assert_response :success
287 response_items = JSON.parse(@response.body)['items']
288 response_object = find_obj_in_resp response_items, 'User', nil
289 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
290 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
292 # four extra links; system_group, group, vm, repo
296 test "setup user with valid email, no vm and no repo as input" do
297 authorize_with :admin
299 post :setup, params: {
300 user: {email: 'foo@example.com'},
301 openid_prefix: 'https://www.google.com/accounts/o8/id'
304 assert_response :success
305 response_items = JSON.parse(@response.body)['items']
306 response_object = find_obj_in_resp response_items, 'User', nil
307 assert_not_nil response_object['uuid'], 'expected uuid for new user'
308 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
310 # two extra links; system_group, and group
313 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
314 'All users', response_object['uuid'], 'arvados#group', true, 'Group'
316 verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
317 'foo/usertestrepo', response_object['uuid'], 'arvados#repository', true, 'Repository'
319 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
320 nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
323 test "setup user with email, first name, repo name and vm uuid" do
324 authorize_with :admin
326 post :setup, params: {
327 openid_prefix: 'https://www.google.com/accounts/o8/id',
328 repo_name: 'usertestrepo',
331 first_name: 'test_first_name',
332 email: 'foo@example.com'
336 assert_response :success
337 response_items = JSON.parse(@response.body)['items']
338 response_object = find_obj_in_resp response_items, 'User', nil
339 assert_not_nil response_object['uuid'], 'expected uuid for new user'
340 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
341 assert_equal 'test_first_name', response_object['first_name'],
342 'expecting first name'
344 # four extra links; system_group, group, repo and vm
348 test "setup user with an existing user email and check different object is created" do
349 authorize_with :admin
350 inactive_user = users(:inactive)
352 post :setup, params: {
353 openid_prefix: 'https://www.google.com/accounts/o8/id',
354 repo_name: 'usertestrepo',
356 email: inactive_user['email']
360 assert_response :success
361 response_items = JSON.parse(@response.body)['items']
362 response_object = find_obj_in_resp response_items, 'User', nil
363 assert_not_nil response_object['uuid'], 'expected uuid for new user'
364 assert_not_equal response_object['uuid'], inactive_user['uuid'],
365 'expected different uuid after create operation'
366 assert_equal inactive_user['email'], response_object['email'], 'expected given email'
367 # system_group, group, and repo. No vm link.
371 test "setup user with openid prefix" do
372 authorize_with :admin
374 post :setup, params: {
375 repo_name: 'usertestrepo',
376 openid_prefix: 'http://www.example.com/account',
378 first_name: "in_create_test_first_name",
379 last_name: "test_last_name",
380 email: "foo@example.com"
384 assert_response :success
386 response_items = JSON.parse(@response.body)['items']
387 created = find_obj_in_resp response_items, 'User', nil
389 assert_equal 'in_create_test_first_name', created['first_name']
390 assert_not_nil created['uuid'], 'expected uuid for new user'
391 assert_not_nil created['email'], 'expected non-nil email'
392 assert_nil created['identity_url'], 'expected no identity_url'
395 # three new links: system_group, repo, and 'All users' group.
398 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
399 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
401 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
402 'All users', created['uuid'], 'arvados#group', true, 'Group'
404 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
405 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
408 test "invoke setup with no openid prefix, expect error" do
409 authorize_with :admin
411 post :setup, params: {
412 repo_name: 'usertestrepo',
414 first_name: "in_create_test_first_name",
415 last_name: "test_last_name",
416 email: "foo@example.com"
420 response_body = JSON.parse(@response.body)
421 response_errors = response_body['errors']
422 assert_not_nil response_errors, 'Expected error in response'
423 assert (response_errors.first.include? 'openid_prefix parameter is missing'),
424 'Expected ArgumentError'
427 test "setup user with user, vm and repo and verify links" do
428 authorize_with :admin
430 post :setup, params: {
432 first_name: "in_create_test_first_name",
433 last_name: "test_last_name",
434 email: "foo@example.com"
437 repo_name: 'usertestrepo',
438 openid_prefix: 'https://www.google.com/accounts/o8/id'
441 assert_response :success
443 response_items = JSON.parse(@response.body)['items']
444 created = find_obj_in_resp response_items, 'User', nil
446 assert_equal 'in_create_test_first_name', created['first_name']
447 assert_not_nil created['uuid'], 'expected uuid for new user'
448 assert_not_nil created['email'], 'expected non-nil email'
449 assert_nil created['identity_url'], 'expected no identity_url'
451 # four new links: system_group, repo, vm and 'All users' group link
454 # system_group isn't part of the response. See User#add_system_group_permission_link
456 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
457 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
459 verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
460 'All users', created['uuid'], 'arvados#group', true, 'Group'
462 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
463 @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
466 test "create user as non admin user and expect error" do
467 authorize_with :active
469 post :create, params: {
470 user: {email: 'foo@example.com'}
473 response_body = JSON.parse(@response.body)
474 response_errors = response_body['errors']
475 assert_not_nil response_errors, 'Expected error in response'
476 assert (response_errors.first.include? 'PermissionDenied'),
477 'Expected PermissionDeniedError'
480 test "setup user as non admin user and expect error" do
481 authorize_with :active
483 post :setup, params: {
484 openid_prefix: 'https://www.google.com/accounts/o8/id',
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 openid_prefix: 'http://www.example.com/account',
594 send_notification_email: 'false',
596 email: "foo@example.com"
600 assert_response :success
601 response_items = JSON.parse(@response.body)['items']
602 created = find_obj_in_resp response_items, 'User', nil
603 assert_not_nil created['uuid'], 'expected uuid for the new user'
604 assert_equal created['email'], 'foo@example.com', 'expected given email'
606 setup_email = ActionMailer::Base.deliveries.last
607 assert_nil setup_email, 'expected no setup email'
610 test "setup user with send notification param true and verify email" do
611 authorize_with :admin
613 post :setup, params: {
614 openid_prefix: 'http://www.example.com/account',
615 send_notification_email: 'true',
617 email: "foo@example.com"
621 assert_response :success
622 response_items = JSON.parse(@response.body)['items']
623 created = find_obj_in_resp response_items, 'User', nil
624 assert_not_nil created['uuid'], 'expected uuid for the new user'
625 assert_equal created['email'], 'foo@example.com', 'expected given email'
627 setup_email = ActionMailer::Base.deliveries.last
628 assert_not_nil setup_email, 'Expected email after setup'
630 assert_equal Rails.configuration.Users.UserNotifierEmailFrom, setup_email.from[0]
631 assert_equal 'foo@example.com', setup_email.to[0]
632 assert_equal 'Welcome to Arvados - shell account enabled', setup_email.subject
633 assert (setup_email.body.to_s.include? 'Your Arvados shell account has been set up'),
634 'Expected Your Arvados shell account has been set up in email body'
635 assert (setup_email.body.to_s.include? "#{Rails.configuration.Services.Workbench1.ExternalURL}users/#{created['uuid']}/virtual_machines"), 'Expected virtual machines url in email body'
638 test "setup inactive user by changing is_active to true" do
639 authorize_with :admin
640 active_user = users(:active)
642 # invoke setup with a repository
643 put :update, params: {
644 id: active_user['uuid'],
649 assert_response :success
650 assert_equal active_user['uuid'], json_response['uuid']
651 updated = User.where(uuid: active_user['uuid']).first
652 assert_equal(true, updated.is_active)
653 assert_equal({read: true}, updated.group_permissions[all_users_group_uuid])
656 test "non-admin user can get basic information about readable users" do
657 authorize_with :spectator
659 check_non_admin_index
660 check_readable_users_index [:spectator], [:inactive, :active]
663 test "non-admin user gets only safe attributes from users#show" do
664 g = act_as_system_user do
667 users = create_list :active_user, 2, join_groups: [g]
668 token = create :token, user: users[0]
669 authorize_with_token token
670 get :show, params: {id: users[1].uuid}
674 [2, 4].each do |limit|
675 test "non-admin user can limit index to #{limit}" do
676 g = act_as_system_user do
679 users = create_list :active_user, 4, join_groups: [g]
680 token = create :token, user: users[0]
682 authorize_with_token token
683 get(:index, params: {limit: limit})
684 check_non_admin_index
685 assert_equal(limit, json_response["items"].size,
686 "non-admin index limit was ineffective")
690 test "admin has full index powers" do
691 authorize_with :admin
692 check_inactive_user_findable
695 test "reader token can grant admin index powers" do
696 authorize_with :spectator
697 check_inactive_user_findable(reader_tokens: [api_token(:admin)])
700 test "admin can filter on user.is_active" do
701 authorize_with :admin
702 get(:index, params: {filters: [["is_active", "=", "true"]]})
703 assert_response :success
704 check_readable_users_index [:active, :spectator], [:inactive]
707 test "admin can search where user.is_active" do
708 authorize_with :admin
709 get(:index, params: {where: {is_active: true}})
710 assert_response :success
711 check_readable_users_index [:active, :spectator], [:inactive]
714 test "update active_no_prefs user profile and expect notification email" do
715 authorize_with :admin
717 put :update, params: {
718 id: users(:active_no_prefs).uuid,
720 prefs: {:profile => {'organization' => 'example.com'}}
723 assert_response :success
726 ActionMailer::Base.deliveries.andand.each do |email|
727 if email.subject == "Profile created by #{users(:active_no_prefs).email}"
732 assert_equal true, found_email, 'Expected email after creating profile'
735 test "update active_no_prefs_profile user profile and expect notification email" do
736 authorize_with :admin
739 user[:prefs] = users(:active_no_prefs_profile_no_getting_started_shown).prefs
740 user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
741 put :update, params: {
742 id: users(:active_no_prefs_profile_no_getting_started_shown).uuid,
745 assert_response :success
748 ActionMailer::Base.deliveries.andand.each do |email|
749 if email.subject == "Profile created by #{users(:active_no_prefs_profile_no_getting_started_shown).email}"
754 assert_equal true, found_email, 'Expected email after creating profile'
757 test "update active user profile and expect no notification email" do
758 authorize_with :admin
760 put :update, params: {
761 id: users(:active).uuid,
763 prefs: {:profile => {'organization' => 'anotherexample.com'}}
766 assert_response :success
769 ActionMailer::Base.deliveries.andand.each do |email|
770 if email.subject == "Profile created by #{users(:active).email}"
775 assert_equal false, found_email, 'Expected no email after updating profile'
778 test "user API response includes writable_by" do
779 authorize_with :active
781 assert_response :success
782 assert_includes(json_response["writable_by"], users(:active).uuid,
783 "user's writable_by should include self")
784 assert_includes(json_response["writable_by"], users(:active).owner_uuid,
785 "user's writable_by should include its owner_uuid")
791 ].each do |auth_user, expect_success|
792 test "update_uuid as #{auth_user}" do
793 authorize_with auth_user
794 orig_uuid = users(:active).uuid
795 post :update_uuid, params: {
797 new_uuid: 'zbbbb-tpzed-abcde12345abcde',
800 assert_response :success
801 assert_empty User.where(uuid: orig_uuid)
804 assert_not_empty User.where(uuid: orig_uuid)
809 test "merge with redirect_to_user_uuid=false" do
810 authorize_with :project_viewer_trustedclient
811 tok = api_client_authorizations(:project_viewer).api_token
812 post :merge, params: {
813 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
814 new_owner_uuid: users(:active).uuid,
815 redirect_to_new_user: false,
817 assert_response(:success)
818 assert_nil(User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
820 # because redirect_to_new_user=false, token owned by
821 # project_viewer should be deleted
822 auth = ApiClientAuthorization.validate(token: tok)
826 test "merge remote to local as admin" do
827 authorize_with :admin
829 remoteuser = User.create!(uuid: "zbbbb-tpzed-remotremotremot")
830 tok = ApiClientAuthorization.create!(user: remoteuser, api_client: api_clients(:untrusted)).api_token
832 auth = ApiClientAuthorization.validate(token: tok)
834 assert_nil(remoteuser.redirect_to_user_uuid)
836 post :merge, params: {
837 new_user_uuid: users(:active).uuid,
838 old_user_uuid: remoteuser.uuid,
839 new_owner_uuid: users(:active).uuid,
840 redirect_to_new_user: true,
842 assert_response(:success)
844 assert_equal(users(:active).uuid, remoteuser.redirect_to_user_uuid)
846 # token owned by remoteuser should be deleted
847 auth = ApiClientAuthorization.validate(token: tok)
851 test "refuse to merge user into self" do
852 authorize_with(:active_trustedclient)
853 post(:merge, params: {
854 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
855 new_owner_uuid: users(:active).uuid,
856 redirect_to_new_user: true,
861 [[:active, :project_viewer_trustedclient],
862 [:active_trustedclient, :project_viewer]].each do |src, dst|
863 test "refuse to merge with untrusted token (#{src} -> #{dst})" do
865 post(:merge, params: {
866 new_user_token: api_client_authorizations(dst).api_token,
867 new_owner_uuid: api_client_authorizations(dst).user.uuid,
868 redirect_to_new_user: true,
874 [[:expired_trustedclient, :project_viewer_trustedclient],
875 [:project_viewer_trustedclient, :expired_trustedclient]].each do |src, dst|
876 test "refuse to merge with expired token (#{src} -> #{dst})" do
878 post(:merge, params: {
879 new_user_token: api_client_authorizations(dst).api_token,
880 new_owner_uuid: api_client_authorizations(dst).user.uuid,
881 redirect_to_new_user: true,
887 [['src', :active_trustedclient],
888 ['dst', :project_viewer_trustedclient]].each do |which_scoped, auth|
889 test "refuse to merge with scoped #{which_scoped} token" do
890 act_as_system_user do
891 api_client_authorizations(auth).update_attributes(scopes: ["GET /", "POST /", "PUT /"])
893 authorize_with(:active_trustedclient)
894 post(:merge, params: {
895 new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token,
896 new_owner_uuid: users(:project_viewer).uuid,
897 redirect_to_new_user: true,
903 test "refuse to merge if new_owner_uuid is not writable" do
904 authorize_with(:project_viewer_trustedclient)
905 post(:merge, params: {
906 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
907 new_owner_uuid: groups(:anonymously_accessible_project).uuid,
908 redirect_to_new_user: true,
913 test "refuse to merge if new_owner_uuid is empty" do
914 authorize_with(:project_viewer_trustedclient)
915 post(:merge, params: {
916 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
918 redirect_to_new_user: true,
923 test "refuse to merge if new_owner_uuid is not provided" do
924 authorize_with(:project_viewer_trustedclient)
925 post(:merge, params: {
926 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
927 redirect_to_new_user: true,
932 test "refuse to update redirect_to_user_uuid directly" do
933 authorize_with(:active_trustedclient)
934 patch(:update, params: {
935 id: users(:active).uuid,
937 redirect_to_user_uuid: users(:active).uuid,
943 test "merge 'project_viewer' account into 'active' account" do
944 authorize_with(:project_viewer_trustedclient)
945 post(:merge, params: {
946 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
947 new_owner_uuid: users(:active).uuid,
948 redirect_to_new_user: true,
950 assert_response(:success)
951 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
953 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
955 assert_not_nil(auth.user)
956 assert_equal(users(:active).uuid, auth.user.uuid)
960 test "merge 'project_viewer' account into 'active' account using uuids" do
961 authorize_with(:admin)
962 post(:merge, params: {
963 old_user_uuid: users(:project_viewer).uuid,
964 new_user_uuid: users(:active).uuid,
965 new_owner_uuid: users(:active).uuid,
966 redirect_to_new_user: true,
968 assert_response(:success)
969 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
971 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
973 assert_not_nil(auth.user)
974 assert_equal(users(:active).uuid, auth.user.uuid)
977 test "merge 'project_viewer' account into 'active' account using uuids denied for non-admin" do
978 authorize_with(:active)
979 post(:merge, params: {
980 old_user_uuid: users(:project_viewer).uuid,
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 missing old_user_uuid" do
990 authorize_with(:admin)
991 post(:merge, params: {
992 new_user_uuid: users(:active).uuid,
993 new_owner_uuid: users(:active).uuid,
994 redirect_to_new_user: true,
997 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1000 test "merge 'project_viewer' account into 'active' account using uuids denied missing new_user_uuid" do
1001 authorize_with(:admin)
1002 post(:merge, params: {
1003 old_user_uuid: users(:project_viewer).uuid,
1004 new_owner_uuid: users(:active).uuid,
1005 redirect_to_new_user: true,
1007 assert_response(422)
1008 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1011 test "merge 'project_viewer' account into 'active' account using uuids denied bogus old_user_uuid" do
1012 authorize_with(:admin)
1013 post(:merge, params: {
1014 old_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
1015 new_user_uuid: users(:active).uuid,
1016 new_owner_uuid: users(:active).uuid,
1017 redirect_to_new_user: true,
1019 assert_response(422)
1020 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1023 test "merge 'project_viewer' account into 'active' account using uuids denied bogus new_user_uuid" do
1024 authorize_with(:admin)
1025 post(:merge, params: {
1026 old_user_uuid: users(:project_viewer).uuid,
1027 new_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
1028 new_owner_uuid: users(:active).uuid,
1029 redirect_to_new_user: true,
1031 assert_response(422)
1032 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1035 test "batch update fails for non-admin" do
1036 authorize_with(:active)
1037 patch(:batch_update, params: {updates: {}})
1038 assert_response(403)
1041 test "batch update" do
1042 existinguuid = 'remot-tpzed-foobarbazwazqux'
1043 newuuid = 'remot-tpzed-newnarnazwazqux'
1044 act_as_system_user do
1045 User.create!(uuid: existinguuid, email: 'root@existing.example.com')
1048 authorize_with(:admin)
1049 patch(:batch_update,
1053 'first_name' => 'root',
1054 'email' => 'root@remot.example.com',
1055 'is_active' => true,
1057 'prefs' => {'foo' => 'bar'},
1060 'first_name' => 'noot',
1061 'email' => 'root@remot.example.com',
1064 assert_response(:success)
1066 assert_equal('root', User.find_by_uuid(existinguuid).first_name)
1067 assert_equal('root@remot.example.com', User.find_by_uuid(existinguuid).email)
1068 assert_equal(true, User.find_by_uuid(existinguuid).is_active)
1069 assert_equal(true, User.find_by_uuid(existinguuid).is_admin)
1070 assert_equal({'foo' => 'bar'}, User.find_by_uuid(existinguuid).prefs)
1072 assert_equal('noot', User.find_by_uuid(newuuid).first_name)
1073 assert_equal('root@remot.example.com', User.find_by_uuid(newuuid).email)
1076 NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
1077 "last_name", "username"].sort
1079 def check_non_admin_index
1080 assert_response :success
1081 response_items = json_response["items"]
1082 assert_not_nil response_items
1083 response_items.each do |user_data|
1084 check_non_admin_item user_data
1085 assert(user_data["is_active"], "non-admin index returned inactive user")
1089 def check_non_admin_show
1090 assert_response :success
1091 check_non_admin_item json_response
1094 def check_non_admin_item user_data
1095 assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
1096 "data in response had missing or extra attributes")
1097 assert_equal("arvados#user", user_data["kind"])
1101 def check_readable_users_index expect_present, expect_missing
1102 response_uuids = json_response["items"].map { |u| u["uuid"] }
1103 expect_present.each do |user_key|
1104 assert_includes(response_uuids, users(user_key).uuid,
1105 "#{user_key} missing from index")
1107 expect_missing.each do |user_key|
1108 refute_includes(response_uuids, users(user_key).uuid,
1109 "#{user_key} included in index")
1113 def check_inactive_user_findable(params={})
1114 inactive_user = users(:inactive)
1115 get(:index, params: params.merge(filters: [["email", "=", inactive_user.email]]))
1116 assert_response :success
1117 user_list = json_response["items"]
1118 assert_equal(1, user_list.andand.count)
1119 # This test needs to check a column non-admins have no access to,
1120 # to ensure that admins see all user information.
1121 assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
1122 "admin's filtered index did not return inactive user")
1125 def verify_links_added more
1126 assert_equal @initial_link_count+more, Link.count,
1127 "Started with #{@initial_link_count} links, expected #{more} more"
1130 def find_obj_in_resp (response_items, object_type, head_kind=nil)
1132 response_items.each { |x|
1137 if object_type == 'User'
1138 if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
1142 else # looking for a link
1143 if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind