3889: split the test "setup user in multiple steps and verify response" into multiple...
[arvados.git] / services / api / test / functional / arvados / v1 / users_controller_test.rb
1 require 'test_helper'
2
3 class Arvados::V1::UsersControllerTest < ActionController::TestCase
4   include CurrentApiClient
5
6   setup do
7     @all_links_at_start = Link.all
8     @vm_uuid = virtual_machines(:testvm).uuid
9   end
10
11   test "activate a user after signing UA" do
12     authorize_with :inactive_but_signed_user_agreement
13     post :activate, id: users(:inactive_but_signed_user_agreement).uuid
14     assert_response :success
15     assert_not_nil assigns(:object)
16     me = JSON.parse(@response.body)
17     assert_equal true, me['is_active']
18   end
19
20   test "refuse to activate a user before signing UA" do
21     act_as_system_user do
22     required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
23                                 system_user_uuid,
24                                 'signature',
25                                 'require',
26                                 system_user_uuid,
27                                 Collection.uuid_like_pattern).
28       collect(&:head_uuid)
29
30       assert required_uuids.length > 0
31
32       signed_uuids = Link.where(owner_uuid: system_user_uuid,
33                                 link_class: 'signature',
34                                 name: 'click',
35                                 tail_uuid: users(:inactive).uuid,
36                                 head_uuid: required_uuids).
37         collect(&:head_uuid)
38
39       assert_equal 0, signed_uuids.length
40     end
41
42     authorize_with :inactive
43
44     post :activate, id: users(:inactive).uuid
45     assert_response 403
46
47     response_body = JSON.parse(@response.body)
48     assert response_body['errors'].first.include? 'Cannot activate without user agreements'
49   end
50
51   test "activate an already-active user" do
52     authorize_with :active
53     post :activate, id: users(:active).uuid
54     assert_response :success
55     me = JSON.parse(@response.body)
56     assert_equal true, me['is_active']
57   end
58
59   test "respond 401 if given token exists but user record is missing" do
60     authorize_with :valid_token_deleted_user
61     get :current, {format: :json}
62     assert_response 401
63   end
64
65   test "create new user with user as input" do
66     authorize_with :admin
67     post :create, user: {
68       first_name: "test_first_name",
69       last_name: "test_last_name",
70       email: "foo@example.com"
71     }
72     assert_response :success
73     created = JSON.parse(@response.body)
74     assert_equal 'test_first_name', created['first_name']
75     assert_not_nil created['uuid'], 'expected uuid for the newly created user'
76     assert_not_nil created['email'], 'expected non-nil email'
77     assert_nil created['identity_url'], 'expected no identity_url'
78   end
79
80   test "create user with user, vm and repo as input" do
81     authorize_with :admin
82     repo_name = 'test_repo'
83
84     post :setup, {
85       repo_name: repo_name,
86       openid_prefix: 'https://www.google.com/accounts/o8/id',
87       user: {
88         uuid: 'zzzzz-tpzed-abcdefghijklmno',
89         first_name: "in_create_test_first_name",
90         last_name: "test_last_name",
91         email: "foo@example.com"
92       }
93     }
94     assert_response :success
95     response_items = JSON.parse(@response.body)['items']
96
97     created = find_obj_in_resp response_items, 'User', nil
98
99     assert_equal 'in_create_test_first_name', created['first_name']
100     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
101     assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
102     assert_not_nil created['email'], 'expected non-nil email'
103     assert_nil created['identity_url'], 'expected no identity_url'
104
105     # arvados#user, repo link and link add user to 'All users' group
106     verify_num_links @all_links_at_start, 4
107
108     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
109         created['uuid'], created['email'], 'arvados#user', false, 'User'
110
111     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
112         repo_name, created['uuid'], 'arvados#repository', true, 'Repository'
113
114     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
115         'All users', created['uuid'], 'arvados#group', true, 'Group'
116
117     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
118         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
119
120     verify_system_group_permission_link_for created['uuid']
121   end
122
123   test "setup user with bogus uuid and expect error" do
124     authorize_with :admin
125
126     post :setup, {
127       uuid: 'bogus_uuid',
128       repo_name: 'test_repo',
129       vm_uuid: @vm_uuid
130     }
131     response_body = JSON.parse(@response.body)
132     response_errors = response_body['errors']
133     assert_not_nil response_errors, 'Expected error in response'
134     assert (response_errors.first.include? 'Path not found'), 'Expected 404'
135   end
136
137   test "setup user with bogus uuid in user and expect error" do
138     authorize_with :admin
139
140     post :setup, {
141       user: {uuid: 'bogus_uuid'},
142       repo_name: 'test_repo',
143       vm_uuid: @vm_uuid,
144       openid_prefix: 'https://www.google.com/accounts/o8/id'
145     }
146     response_body = JSON.parse(@response.body)
147     response_errors = response_body['errors']
148     assert_not_nil response_errors, 'Expected error in response'
149     assert (response_errors.first.include? 'ArgumentError: Require user email'),
150       'Expected RuntimeError'
151   end
152
153   test "setup user with no uuid and user, expect error" do
154     authorize_with :admin
155
156     post :setup, {
157       repo_name: 'test_repo',
158       vm_uuid: @vm_uuid,
159       openid_prefix: 'https://www.google.com/accounts/o8/id'
160     }
161     response_body = JSON.parse(@response.body)
162     response_errors = response_body['errors']
163     assert_not_nil response_errors, 'Expected error in response'
164     assert (response_errors.first.include? 'Required uuid or user'),
165         'Expected ArgumentError'
166   end
167
168   test "setup user with no uuid and email, expect error" do
169     authorize_with :admin
170
171     post :setup, {
172       user: {},
173       repo_name: 'test_repo',
174       vm_uuid: @vm_uuid,
175       openid_prefix: 'https://www.google.com/accounts/o8/id'
176     }
177     response_body = JSON.parse(@response.body)
178     response_errors = response_body['errors']
179     assert_not_nil response_errors, 'Expected error in response'
180     assert (response_errors.first.include? '<ArgumentError: Require user email'),
181         'Expected ArgumentError'
182   end
183
184   test "invoke setup with existing uuid, vm and repo and verify links" do
185     authorize_with :admin
186     inactive_user = users(:inactive)
187
188     post :setup, {
189       uuid: users(:inactive).uuid,
190       repo_name: 'test_repo',
191       vm_uuid: @vm_uuid
192     }
193
194     assert_response :success
195
196     response_items = JSON.parse(@response.body)['items']
197     resp_obj = find_obj_in_resp response_items, 'User', nil
198
199     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
200     assert_equal inactive_user['uuid'], resp_obj['uuid']
201     assert_equal inactive_user['email'], resp_obj['email'],
202         'expecting inactive user email'
203
204     # expect repo and vm links
205     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
206         'test_repo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
207
208     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
209         @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
210   end
211
212   test "invoke setup with existing uuid in user, verify response" do
213     authorize_with :admin
214     inactive_user = users(:inactive)
215
216     post :setup, {
217       user: {uuid: inactive_user['uuid']},
218       openid_prefix: 'https://www.google.com/accounts/o8/id'
219     }
220
221     assert_response :success
222
223     response_items = JSON.parse(@response.body)['items']
224     resp_obj = find_obj_in_resp response_items, 'User', nil
225
226     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
227     assert_equal inactive_user['uuid'], resp_obj['uuid']
228     assert_equal inactive_user['email'], resp_obj['email'],
229         'expecting inactive user email'
230   end
231
232   test "invoke setup with existing uuid but different email, expect original email" do
233     authorize_with :admin
234     inactive_user = users(:inactive)
235
236     post :setup, {
237       uuid: inactive_user['uuid'],
238       user: {email: 'junk_email'}
239     }
240
241     assert_response :success
242
243     response_items = JSON.parse(@response.body)['items']
244     resp_obj = find_obj_in_resp response_items, 'User', nil
245
246     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
247     assert_equal inactive_user['uuid'], resp_obj['uuid']
248     assert_equal inactive_user['email'], resp_obj['email'],
249         'expecting inactive user email'
250   end
251
252   test "setup user with valid email and repo as input" do
253     authorize_with :admin
254
255     post :setup, {
256       repo_name: 'test_repo',
257       user: {email: 'foo@example.com'},
258       openid_prefix: 'https://www.google.com/accounts/o8/id'
259     }
260
261     assert_response :success
262     response_items = JSON.parse(@response.body)['items']
263     response_object = find_obj_in_resp response_items, 'User', nil
264     assert_not_nil response_object['uuid'], 'expected uuid for the new user'
265     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
266
267     # four extra links; system_group, login, group and repo perms
268     verify_num_links @all_links_at_start, 4
269   end
270
271   test "setup user with fake vm and expect error" do
272     authorize_with :admin
273
274     post :setup, {
275       repo_name: 'test_repo',
276       vm_uuid: 'no_such_vm',
277       user: {email: 'foo@example.com'},
278       openid_prefix: 'https://www.google.com/accounts/o8/id'
279     }
280
281     response_body = JSON.parse(@response.body)
282     response_errors = response_body['errors']
283     assert_not_nil response_errors, 'Expected error in response'
284     assert (response_errors.first.include? "No vm found for no_such_vm"),
285           'Expected RuntimeError: No vm found for no_such_vm'
286   end
287
288   test "setup user with valid email, repo and real vm as input" do
289     authorize_with :admin
290
291     post :setup, {
292       repo_name: 'test_repo',
293       openid_prefix: 'https://www.google.com/accounts/o8/id',
294       vm_uuid: @vm_uuid,
295       user: {email: 'foo@example.com'}
296     }
297
298     assert_response :success
299     response_items = JSON.parse(@response.body)['items']
300     response_object = find_obj_in_resp response_items, 'User', nil
301     assert_not_nil response_object['uuid'], 'expected uuid for the new user'
302     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
303
304     # five extra links; system_group, login, group, vm, repo
305     verify_num_links @all_links_at_start, 5
306   end
307
308   test "setup user with valid email, no vm and no repo as input" do
309     authorize_with :admin
310
311     post :setup, {
312       user: {email: 'foo@example.com'},
313       openid_prefix: 'https://www.google.com/accounts/o8/id'
314     }
315
316     assert_response :success
317     response_items = JSON.parse(@response.body)['items']
318     response_object = find_obj_in_resp response_items, 'User', nil
319     assert_not_nil response_object['uuid'], 'expected uuid for new user'
320     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
321
322     # three extra links; system_group, login, and group
323     verify_num_links @all_links_at_start, 3
324
325     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
326         response_object['uuid'], response_object['email'], 'arvados#user', false, 'User'
327
328     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
329         'All users', response_object['uuid'], 'arvados#group', true, 'Group'
330
331     verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
332         'test_repo', response_object['uuid'], 'arvados#repository', true, 'Repository'
333
334     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
335         nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
336   end
337
338   test "setup user with email, first name, repo name and vm uuid" do
339     authorize_with :admin
340
341     post :setup, {
342       openid_prefix: 'https://www.google.com/accounts/o8/id',
343       repo_name: 'test_repo',
344       vm_uuid: @vm_uuid,
345       user: {
346         first_name: 'test_first_name',
347         email: 'foo@example.com'
348       }
349     }
350
351     assert_response :success
352     response_items = JSON.parse(@response.body)['items']
353     response_object = find_obj_in_resp response_items, 'User', nil
354     assert_not_nil response_object['uuid'], 'expected uuid for new user'
355     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
356     assert_equal 'test_first_name', response_object['first_name'],
357         'expecting first name'
358
359     # five extra links; system_group, login, group, repo and vm
360     verify_num_links @all_links_at_start, 5
361   end
362
363   test "setup user with an exising user email and check different object is created" do
364     authorize_with :admin
365     inactive_user = users(:inactive)
366
367     post :setup, {
368       openid_prefix: 'https://www.google.com/accounts/o8/id',
369       repo_name: 'test_repo',
370       user: {
371         email: inactive_user['email']
372       }
373     }
374
375     assert_response :success
376     response_items = JSON.parse(@response.body)['items']
377     response_object = find_obj_in_resp response_items, 'User', nil
378     assert_not_nil response_object['uuid'], 'expected uuid for new user'
379     assert_not_equal response_object['uuid'], inactive_user['uuid'],
380         'expected different uuid after create operation'
381     assert_equal inactive_user['email'], response_object['email'], 'expected given email'
382     # system_group, openid, group, and repo. No vm link.
383     verify_num_links @all_links_at_start, 4
384   end
385
386   test "setup user with openid prefix" do
387     authorize_with :admin
388
389     post :setup, {
390       repo_name: 'test_repo',
391       openid_prefix: 'http://www.example.com/account',
392       user: {
393         first_name: "in_create_test_first_name",
394         last_name: "test_last_name",
395         email: "foo@example.com"
396       }
397     }
398
399     assert_response :success
400
401     response_items = JSON.parse(@response.body)['items']
402     created = find_obj_in_resp response_items, 'User', nil
403
404     assert_equal 'in_create_test_first_name', created['first_name']
405     assert_not_nil created['uuid'], 'expected uuid for new user'
406     assert_not_nil created['email'], 'expected non-nil email'
407     assert_nil created['identity_url'], 'expected no identity_url'
408
409     # verify links
410     # four new links: system_group, arvados#user, repo, and 'All users' group.
411     verify_num_links @all_links_at_start, 4
412
413     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
414         created['uuid'], created['email'], 'arvados#user', false, 'User'
415
416     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
417         'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
418
419     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
420         'All users', created['uuid'], 'arvados#group', true, 'Group'
421
422     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
423         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
424   end
425
426   test "invoke setup with no openid prefix, expect error" do
427     authorize_with :admin
428
429     post :setup, {
430       repo_name: 'test_repo',
431       user: {
432         first_name: "in_create_test_first_name",
433         last_name: "test_last_name",
434         email: "foo@example.com"
435       }
436     }
437
438     response_body = JSON.parse(@response.body)
439     response_errors = response_body['errors']
440     assert_not_nil response_errors, 'Expected error in response'
441     assert (response_errors.first.include? 'openid_prefix parameter is missing'),
442         'Expected ArgumentError'
443   end
444
445   test "setup user with user, vm and repo and verify links" do
446     authorize_with :admin
447
448     post :setup, {
449       user: {
450         first_name: "in_create_test_first_name",
451         last_name: "test_last_name",
452         email: "foo@example.com"
453       },
454       vm_uuid: @vm_uuid,
455       repo_name: 'test_repo',
456       openid_prefix: 'https://www.google.com/accounts/o8/id'
457     }
458
459     assert_response :success
460
461     response_items = JSON.parse(@response.body)['items']
462     created = find_obj_in_resp response_items, 'User', nil
463
464     assert_equal 'in_create_test_first_name', created['first_name']
465     assert_not_nil created['uuid'], 'expected uuid for new user'
466     assert_not_nil created['email'], 'expected non-nil email'
467     assert_nil created['identity_url'], 'expected no identity_url'
468
469     # five new links: system_group, arvados#user, repo, vm and 'All
470     # users' group link
471     verify_num_links @all_links_at_start, 5
472
473     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
474         created['uuid'], created['email'], 'arvados#user', false, 'User'
475
476     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
477         'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
478
479     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
480         'All users', created['uuid'], 'arvados#group', true, 'Group'
481
482     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
483         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
484   end
485
486   test "create user as non admin user and expect error" do
487     authorize_with :active
488
489     post :create, {
490       user: {email: 'foo@example.com'}
491     }
492
493     response_body = JSON.parse(@response.body)
494     response_errors = response_body['errors']
495     assert_not_nil response_errors, 'Expected error in response'
496     assert (response_errors.first.include? 'PermissionDenied'),
497           'Expected PermissionDeniedError'
498   end
499
500   test "setup user as non admin user and expect error" do
501     authorize_with :active
502
503     post :setup, {
504       openid_prefix: 'https://www.google.com/accounts/o8/id',
505       user: {email: 'foo@example.com'}
506     }
507
508     response_body = JSON.parse(@response.body)
509     response_errors = response_body['errors']
510     assert_not_nil response_errors, 'Expected error in response'
511     assert (response_errors.first.include? 'Forbidden'),
512           'Expected Forbidden error'
513   end
514
515   test "setup active user with repo and no vm" do
516     authorize_with :admin
517     active_user = users(:active)
518
519     # invoke setup with a repository
520     post :setup, {
521       repo_name: 'new_repo',
522       uuid: active_user['uuid']
523     }
524
525     assert_response :success
526
527     response_items = JSON.parse(@response.body)['items']
528     created = find_obj_in_resp response_items, 'User', nil
529
530     assert_equal active_user[:email], created['email'], 'expected input email'
531
532      # verify links
533     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
534         'All users', created['uuid'], 'arvados#group', true, 'Group'
535
536     verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage',
537         'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
538
539     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
540         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
541   end
542
543   test "setup active user with vm and no repo" do
544     authorize_with :admin
545     active_user = users(:active)
546
547     # invoke setup with a repository
548     post :setup, {
549       vm_uuid: @vm_uuid,
550       uuid: active_user['uuid'],
551       email: 'junk_email'
552     }
553
554     assert_response :success
555
556     response_items = JSON.parse(@response.body)['items']
557     created = find_obj_in_resp response_items, 'User', nil
558
559     assert_equal active_user['email'], created['email'], 'expected original email'
560
561     # verify links
562     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
563         'All users', created['uuid'], 'arvados#group', true, 'Group'
564
565     verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage',
566         'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
567
568     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
569         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
570   end
571
572   test "unsetup active user" do
573     active_user = users(:active)
574     assert_not_nil active_user['uuid'], 'expected uuid for the active user'
575     assert active_user['is_active'], 'expected is_active for active user'
576
577     verify_link_existence active_user['uuid'], active_user['email'],
578           false, true, false, true, true
579
580     authorize_with :admin
581
582     # now unsetup this user
583     post :unsetup, id: active_user['uuid']
584     assert_response :success
585
586     response_user = JSON.parse(@response.body)
587     assert_not_nil response_user['uuid'], 'expected uuid for the upsetup user'
588     assert_equal active_user['uuid'], response_user['uuid'], 'expected uuid not found'
589     assert !response_user['is_active'], 'expected user to be inactive'
590     assert !response_user['is_invited'], 'expected user to be uninvited'
591
592     verify_link_existence response_user['uuid'], response_user['email'],
593           false, false, false, false, false
594
595     active_user = User.find_by_uuid(users(:active).uuid)
596     readable_groups = active_user.groups_i_can(:read)
597     all_users_group = Group.all.collect(&:uuid).select { |g| g.match /-f+$/ }
598     refute_includes(readable_groups, all_users_group,
599                     "active user can read All Users group after being deactivated")
600     assert_equal(false, active_user.is_invited,
601                  "active user is_invited after being deactivated & reloaded")
602   end
603
604   test "setup user with send notification param false and verify no email" do
605     authorize_with :admin
606
607     post :setup, {
608       openid_prefix: 'http://www.example.com/account',
609       send_notification_email: 'false',
610       user: {
611         email: "foo@example.com"
612       }
613     }
614
615     assert_response :success
616     response_items = JSON.parse(@response.body)['items']
617     created = find_obj_in_resp response_items, 'User', nil
618     assert_not_nil created['uuid'], 'expected uuid for the new user'
619     assert_equal created['email'], 'foo@example.com', 'expected given email'
620
621     setup_email = ActionMailer::Base.deliveries.last
622     assert_nil setup_email, 'expected no setup email'
623   end
624
625   test "setup user with send notification param true and verify email" do
626     authorize_with :admin
627
628     post :setup, {
629       openid_prefix: 'http://www.example.com/account',
630       send_notification_email: 'true',
631       user: {
632         email: "foo@example.com"
633       }
634     }
635
636     assert_response :success
637     response_items = JSON.parse(@response.body)['items']
638     created = find_obj_in_resp response_items, 'User', nil
639     assert_not_nil created['uuid'], 'expected uuid for the new user'
640     assert_equal created['email'], 'foo@example.com', 'expected given email'
641
642     setup_email = ActionMailer::Base.deliveries.last
643     assert_not_nil setup_email, 'Expected email after setup'
644
645     assert_equal Rails.configuration.user_notifier_email_from, setup_email.from[0]
646     assert_equal 'foo@example.com', setup_email.to[0]
647     assert_equal 'Welcome to Curoverse', setup_email.subject
648     assert (setup_email.body.to_s.include? 'Your Arvados account has been set up'),
649         'Expected Your Arvados account has been set up in email body'
650     assert (setup_email.body.to_s.include? 'foo@example.com'),
651         'Expected user email in email body'
652     assert (setup_email.body.to_s.include? Rails.configuration.workbench_address),
653         'Expected workbench url in email body'
654   end
655
656   test "non-admin user can get basic information about readable users" do
657     authorize_with :spectator
658     get(:index)
659     check_non_admin_index
660     check_readable_users_index [:spectator], [:inactive, :active]
661   end
662
663   test "non-admin user gets only safe attributes from users#show" do
664     g = act_as_system_user do
665       create :group
666     end
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, id: users[1].uuid
671     check_non_admin_show
672   end
673
674   test "non-admin user can limit index" do
675     g = act_as_system_user do
676       create :group
677     end
678     users = create_list :active_user, 4, join_groups: [g]
679     token = create :token, user: users[0]
680
681     [2, 4].each do |limit|
682       authorize_with_token token
683       get(:index, limit: limit)
684       check_non_admin_index
685       assert_equal(limit, json_response["items"].size,
686                    "non-admin index limit was ineffective")
687     end
688   end
689
690   test "admin has full index powers" do
691     authorize_with :admin
692     check_inactive_user_findable
693   end
694
695   test "reader token can grant admin index powers" do
696     authorize_with :spectator
697     check_inactive_user_findable(reader_tokens: [api_token(:admin)])
698   end
699
700   test "admin can filter on user.is_active" do
701     authorize_with :admin
702     get(:index, filters: [["is_active", "=", "true"]])
703     assert_response :success
704     check_readable_users_index [:active, :spectator], [:inactive]
705   end
706
707   test "admin can search where user.is_active" do
708     authorize_with :admin
709     get(:index, where: {is_active: true})
710     assert_response :success
711     check_readable_users_index [:active, :spectator], [:inactive]
712   end
713
714   test "update active_no_prefs user profile and expect notification email" do
715     authorize_with :admin
716
717     put :update, {
718       id: users(:active_no_prefs).uuid,
719       user: {
720         prefs: {:profile => {'organization' => 'example.com'}}
721       }
722     }
723     assert_response :success
724
725     found_email = false
726     ActionMailer::Base.deliveries.andand.each do |email|
727       if email.subject == "Profile created by #{users(:active_no_prefs).email}"
728         found_email = true
729         break
730       end
731     end
732     assert_equal true, found_email, 'Expected email after creating profile'
733   end
734
735   test "update active_no_prefs_profile user profile and expect notification email" do
736     authorize_with :admin
737
738     user = {}
739     user[:prefs] = users(:active_no_prefs_profile).prefs
740     user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
741     put :update, {
742       id: users(:active_no_prefs_profile).uuid,
743       user: user
744     }
745     assert_response :success
746
747     found_email = false
748     ActionMailer::Base.deliveries.andand.each do |email|
749       if email.subject == "Profile created by #{users(:active_no_prefs_profile).email}"
750         found_email = true
751         break
752       end
753     end
754     assert_equal true, found_email, 'Expected email after creating profile'
755   end
756
757   test "update active user profile and expect no notification email" do
758     authorize_with :admin
759
760     put :update, {
761       id: users(:active).uuid,
762       user: {
763         prefs: {:profile => {'organization' => 'anotherexample.com'}}
764       }
765     }
766     assert_response :success
767
768     found_email = false
769     ActionMailer::Base.deliveries.andand.each do |email|
770       if email.subject == "Profile created by #{users(:active).email}"
771         found_email = true
772         break
773       end
774     end
775     assert_equal false, found_email, 'Expected no email after updating profile'
776   end
777
778
779   NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
780                          "last_name"].sort
781
782   def check_non_admin_index
783     assert_response :success
784     response_items = json_response["items"]
785     assert_not_nil response_items
786     response_items.each do |user_data|
787       check_non_admin_item user_data
788       assert(user_data["is_active"], "non-admin index returned inactive user")
789     end
790   end
791
792   def check_non_admin_show
793     assert_response :success
794     check_non_admin_item json_response
795   end
796
797   def check_non_admin_item user_data
798     assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
799                  "data in response had missing or extra attributes")
800     assert_equal("arvados#user", user_data["kind"])
801   end
802
803
804   def check_readable_users_index expect_present, expect_missing
805     response_uuids = json_response["items"].map { |u| u["uuid"] }
806     expect_present.each do |user_key|
807       assert_includes(response_uuids, users(user_key).uuid,
808                       "#{user_key} missing from index")
809     end
810     expect_missing.each do |user_key|
811       refute_includes(response_uuids, users(user_key).uuid,
812                       "#{user_key} included in index")
813     end
814   end
815
816   def check_inactive_user_findable(params={})
817     inactive_user = users(:inactive)
818     get(:index, params.merge(filters: [["email", "=", inactive_user.email]]))
819     assert_response :success
820     user_list = json_response["items"]
821     assert_equal(1, user_list.andand.count)
822     # This test needs to check a column non-admins have no access to,
823     # to ensure that admins see all user information.
824     assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
825                  "admin's filtered index did not return inactive user")
826   end
827
828   def verify_num_links (original_links, expected_additional_links)
829     links_now = Link.all
830     assert_equal expected_additional_links, Link.all.size-original_links.size,
831         "Expected #{expected_additional_links.inspect} more links"
832   end
833
834   def find_obj_in_resp (response_items, object_type, head_kind=nil)
835     return_obj = nil
836     response_items
837     response_items.each { |x|
838       if !x
839         next
840       end
841
842       if object_type == 'User'
843         if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
844           return_obj = x
845           break
846         end
847       else  # looking for a link
848         if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
849           return_obj = x
850           break
851         end
852       end
853     }
854     return return_obj
855   end
856
857   def verify_link(response_items, link_object_name, expect_link, link_class,
858         link_name, head_uuid, tail_uuid, head_kind, fetch_object, class_name)
859
860     link = find_obj_in_resp response_items, 'Link', link_object_name
861
862     if !expect_link
863       assert_nil link, "Expected no link for #{link_object_name}"
864       return
865     end
866
867     assert_not_nil link, "Expected link for #{link_object_name}"
868
869     if fetch_object
870       object = Object.const_get(class_name).where(name: head_uuid)
871       assert [] != object, "expected #{class_name} with name #{head_uuid}"
872       head_uuid = object.first[:uuid]
873     end
874     assert_equal link_class, link['link_class'],
875         "did not find expected link_class for #{link_object_name}"
876
877     assert_equal link_name, link['name'],
878         "did not find expected link_name for #{link_object_name}"
879
880     assert_equal tail_uuid, link['tail_uuid'],
881         "did not find expected tail_uuid for #{link_object_name}"
882
883     assert_equal head_kind, link['head_kind'],
884         "did not find expected head_kind for #{link_object_name}"
885
886     assert_equal head_uuid, link['head_uuid'],
887         "did not find expected head_uuid for #{link_object_name}"
888   end
889
890   def verify_link_existence uuid, email, expect_oid_login_perms,
891       expect_repo_perms, expect_vm_perms, expect_group_perms, expect_signatures
892     # verify that all links are deleted for the user
893     oid_login_perms = Link.where(tail_uuid: email,
894                                  link_class: 'permission',
895                                  name: 'can_login').where("head_uuid like ?", User.uuid_like_pattern)
896     if expect_oid_login_perms
897       assert oid_login_perms.any?, "expected oid_login_perms"
898     else
899       assert !oid_login_perms.any?, "expected all oid_login_perms deleted"
900     end
901
902     repo_perms = Link.where(tail_uuid: uuid,
903                             link_class: 'permission',
904                             name: 'can_manage').where("head_uuid like ?", Repository.uuid_like_pattern)
905     if expect_repo_perms
906       assert repo_perms.any?, "expected repo_perms"
907     else
908       assert !repo_perms.any?, "expected all repo_perms deleted"
909     end
910
911     vm_login_perms = Link.
912       where(tail_uuid: uuid,
913             link_class: 'permission',
914             name: 'can_login').
915       where("head_uuid like ?",
916             VirtualMachine.uuid_like_pattern).
917       where('uuid <> ?',
918             links(:auto_setup_vm_login_username_can_login_to_test_vm).uuid)
919     if expect_vm_perms
920       assert vm_login_perms.any?, "expected vm_login_perms"
921     else
922       assert !vm_login_perms.any?, "expected all vm_login_perms deleted"
923     end
924
925     group = Group.where(name: 'All users').select do |g|
926       g[:uuid].match /-f+$/
927     end.first
928     group_read_perms = Link.where(tail_uuid: uuid,
929                                   head_uuid: group[:uuid],
930                                   link_class: 'permission',
931                                   name: 'can_read')
932     if expect_group_perms
933       assert group_read_perms.any?, "expected all users group read perms"
934     else
935       assert !group_read_perms.any?, "expected all users group perm deleted"
936     end
937
938     signed_uuids = Link.where(link_class: 'signature',
939                               tail_uuid: uuid)
940
941     if expect_signatures
942       assert signed_uuids.any?, "expected signatures"
943     else
944       assert !signed_uuids.any?, "expected all signatures deleted"
945     end
946
947   end
948
949   def verify_system_group_permission_link_for user_uuid
950     assert_equal 1, Link.where(link_class: 'permission',
951                                name: 'can_manage',
952                                tail_uuid: system_group_uuid,
953                                head_uuid: user_uuid).count
954   end
955 end