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