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_read',
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_read',
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_read',
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_read',
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_read',
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_read',
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}, 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]
679 test "non-admin user gets only safe attributes from users#show" do
680 g = act_as_system_user do
681 create :group, group_class: "role"
683 users = create_list :active_user, 2, join_groups: [g]
684 token = create :token, user: users[0]
685 authorize_with_token token
686 get :show, params: {id: users[1].uuid}
690 [2, 4].each do |limit|
691 test "non-admin user can limit index to #{limit}" do
692 g = act_as_system_user do
693 create :group, group_class: "role"
695 users = create_list :active_user, 4, join_groups: [g]
696 token = create :token, user: users[0]
698 authorize_with_token token
699 get(:index, params: {limit: limit})
700 check_non_admin_index
701 assert_equal(limit, json_response["items"].size,
702 "non-admin index limit was ineffective")
706 test "admin has full index powers" do
707 authorize_with :admin
708 check_inactive_user_findable
711 test "reader token can grant admin index powers" do
712 authorize_with :spectator
713 check_inactive_user_findable(reader_tokens: [api_token(:admin)])
716 test "admin can filter on user.is_active" do
717 authorize_with :admin
718 get(:index, params: {filters: [["is_active", "=", "true"]]})
719 assert_response :success
720 check_readable_users_index [:active, :spectator], [:inactive]
723 test "admin can search where user.is_active" do
724 authorize_with :admin
725 get(:index, params: {where: {is_active: true}})
726 assert_response :success
727 check_readable_users_index [:active, :spectator], [:inactive]
730 test "update active_no_prefs user profile and expect notification email" do
731 authorize_with :admin
733 put :update, params: {
734 id: users(:active_no_prefs).uuid,
736 prefs: {:profile => {'organization' => 'example.com'}}
739 assert_response :success
742 ActionMailer::Base.deliveries.andand.each do |email|
743 if email.subject == "Profile created by #{users(:active_no_prefs).email}"
748 assert_equal true, found_email, 'Expected email after creating profile'
751 test "update active_no_prefs_profile user profile and expect notification email" do
752 authorize_with :admin
755 user[:prefs] = users(:active_no_prefs_profile_no_getting_started_shown).prefs
756 user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
757 put :update, params: {
758 id: users(:active_no_prefs_profile_no_getting_started_shown).uuid,
761 assert_response :success
764 ActionMailer::Base.deliveries.andand.each do |email|
765 if email.subject == "Profile created by #{users(:active_no_prefs_profile_no_getting_started_shown).email}"
770 assert_equal true, found_email, 'Expected email after creating profile'
773 test "update active user profile and expect no notification email" do
774 authorize_with :admin
776 put :update, params: {
777 id: users(:active).uuid,
779 prefs: {:profile => {'organization' => 'anotherexample.com'}}
782 assert_response :success
785 ActionMailer::Base.deliveries.andand.each do |email|
786 if email.subject == "Profile created by #{users(:active).email}"
791 assert_equal false, found_email, 'Expected no email after updating profile'
794 test "user API response includes writable_by" do
795 authorize_with :active
797 assert_response :success
798 assert_includes(json_response["writable_by"], users(:active).uuid,
799 "user's writable_by should include self")
800 assert_includes(json_response["writable_by"], users(:active).owner_uuid,
801 "user's writable_by should include its owner_uuid")
804 test "merge with redirect_to_user_uuid=false" do
805 authorize_with :project_viewer_trustedclient
806 tok = api_client_authorizations(:project_viewer).api_token
807 post :merge, params: {
808 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
809 new_owner_uuid: users(:active).uuid,
810 redirect_to_new_user: false,
812 assert_response(:success)
813 assert_nil(User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
815 # because redirect_to_new_user=false, token owned by
816 # project_viewer should be deleted
817 auth = ApiClientAuthorization.validate(token: tok)
821 test "merge remote to local as admin" do
822 authorize_with :admin
824 remoteuser = User.create!(uuid: "zbbbb-tpzed-remotremotremot")
825 tok = ApiClientAuthorization.create!(user: remoteuser, api_client: api_clients(:untrusted)).api_token
827 auth = ApiClientAuthorization.validate(token: tok)
829 assert_nil(remoteuser.redirect_to_user_uuid)
831 post :merge, params: {
832 new_user_uuid: users(:active).uuid,
833 old_user_uuid: remoteuser.uuid,
834 new_owner_uuid: users(:active).uuid,
835 redirect_to_new_user: true,
837 assert_response(:success)
839 assert_equal(users(:active).uuid, remoteuser.redirect_to_user_uuid)
841 # token owned by remoteuser should be deleted
842 auth = ApiClientAuthorization.validate(token: tok)
846 test "refuse to merge user into self" do
847 authorize_with(:active_trustedclient)
848 post(:merge, params: {
849 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
850 new_owner_uuid: users(:active).uuid,
851 redirect_to_new_user: true,
856 [[:active, :project_viewer_trustedclient],
857 [:active_trustedclient, :project_viewer]].each do |src, dst|
858 test "refuse to merge with untrusted token (#{src} -> #{dst})" do
860 post(:merge, params: {
861 new_user_token: api_client_authorizations(dst).api_token,
862 new_owner_uuid: api_client_authorizations(dst).user.uuid,
863 redirect_to_new_user: true,
869 [[:expired_trustedclient, :project_viewer_trustedclient],
870 [:project_viewer_trustedclient, :expired_trustedclient]].each do |src, dst|
871 test "refuse to merge with expired token (#{src} -> #{dst})" do
873 post(:merge, params: {
874 new_user_token: api_client_authorizations(dst).api_token,
875 new_owner_uuid: api_client_authorizations(dst).user.uuid,
876 redirect_to_new_user: true,
882 [['src', :active_trustedclient],
883 ['dst', :project_viewer_trustedclient]].each do |which_scoped, auth|
884 test "refuse to merge with scoped #{which_scoped} token" do
885 act_as_system_user do
886 api_client_authorizations(auth).update_attributes(scopes: ["GET /", "POST /", "PUT /"])
888 authorize_with(:active_trustedclient)
889 post(:merge, params: {
890 new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token,
891 new_owner_uuid: users(:project_viewer).uuid,
892 redirect_to_new_user: true,
898 test "refuse to merge if new_owner_uuid is not writable" do
899 authorize_with(:project_viewer_trustedclient)
900 post(:merge, params: {
901 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
902 new_owner_uuid: groups(:anonymously_accessible_project).uuid,
903 redirect_to_new_user: true,
908 test "refuse to merge if new_owner_uuid is empty" do
909 authorize_with(:project_viewer_trustedclient)
910 post(:merge, params: {
911 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
913 redirect_to_new_user: true,
918 test "refuse to merge if new_owner_uuid is not provided" do
919 authorize_with(:project_viewer_trustedclient)
920 post(:merge, params: {
921 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
922 redirect_to_new_user: true,
927 test "refuse to update redirect_to_user_uuid directly" do
928 authorize_with(:active_trustedclient)
929 patch(:update, params: {
930 id: users(:active).uuid,
932 redirect_to_user_uuid: users(:active).uuid,
938 test "merge 'project_viewer' account into 'active' account" do
939 authorize_with(:project_viewer_trustedclient)
940 post(:merge, params: {
941 new_user_token: api_client_authorizations(:active_trustedclient).api_token,
942 new_owner_uuid: users(:active).uuid,
943 redirect_to_new_user: true,
945 assert_response(:success)
946 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
948 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
950 assert_not_nil(auth.user)
951 assert_equal(users(:active).uuid, auth.user.uuid)
955 test "merge 'project_viewer' account into 'active' account using uuids" do
956 authorize_with(:admin)
957 post(:merge, params: {
958 old_user_uuid: users(:project_viewer).uuid,
959 new_user_uuid: users(:active).uuid,
960 new_owner_uuid: users(:active).uuid,
961 redirect_to_new_user: true,
963 assert_response(:success)
964 assert_equal(users(:active).uuid, User.unscoped.find_by_uuid(users(:project_viewer).uuid).redirect_to_user_uuid)
966 auth = ApiClientAuthorization.validate(token: api_client_authorizations(:project_viewer).api_token)
968 assert_not_nil(auth.user)
969 assert_equal(users(:active).uuid, auth.user.uuid)
972 test "merge 'project_viewer' account into 'active' account using uuids denied for non-admin" do
973 authorize_with(:active)
974 post(:merge, params: {
975 old_user_uuid: users(:project_viewer).uuid,
976 new_user_uuid: users(:active).uuid,
977 new_owner_uuid: users(:active).uuid,
978 redirect_to_new_user: true,
981 assert_nil(users(:project_viewer).redirect_to_user_uuid)
984 test "merge 'project_viewer' account into 'active' account using uuids denied missing old_user_uuid" do
985 authorize_with(:admin)
986 post(:merge, params: {
987 new_user_uuid: users(:active).uuid,
988 new_owner_uuid: users(:active).uuid,
989 redirect_to_new_user: true,
992 assert_nil(users(:project_viewer).redirect_to_user_uuid)
995 test "merge 'project_viewer' account into 'active' account using uuids denied missing new_user_uuid" do
996 authorize_with(:admin)
997 post(:merge, params: {
998 old_user_uuid: users(:project_viewer).uuid,
999 new_owner_uuid: users(:active).uuid,
1000 redirect_to_new_user: true,
1002 assert_response(422)
1003 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1006 test "merge 'project_viewer' account into 'active' account using uuids denied bogus old_user_uuid" do
1007 authorize_with(:admin)
1008 post(:merge, params: {
1009 old_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
1010 new_user_uuid: users(:active).uuid,
1011 new_owner_uuid: users(:active).uuid,
1012 redirect_to_new_user: true,
1014 assert_response(422)
1015 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1018 test "merge 'project_viewer' account into 'active' account using uuids denied bogus new_user_uuid" do
1019 authorize_with(:admin)
1020 post(:merge, params: {
1021 old_user_uuid: users(:project_viewer).uuid,
1022 new_user_uuid: "zzzzz-tpzed-bogusbogusbogus",
1023 new_owner_uuid: users(:active).uuid,
1024 redirect_to_new_user: true,
1026 assert_response(422)
1027 assert_nil(users(:project_viewer).redirect_to_user_uuid)
1030 test "batch update fails for non-admin" do
1031 authorize_with(:active)
1032 patch(:batch_update, params: {updates: {}})
1033 assert_response(403)
1036 test "batch update" do
1037 existinguuid = 'remot-tpzed-foobarbazwazqux'
1038 newuuid = 'remot-tpzed-newnarnazwazqux'
1039 unchanginguuid = 'remot-tpzed-nochangingattrs'
1040 act_as_system_user do
1041 User.create!(uuid: existinguuid, email: 'root@existing.example.com')
1042 User.create!(uuid: unchanginguuid, email: 'root@unchanging.example.com', prefs: {'foo' => {'bar' => 'baz'}})
1044 assert_equal(1, Log.where(object_uuid: unchanginguuid).count)
1046 authorize_with(:admin)
1047 patch(:batch_update,
1051 'first_name' => 'root',
1052 'email' => 'root@remot.example.com',
1053 'is_active' => true,
1055 'prefs' => {'foo' => 'bar'},
1058 'first_name' => 'noot',
1059 'email' => 'root@remot.example.com',
1063 'email' => 'root@unchanging.example.com',
1064 'prefs' => {'foo' => {'bar' => 'baz'}},
1067 assert_response(:success)
1069 assert_equal('root', User.find_by_uuid(existinguuid).first_name)
1070 assert_equal('root@remot.example.com', User.find_by_uuid(existinguuid).email)
1071 assert_equal(true, User.find_by_uuid(existinguuid).is_active)
1072 assert_equal(true, User.find_by_uuid(existinguuid).is_admin)
1073 assert_equal({'foo' => 'bar'}, User.find_by_uuid(existinguuid).prefs)
1075 assert_equal('noot', User.find_by_uuid(newuuid).first_name)
1076 assert_equal('root@remot.example.com', User.find_by_uuid(newuuid).email)
1078 assert_equal(1, Log.where(object_uuid: unchanginguuid).count)
1081 NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
1082 "last_name", "username"].sort
1084 def check_non_admin_index
1085 assert_response :success
1086 response_items = json_response["items"]
1087 assert_not_nil response_items
1088 response_items.each do |user_data|
1089 check_non_admin_item user_data
1090 assert(user_data["is_active"], "non-admin index returned inactive user")
1094 def check_non_admin_show
1095 assert_response :success
1096 check_non_admin_item json_response
1099 def check_non_admin_item user_data
1100 assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
1101 "data in response had missing or extra attributes")
1102 assert_equal("arvados#user", user_data["kind"])
1106 def check_readable_users_index expect_present, expect_missing
1107 response_uuids = json_response["items"].map { |u| u["uuid"] }
1108 expect_present.each do |user_key|
1109 assert_includes(response_uuids, users(user_key).uuid,
1110 "#{user_key} missing from index")
1112 expect_missing.each do |user_key|
1113 refute_includes(response_uuids, users(user_key).uuid,
1114 "#{user_key} included in index")
1118 def check_inactive_user_findable(params={})
1119 inactive_user = users(:inactive)
1120 get(:index, params: params.merge(filters: [["email", "=", inactive_user.email]]))
1121 assert_response :success
1122 user_list = json_response["items"]
1123 assert_equal(1, user_list.andand.count)
1124 # This test needs to check a column non-admins have no access to,
1125 # to ensure that admins see all user information.
1126 assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
1127 "admin's filtered index did not return inactive user")
1130 def verify_links_added more
1131 assert_equal @initial_link_count+more, Link.count,
1132 "Started with #{@initial_link_count} links, expected #{more} more"
1135 def find_obj_in_resp (response_items, object_type, head_kind=nil)
1137 response_items.each { |x|
1142 if object_type == 'User'
1143 if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
1147 else # looking for a link
1148 if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind