1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
6 require 'helpers/users_test_helper'
8 class Arvados::V1::UsersControllerTest < ActionController::TestCase
9 include CurrentApiClient
10 include UsersTestHelper
13 @initial_link_count = Link.count
14 @vm_uuid = virtual_machines(:testvm).uuid
15 ActionMailer::Base.deliveries = []
16 Rails.configuration.Users.ActivatedUsersAreVisibleToOthers = false
19 test "activate a user after signing UA" do
20 authorize_with :inactive_but_signed_user_agreement
21 post :activate, params: {id: users(:inactive_but_signed_user_agreement).uuid}
22 assert_response :success
23 assert_not_nil assigns(:object)
24 me = JSON.parse(@response.body)
25 assert_equal true, me['is_active']
28 test "refuse to activate a user before signing UA" do
30 required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
35 Collection.uuid_like_pattern).
38 assert required_uuids.length > 0
40 signed_uuids = Link.where(owner_uuid: system_user_uuid,
41 link_class: 'signature',
43 tail_uuid: users(:inactive).uuid,
44 head_uuid: required_uuids).
47 assert_equal 0, signed_uuids.length
50 authorize_with :inactive
51 assert_equal false, users(:inactive).is_active
53 post :activate, params: {id: users(:inactive).uuid}
57 assert resp['errors'].first.include? 'Cannot activate without user agreements'
58 assert_nil resp['is_active']
61 test "activate an already-active user" do
62 authorize_with :active
63 post :activate, params: {id: users(:active).uuid}
64 assert_response :success
65 me = JSON.parse(@response.body)
66 assert_equal true, me['is_active']
69 test "respond 401 if given token exists but user record is missing" do
70 authorize_with :valid_token_deleted_user
71 get :current, format: :json
75 test "create new user with user as input" do
77 post :create, params: {
79 first_name: "test_first_name",
80 last_name: "test_last_name",
81 email: "foo@example.com"
84 assert_response :success
85 created = JSON.parse(@response.body)
86 assert_equal 'test_first_name', created['first_name']
87 assert_not_nil created['uuid'], 'expected uuid for the newly created user'
88 assert_not_nil created['email'], 'expected non-nil email'
89 assert_nil created['identity_url'], 'expected no identity_url'
92 test "create new user with empty username" do
94 post :create, params: {
96 first_name: "test_first_name",
97 last_name: "test_last_name",
101 assert_response :success
102 created = JSON.parse(@response.body)
103 assert_equal 'test_first_name', created['first_name']
104 assert_not_nil created['uuid'], 'expected uuid for the newly created user'
105 assert_nil created['email'], 'expected no email'
106 assert_nil created['username'], 'expected no username'
109 test "update user with empty username" do
110 authorize_with :admin
111 user = users('spectator')
112 assert_not_nil user['username']
113 put :update, params: {
114 id: users('spectator')['uuid'],
119 assert_response :success
120 updated = JSON.parse(@response.body)
121 assert_nil updated['username'], 'expected no username'
124 test "create user with user, vm and repo as input" do
125 authorize_with :admin
126 repo_name = 'usertestrepo'
128 post :setup, params: {
129 repo_name: repo_name,
131 uuid: 'zzzzz-tpzed-abcdefghijklmno',
132 first_name: "in_create_test_first_name",
133 last_name: "test_last_name",
134 email: "foo@example.com"
137 assert_response :success
138 response_items = JSON.parse(@response.body)['items']
140 created = find_obj_in_resp response_items, 'User', nil
142 assert_equal 'in_create_test_first_name', created['first_name']
143 assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
144 assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
145 assert_not_nil created['email'], 'expected non-nil email'
146 assert_nil created['identity_url'], 'expected no identity_url'
148 # repo link and link add user to 'All users' group
151 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
152 "foo/#{repo_name}", created['uuid'], 'arvados#repository', true, 'Repository'
154 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
155 'All users', created['uuid'], 'arvados#group', true, 'Group'
157 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
158 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
160 verify_system_group_permission_link_for created['uuid']
163 test "setup user with bogus uuid and expect error" do
164 authorize_with :admin
166 post :setup, params: {
168 repo_name: 'usertestrepo',
171 response_body = JSON.parse(@response.body)
172 response_errors = response_body['errors']
173 assert_not_nil response_errors, 'Expected error in response'
174 assert (response_errors.first.include? 'Path not found'), 'Expected 404'
177 test "setup user with bogus uuid in user and expect error" do
178 authorize_with :admin
180 post :setup, params: {
181 user: {uuid: 'bogus_uuid'},
182 repo_name: 'usertestrepo',
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 RuntimeError'
192 test "setup user with no uuid and user, expect error" do
193 authorize_with :admin
195 post :setup, params: {
196 repo_name: 'usertestrepo',
199 response_body = JSON.parse(@response.body)
200 response_errors = response_body['errors']
201 assert_not_nil response_errors, 'Expected error in response'
202 assert (response_errors.first.include? 'Required uuid or user'),
203 'Expected ArgumentError'
206 test "setup user with no uuid and email, expect error" do
207 authorize_with :admin
209 post :setup, params: {
211 repo_name: 'usertestrepo',
214 response_body = JSON.parse(@response.body)
215 response_errors = response_body['errors']
216 assert_not_nil response_errors, 'Expected error in response'
217 assert (response_errors.first.include? '<ArgumentError: Require user email'),
218 'Expected ArgumentError'
221 test "invoke setup with existing uuid, vm and repo and verify links" do
222 authorize_with :admin
223 inactive_user = users(:inactive)
225 post :setup, params: {
226 uuid: users(:inactive).uuid,
227 repo_name: 'usertestrepo',
231 assert_response :success
233 response_items = JSON.parse(@response.body)['items']
234 resp_obj = find_obj_in_resp response_items, 'User', nil
236 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
237 assert_equal inactive_user['uuid'], resp_obj['uuid']
238 assert_equal inactive_user['email'], resp_obj['email'],
239 'expecting inactive user email'
241 # expect repo and vm links
242 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
243 'inactiveuser/usertestrepo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
245 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
246 @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
249 test "invoke setup with existing uuid but different email, expect original email" do
250 authorize_with :admin
251 inactive_user = users(:inactive)
253 post :setup, params: {
254 uuid: inactive_user['uuid'],
255 user: {email: 'junk_email'}
258 assert_response :success
260 response_items = JSON.parse(@response.body)['items']
261 resp_obj = find_obj_in_resp response_items, 'User', nil
263 assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
264 assert_equal inactive_user['uuid'], resp_obj['uuid']
265 assert_equal inactive_user['email'], resp_obj['email'],
266 'expecting inactive user email'
269 test "setup user with valid email and repo as input" do
270 authorize_with :admin
272 post :setup, params: {
273 repo_name: 'usertestrepo',
274 user: {email: 'foo@example.com'},
277 assert_response :success
278 response_items = JSON.parse(@response.body)['items']
279 response_object = find_obj_in_resp response_items, 'User', nil
280 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
281 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
283 # three extra links; system_group, group and repo perms
287 test "setup user with fake vm and expect error" do
288 authorize_with :admin
290 post :setup, params: {
291 repo_name: 'usertestrepo',
292 vm_uuid: 'no_such_vm',
293 user: {email: 'foo@example.com'},
296 response_body = JSON.parse(@response.body)
297 response_errors = response_body['errors']
298 assert_not_nil response_errors, 'Expected error in response'
299 assert (response_errors.first.include? "No vm found for no_such_vm"),
300 'Expected RuntimeError: No vm found for no_such_vm'
303 test "setup user with valid email, repo and real vm as input" do
304 authorize_with :admin
306 post :setup, params: {
307 repo_name: 'usertestrepo',
309 user: {email: 'foo@example.com'}
312 assert_response :success
313 response_items = JSON.parse(@response.body)['items']
314 response_object = find_obj_in_resp response_items, 'User', nil
315 assert_not_nil response_object['uuid'], 'expected uuid for the new user'
316 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
318 # four extra links; system_group, group, vm, repo
322 test "setup user with valid email, no vm and no repo as input" do
323 authorize_with :admin
325 post :setup, params: {
326 user: {email: 'foo@example.com'},
329 assert_response :success
330 response_items = JSON.parse(@response.body)['items']
331 response_object = find_obj_in_resp response_items, 'User', nil
332 assert_not_nil response_object['uuid'], 'expected uuid for new user'
333 assert_equal response_object['email'], 'foo@example.com', 'expected given email'
335 # two extra links; system_group, and group
338 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
339 'All users', response_object['uuid'], 'arvados#group', true, 'Group'
341 verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
342 'foo/usertestrepo', response_object['uuid'], 'arvados#repository', true, 'Repository'
344 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
345 nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
348 test "setup user with email, first name, repo name and vm uuid" do
349 authorize_with :admin
351 post :setup, params: {
352 repo_name: 'usertestrepo',
355 first_name: 'test_first_name',
356 email: 'foo@example.com'
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_equal response_object['email'], 'foo@example.com', 'expected given email'
365 assert_equal 'test_first_name', response_object['first_name'],
366 'expecting first name'
368 # four extra links; system_group, group, repo and vm
372 test "setup user with an existing user email and check different object is created" do
373 authorize_with :admin
374 inactive_user = users(:inactive)
376 post :setup, params: {
377 repo_name: 'usertestrepo',
379 email: inactive_user['email']
383 assert_response :success
384 response_items = JSON.parse(@response.body)['items']
385 response_object = find_obj_in_resp response_items, 'User', nil
386 assert_not_nil response_object['uuid'], 'expected uuid for new user'
387 assert_not_equal response_object['uuid'], inactive_user['uuid'],
388 'expected different uuid after create operation'
389 assert_equal inactive_user['email'], response_object['email'], 'expected given email'
390 # system_group, group, and repo. No vm link.
394 test "setup user with openid prefix" do
395 authorize_with :admin
397 post :setup, params: {
398 repo_name: 'usertestrepo',
400 first_name: "in_create_test_first_name",
401 last_name: "test_last_name",
402 email: "foo@example.com"
406 assert_response :success
408 response_items = JSON.parse(@response.body)['items']
409 created = find_obj_in_resp response_items, 'User', nil
411 assert_equal 'in_create_test_first_name', created['first_name']
412 assert_not_nil created['uuid'], 'expected uuid for new user'
413 assert_not_nil created['email'], 'expected non-nil email'
414 assert_nil created['identity_url'], 'expected no identity_url'
417 # three new links: system_group, repo, and 'All users' group.
420 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
421 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
423 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
424 'All users', created['uuid'], 'arvados#group', true, 'Group'
426 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
427 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
430 test "setup user with user, vm and repo and verify links" do
431 authorize_with :admin
433 post :setup, params: {
435 first_name: "in_create_test_first_name",
436 last_name: "test_last_name",
437 email: "foo@example.com"
440 repo_name: 'usertestrepo',
443 assert_response :success
445 response_items = JSON.parse(@response.body)['items']
446 created = find_obj_in_resp response_items, 'User', nil
448 assert_equal 'in_create_test_first_name', created['first_name']
449 assert_not_nil created['uuid'], 'expected uuid for new user'
450 assert_not_nil created['email'], 'expected non-nil email'
451 assert_nil created['identity_url'], 'expected no identity_url'
453 # four new links: system_group, repo, vm and 'All users' group link
456 # system_group isn't part of the response. See User#add_system_group_permission_link
458 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
459 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
461 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
462 'All users', created['uuid'], 'arvados#group', true, 'Group'
464 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
465 @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
468 test "create user as non admin user and expect error" do
469 authorize_with :active
471 post :create, params: {
472 user: {email: 'foo@example.com'}
475 response_body = JSON.parse(@response.body)
476 response_errors = response_body['errors']
477 assert_not_nil response_errors, 'Expected error in response'
478 assert (response_errors.first.include? 'PermissionDenied'),
479 'Expected PermissionDeniedError'
482 test "setup user as non admin user and expect error" do
483 authorize_with :active
485 post :setup, params: {
486 user: {email: 'foo@example.com'}
489 response_body = JSON.parse(@response.body)
490 response_errors = response_body['errors']
491 assert_not_nil response_errors, 'Expected error in response'
492 assert (response_errors.first.include? 'Forbidden'),
493 'Expected Forbidden error'
496 test "setup active user with repo and no vm" do
497 authorize_with :admin
498 active_user = users(:active)
500 # invoke setup with a repository
501 post :setup, params: {
502 repo_name: 'usertestrepo',
503 uuid: active_user['uuid']
506 assert_response :success
508 response_items = JSON.parse(@response.body)['items']
509 created = find_obj_in_resp response_items, 'User', nil
511 assert_equal active_user[:email], created['email'], 'expected input email'
514 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
515 'All users', created['uuid'], 'arvados#group', true, 'Group'
517 verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
518 'active/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository'
520 verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
521 nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
524 test "setup active user with vm and no repo" do
525 authorize_with :admin
526 active_user = users(:active)
527 repos_query = Repository.where(owner_uuid: active_user.uuid)
528 repo_link_query = Link.where(tail_uuid: active_user.uuid,
529 link_class: "permission", name: "can_manage")
530 repos_count = repos_query.count
531 repo_link_count = repo_link_query.count
533 # invoke setup with a repository
534 post :setup, params: {
536 uuid: active_user['uuid'],
540 assert_response :success
542 response_items = JSON.parse(@response.body)['items']
543 created = find_obj_in_resp response_items, 'User', nil
545 assert_equal active_user['email'], created['email'], 'expected original email'
548 verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
549 'All users', created['uuid'], 'arvados#group', true, 'Group'
551 assert_equal(repos_count, repos_query.count)
552 assert_equal(repo_link_count, repo_link_query.count)
554 verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
555 @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
558 test "unsetup active user" do
559 active_user = users(:active)
560 assert_not_nil active_user['uuid'], 'expected uuid for the active user'
561 assert active_user['is_active'], 'expected is_active for active user'
563 verify_link_existence active_user['uuid'], active_user['email'],
564 false, true, true, true, true
566 authorize_with :admin
568 # now unsetup this user
569 post :unsetup, params: {id: active_user['uuid']}
570 assert_response :success
572 response_user = JSON.parse(@response.body)
573 assert_not_nil response_user['uuid'], 'expected uuid for the upsetup user'
574 assert_equal active_user['uuid'], response_user['uuid'], 'expected uuid not found'
575 assert !response_user['is_active'], 'expected user to be inactive'
576 assert !response_user['is_invited'], 'expected user to be uninvited'
578 verify_link_existence response_user['uuid'], response_user['email'],
579 false, false, false, false, false
581 active_user = User.find_by_uuid(users(:active).uuid)
582 readable_groups = active_user.groups_i_can(:read)
583 all_users_group = Group.all.collect(&:uuid).select { |g| g.match(/-f+$/) }
584 refute_includes(readable_groups, all_users_group,
585 "active user can read All Users group after being deactivated")
586 assert_equal(false, active_user.is_invited,
587 "active user is_invited after being deactivated & reloaded")
590 test "setup user with send notification param false and verify no email" do
591 authorize_with :admin
593 post :setup, params: {
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 Rails.configuration.Users.UserSetupMailText = %{
614 <% if not @user.full_name.empty? -%>
615 <%= @user.full_name %>,
620 Your Arvados shell account has been set up. Please visit the virtual machines page <% if Rails.configuration.Services.Workbench1.ExternalURL %>at
622 <%= Rails.configuration.Services.Workbench1.ExternalURL %><%= "/" if !Rails.configuration.Services.Workbench1.ExternalURL.to_s.end_with?("/") %>users/<%= @user.uuid%>/virtual_machines <% else %><% end %>
624 for connection instructions.
630 post :setup, params: {
631 send_notification_email: 'true',
633 email: "foo@example.com"
637 assert_response :success
638 response_items = JSON.parse(@response.body)['items']
639 created = find_obj_in_resp response_items, 'User', nil
640 assert_not_nil created['uuid'], 'expected uuid for the new user'
641 assert_equal created['email'], 'foo@example.com', 'expected given email'
643 setup_email = ActionMailer::Base.deliveries.last
644 assert_not_nil setup_email, 'Expected email after setup'
646 assert_equal Rails.configuration.Users.UserNotifierEmailFrom, setup_email.from[0]
647 assert_equal 'foo@example.com', setup_email.to[0]
648 assert_equal 'Welcome to Arvados - account enabled', setup_email.subject
649 assert (setup_email.body.to_s.include? 'Your Arvados shell account has been set up'),
650 'Expected Your Arvados shell account has been set up in email body'
651 assert (setup_email.body.to_s.include? "#{Rails.configuration.Services.Workbench1.ExternalURL}users/#{created['uuid']}/virtual_machines"), 'Expected virtual machines url in email body'
654 test "setup inactive user by changing is_active to true" do
655 authorize_with :admin
656 active_user = users(:active)
658 # invoke setup with a repository
659 put :update, params: {
660 id: active_user['uuid'],
665 assert_response :success
666 assert_equal active_user['uuid'], json_response['uuid']
667 updated = User.where(uuid: active_user['uuid']).first
668 assert_equal(true, updated.is_active)
669 assert_equal({read: true, write: true}, updated.group_permissions[all_users_group_uuid])
672 test "non-admin user can get basic information about readable users" do
673 authorize_with :spectator
675 check_non_admin_index
676 check_readable_users_index [:spectator], [:inactive, :active]
677 json_response["items"].each do |u|
678 if u["uuid"] == users(:spectator).uuid
679 assert_equal true, u["can_write"]
680 assert_equal true, u["can_manage"]
685 test "non-admin user gets only safe attributes from users#show" do
686 g = act_as_system_user do
687 create :group, group_class: "role"
689 users = create_list :active_user, 2, join_groups: [g]
690 token = create :token, user: users[0]
691 authorize_with_token token
692 get :show, params: {id: users[1].uuid}
696 [2, 4].each do |limit|
697 test "non-admin user can limit index to #{limit}" do
698 g = act_as_system_user do
699 create :group, group_class: "role"
701 users = create_list :active_user, 4, join_groups: [g]
702 token = create :token, user: users[0]
704 authorize_with_token token
705 get(:index, params: {limit: limit})
706 check_non_admin_index
707 assert_equal(limit, json_response["items"].size,
708 "non-admin index limit was ineffective")
712 test "admin has full index powers" do
713 authorize_with :admin
714 check_inactive_user_findable
717 test "reader token can grant admin index powers" do
718 authorize_with :spectator
719 check_inactive_user_findable(reader_tokens: [api_token(:admin)])
722 test "admin can filter on user.is_active" do
723 authorize_with :admin
724 get(:index, params: {filters: [["is_active", "=", "true"]]})
725 assert_response :success
726 check_readable_users_index [:active, :spectator], [:inactive]
729 test "admin can search where user.is_active" do
730 authorize_with :admin
731 get(:index, params: {where: {is_active: true}})
732 assert_response :success
733 check_readable_users_index [:active, :spectator], [:inactive]
736 test "update active_no_prefs user profile and expect notification email" do
737 authorize_with :admin
739 put :update, params: {
740 id: users(:active_no_prefs).uuid,
742 prefs: {:profile => {'organization' => 'example.com'}}
745 assert_response :success
748 ActionMailer::Base.deliveries.andand.each do |email|
749 if email.subject == "Profile created by #{users(:active_no_prefs).email}"
754 assert_equal true, found_email, 'Expected email after creating profile'
757 test "update active_no_prefs_profile user profile and expect notification email" do
758 authorize_with :admin
761 user[:prefs] = users(:active_no_prefs_profile_no_getting_started_shown).prefs
762 user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
763 put :update, params: {
764 id: users(:active_no_prefs_profile_no_getting_started_shown).uuid,
767 assert_response :success
770 ActionMailer::Base.deliveries.andand.each do |email|
771 if email.subject == "Profile created by #{users(:active_no_prefs_profile_no_getting_started_shown).email}"
776 assert_equal true, found_email, 'Expected email after creating profile'
779 test "update active user profile and expect no notification email" do
780 authorize_with :admin
782 put :update, params: {
783 id: users(:active).uuid,
785 prefs: {:profile => {'organization' => 'anotherexample.com'}}
788 assert_response :success
791 ActionMailer::Base.deliveries.andand.each do |email|
792 if email.subject == "Profile created by #{users(:active).email}"
797 assert_equal false, found_email, 'Expected no email after updating profile'
800 test "user API response includes writable_by" do
801 authorize_with :active
803 assert_response :success
804 assert_includes(json_response["writable_by"], users(:active).uuid,
805 "user's writable_by should include self")
806 assert_includes(json_response["writable_by"], users(:active).owner_uuid,
807 "user's writable_by should include its owner_uuid")
810 test "merge with redirect_to_user_uuid=false" do
811 authorize_with :project_viewer_trustedclient
812 tok = api_client_authorizations(:project_viewer).api_token
813 post :merge, params: {
814 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
815 new_owner_uuid: users(:active).uuid,
816 redirect_to_new_user: false,
818 assert_response(:success)
819 assert_nil(User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
821 # because redirect_to_new_user=false, token owned by
822 # project_viewer should be deleted
823 auth = ApiClientAuthorization.validate(token: tok)
827 test "merge remote to local as admin" do
828 authorize_with :admin
830 remoteuser = User.create!(uuid: "zbbbb-tpzed-remotremotremot")
831 tok = ApiClientAuthorization.create!(user: remoteuser, api_client: api_clients(:untrusted)).api_token
833 auth = ApiClientAuthorization.validate(token: tok)
835 assert_nil(remoteuser.redirect_to_user_uuid)
837 post :merge, params: {
838 new_user_uuid: users(:active).uuid,
839 old_user_uuid: remoteuser.uuid,
840 new_owner_uuid: users(:active).uuid,
841 redirect_to_new_user: true,
843 assert_response(:success)
845 assert_equal(users(:active).uuid, remoteuser.redirect_to_user_uuid)
847 # token owned by remoteuser should be deleted
848 auth = ApiClientAuthorization.validate(token: tok)
852 test "refuse to merge user into self" do
853 authorize_with(:active_trustedclient)
854 post(:merge, params: {
855 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
856 new_owner_uuid: users(:active).uuid,
857 redirect_to_new_user: true,
862 [[:active, :project_viewer_trustedclient],
863 [:active_trustedclient, :project_viewer]].each do |src, dst|
864 test "refuse to merge with untrusted token (#{src} -> #{dst})" do
866 post(:merge, params: {
867 new_user_token: api_client_authorizations(dst).api_token,
868 new_owner_uuid: api_client_authorizations(dst).user.uuid,
869 redirect_to_new_user: true,
875 [[:expired_trustedclient, :project_viewer_trustedclient],
876 [:project_viewer_trustedclient, :expired_trustedclient]].each do |src, dst|
877 test "refuse to merge with expired token (#{src} -> #{dst})" do
879 post(:merge, params: {
880 new_user_token: api_client_authorizations(dst).api_token,
881 new_owner_uuid: api_client_authorizations(dst).user.uuid,
882 redirect_to_new_user: true,
888 [['src', :active_trustedclient],
889 ['dst', :project_viewer_trustedclient]].each do |which_scoped, auth|
890 test "refuse to merge with scoped #{which_scoped} token" do
891 act_as_system_user do
892 api_client_authorizations(auth).update(scopes: ["GET /", "POST /", "PUT /"])
894 authorize_with(:active_trustedclient)
895 post(:merge, params: {
896 new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token,
897 new_owner_uuid: users(:project_viewer).uuid,
898 redirect_to_new_user: true,
904 test "refuse to merge if new_owner_uuid is not writable" do
905 authorize_with(:project_viewer_trustedclient)
906 post(:merge, params: {
907 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
908 new_owner_uuid: groups(:anonymously_accessible_project).uuid,
909 redirect_to_new_user: true,
914 test "refuse to merge if new_owner_uuid is empty" do
915 authorize_with(:project_viewer_trustedclient)
916 post(:merge, params: {
917 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
919 redirect_to_new_user: true,
924 test "refuse to merge if new_owner_uuid is not provided" do
925 authorize_with(:project_viewer_trustedclient)
926 post(:merge, params: {
927 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
928 redirect_to_new_user: true,
933 test "refuse to update redirect_to_user_uuid directly" do
934 authorize_with(:active_trustedclient)
935 patch(:update, params: {
936 id: users(:active).uuid,
938 redirect_to_user_uuid: users(:active).uuid,
944 test "merge 'project_viewer' account into 'active' account" do
945 authorize_with(:project_viewer_trustedclient)
946 post(:merge, params: {
947 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
948 new_owner_uuid: users(:active).uuid,
949 redirect_to_new_user: true,
951 assert_response(:success)
952 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
954 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
956 assert_not_nil(auth.user)
957 assert_equal(users(:active).uuid, auth.user.uuid)
961 test "merge 'project_viewer' account into 'active' account using uuids" do
962 authorize_with(:admin)
963 post(:merge, params: {
964 old_user_uuid: users(:project_viewer).uuid,
965 new_user_uuid: users(:active).uuid,
966 new_owner_uuid: users(:active).uuid,
967 redirect_to_new_user: true,
969 assert_response(:success)
970 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
972 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
974 assert_not_nil(auth.user)
975 assert_equal(users(:active).uuid, auth.user.uuid)
978 test "merge 'project_viewer' account into 'active' account using uuids denied for non-admin" do
979 authorize_with(:active)
980 post(:merge, params: {
981 old_user_uuid: users(:project_viewer).uuid,
982 new_user_uuid: users(:active).uuid,
983 new_owner_uuid: users(:active).uuid,
984 redirect_to_new_user: true,
987 assert_nil(users(:project_viewer).redirect_to_user_uuid)
990 test "merge 'project_viewer' account into 'active' account using uuids denied missing old_user_uuid" do
991 authorize_with(:admin)
992 post(:merge, params: {
993 new_user_uuid: users(:active).uuid,
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 "merge 'project_viewer' account into 'active' account using uuids denied missing new_user_uuid" do
1002 authorize_with(:admin)
1003 post(:merge, params: {
1004 old_user_uuid: users(:project_viewer).uuid,
1005 new_owner_uuid: users(:active).uuid,
1006 redirect_to_new_user: true,
1008 assert_response(422)
1009 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1012 test "merge 'project_viewer' account into 'active' account using uuids denied bogus old_user_uuid" do
1013 authorize_with(:admin)
1014 post(:merge, params: {
1015 old_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
1016 new_user_uuid: users(:active).uuid,
1017 new_owner_uuid: users(:active).uuid,
1018 redirect_to_new_user: true,
1020 assert_response(422)
1021 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1024 test "merge 'project_viewer' account into 'active' account using uuids denied bogus new_user_uuid" do
1025 authorize_with(:admin)
1026 post(:merge, params: {
1027 old_user_uuid: users(:project_viewer).uuid,
1028 new_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
1029 new_owner_uuid: users(:active).uuid,
1030 redirect_to_new_user: true,
1032 assert_response(422)
1033 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1036 test "batch update fails for non-admin" do
1037 authorize_with(:active)
1038 patch(:batch_update, params: {updates: {}})
1039 assert_response(403)
1042 test "batch update" do
1043 existinguuid = 'remot-tpzed-foobarbazwazqux'
1044 newuuid = 'remot-tpzed-newnarnazwazqux'
1045 unchanginguuid = 'remot-tpzed-nochangingattrs'
1046 conflictinguuid1 = 'remot-tpzed-conflictingnam1'
1047 conflictinguuid2 = 'remot-tpzed-conflictingnam2'
1048 act_as_system_user do
1049 User.create!(uuid: existinguuid, email: 'root@existing.example.com')
1050 User.create!(uuid: unchanginguuid, email: 'root@unchanging.example.com', prefs: {'foo' => {'bar' => 'baz'}})
1052 assert_equal(1, Log.where(object_uuid: unchanginguuid).count)
1054 Rails.configuration.Login.LoginCluster = 'remot'
1056 authorize_with(:admin)
1057 patch(:batch_update,
1061 'first_name' => 'root',
1062 'email' => 'root@remot.example.com',
1063 'is_active' => true,
1065 'prefs' => {'foo' => 'bar'},
1066 'is_invited' => true
1069 'first_name' => 'noot',
1070 'email' => 'root@remot.example.com',
1072 'is_invited' => true
1075 'email' => 'root@unchanging.example.com',
1076 'prefs' => {'foo' => {'bar' => 'baz'}},
1077 'is_invited' => true
1079 conflictinguuid1 => {
1080 'email' => 'root@conflictingname1.example.com',
1081 'username' => 'active',
1082 'is_invited' => true
1084 conflictinguuid2 => {
1085 'email' => 'root@conflictingname2.example.com',
1086 'username' => 'federatedactive',
1087 'is_invited' => true
1090 assert_response(:success)
1092 assert_equal('root', User.find_by_uuid(existinguuid).first_name)
1093 assert_equal('root@remot.example.com', User.find_by_uuid(existinguuid).email)
1094 assert_equal(true, User.find_by_uuid(existinguuid).is_active)
1095 assert_equal(true, User.find_by_uuid(existinguuid).is_admin)
1096 assert_equal({'foo' => 'bar'}, User.find_by_uuid(existinguuid).prefs)
1098 assert_equal('noot', User.find_by_uuid(newuuid).first_name)
1099 assert_equal('root@remot.example.com', User.find_by_uuid(newuuid).email)
1101 assert_equal(1, Log.where(object_uuid: unchanginguuid).count)
1104 test 'batch update does not produce spurious log events' do
1105 # test for bug #21304
1107 existinguuid = 'remot-tpzed-foobarbazwazqux'
1108 act_as_system_user do
1109 User.create!(uuid: existinguuid,
1114 assert_equal(1, Log.where(object_uuid: existinguuid).count)
1116 Rails.configuration.Login.LoginCluster = 'remot'
1118 authorize_with(:admin)
1119 patch(:batch_update,
1123 'first_name' => 'root',
1126 'is_active' => true,
1127 'is_invited' => true
1130 assert_response(:success)
1132 assert_equal(1, Log.where(object_uuid: existinguuid).count)
1135 NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "is_admin", "is_invited", "email", "first_name",
1136 "last_name", "username", "can_write", "can_manage"].sort
1138 def check_non_admin_index
1139 assert_response :success
1140 response_items = json_response["items"]
1141 assert_not_nil response_items
1142 response_items.each do |user_data|
1143 check_non_admin_item user_data
1144 assert(user_data["is_active"], "non-admin index returned inactive user")
1148 def check_non_admin_show
1149 assert_response :success
1150 check_non_admin_item json_response
1153 def check_non_admin_item user_data
1154 assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
1155 "data in response had missing or extra attributes")
1156 assert_equal("arvados#user", user_data["kind"])
1160 def check_readable_users_index expect_present, expect_missing
1161 response_uuids = json_response["items"].map { |u| u["uuid"] }
1162 expect_present.each do |user_key|
1163 assert_includes(response_uuids, users(user_key).uuid,
1164 "#{user_key} missing from index")
1166 expect_missing.each do |user_key|
1167 refute_includes(response_uuids, users(user_key).uuid,
1168 "#{user_key} included in index")
1172 def check_inactive_user_findable(params={})
1173 inactive_user = users(:inactive)
1174 get(:index, params: params.merge(filters: [["email", "=", inactive_user.email]]))
1175 assert_response :success
1176 user_list = json_response["items"]
1177 assert_equal(1, user_list.andand.count)
1178 # This test needs to check a column non-admins have no access to,
1179 # to ensure that admins see all user information.
1180 assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
1181 "admin's filtered index did not return inactive user")
1184 def verify_links_added more
1185 assert_equal @initial_link_count+more, Link.count,
1186 "Started with #{@initial_link_count} links, expected #{more} more"
1189 def find_obj_in_resp (response_items, object_type, head_kind=nil)
1191 response_items.each { |x|
1196 if object_type == 'User'
1197 if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
1201 else # looking for a link
1202 if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind