Merge branch 'master' into 6219-fuse-performance-testing
[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 = 'usertestrepo'
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         "foo/#{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: 'usertestrepo',
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: 'usertestrepo',
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: 'usertestrepo',
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: 'usertestrepo',
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: 'usertestrepo',
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         'inactiveuser/usertestrepo', 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: 'usertestrepo',
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: 'usertestrepo',
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: 'usertestrepo',
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         'foo/usertestrepo', 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: 'usertestrepo',
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: 'usertestrepo',
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: 'usertestrepo',
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         'foo/usertestrepo', 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: 'usertestrepo',
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: 'usertestrepo',
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         'foo/usertestrepo', 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: 'usertestrepo',
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         'active/usertestrepo', 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     repos_query = Repository.where(owner_uuid: active_user.uuid)
551     repo_link_query = Link.where(tail_uuid: active_user.uuid,
552                                  link_class: "permission", name: "can_manage")
553     repos_count = repos_query.count
554     repo_link_count = repo_link_query.count
555
556     # invoke setup with a repository
557     post :setup, {
558       vm_uuid: @vm_uuid,
559       uuid: active_user['uuid'],
560       email: 'junk_email'
561     }
562
563     assert_response :success
564
565     response_items = JSON.parse(@response.body)['items']
566     created = find_obj_in_resp response_items, 'User', nil
567
568     assert_equal active_user['email'], created['email'], 'expected original email'
569
570     # verify links
571     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
572         'All users', created['uuid'], 'arvados#group', true, 'Group'
573
574     assert_equal(repos_count, repos_query.count)
575     assert_equal(repo_link_count, repo_link_query.count)
576
577     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
578         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
579   end
580
581   test "unsetup active user" do
582     active_user = users(:active)
583     assert_not_nil active_user['uuid'], 'expected uuid for the active user'
584     assert active_user['is_active'], 'expected is_active for active user'
585
586     verify_link_existence active_user['uuid'], active_user['email'],
587           false, true, true, true, true
588
589     authorize_with :admin
590
591     # now unsetup this user
592     post :unsetup, id: active_user['uuid']
593     assert_response :success
594
595     response_user = JSON.parse(@response.body)
596     assert_not_nil response_user['uuid'], 'expected uuid for the upsetup user'
597     assert_equal active_user['uuid'], response_user['uuid'], 'expected uuid not found'
598     assert !response_user['is_active'], 'expected user to be inactive'
599     assert !response_user['is_invited'], 'expected user to be uninvited'
600
601     verify_link_existence response_user['uuid'], response_user['email'],
602           false, false, false, false, false
603
604     active_user = User.find_by_uuid(users(:active).uuid)
605     readable_groups = active_user.groups_i_can(:read)
606     all_users_group = Group.all.collect(&:uuid).select { |g| g.match /-f+$/ }
607     refute_includes(readable_groups, all_users_group,
608                     "active user can read All Users group after being deactivated")
609     assert_equal(false, active_user.is_invited,
610                  "active user is_invited after being deactivated & reloaded")
611   end
612
613   test "setup user with send notification param false and verify no email" do
614     authorize_with :admin
615
616     post :setup, {
617       openid_prefix: 'http://www.example.com/account',
618       send_notification_email: 'false',
619       user: {
620         email: "foo@example.com"
621       }
622     }
623
624     assert_response :success
625     response_items = JSON.parse(@response.body)['items']
626     created = find_obj_in_resp response_items, 'User', nil
627     assert_not_nil created['uuid'], 'expected uuid for the new user'
628     assert_equal created['email'], 'foo@example.com', 'expected given email'
629
630     setup_email = ActionMailer::Base.deliveries.last
631     assert_nil setup_email, 'expected no setup email'
632   end
633
634   test "setup user with send notification param true and verify email" do
635     authorize_with :admin
636
637     post :setup, {
638       openid_prefix: 'http://www.example.com/account',
639       send_notification_email: 'true',
640       user: {
641         email: "foo@example.com"
642       }
643     }
644
645     assert_response :success
646     response_items = JSON.parse(@response.body)['items']
647     created = find_obj_in_resp response_items, 'User', nil
648     assert_not_nil created['uuid'], 'expected uuid for the new user'
649     assert_equal created['email'], 'foo@example.com', 'expected given email'
650
651     setup_email = ActionMailer::Base.deliveries.last
652     assert_not_nil setup_email, 'Expected email after setup'
653
654     assert_equal Rails.configuration.user_notifier_email_from, setup_email.from[0]
655     assert_equal 'foo@example.com', setup_email.to[0]
656     assert_equal 'Welcome to Curoverse - shell account enabled', setup_email.subject
657     assert (setup_email.body.to_s.include? 'Your Arvados shell account has been set up'),
658         'Expected Your Arvados shell account has been set up in email body'
659     assert (setup_email.body.to_s.include? Rails.configuration.workbench_address),
660         'Expected workbench url in email body'
661   end
662
663   test "non-admin user can get basic information about readable users" do
664     authorize_with :spectator
665     get(:index)
666     check_non_admin_index
667     check_readable_users_index [:spectator], [:inactive, :active]
668   end
669
670   test "non-admin user gets only safe attributes from users#show" do
671     g = act_as_system_user do
672       create :group
673     end
674     users = create_list :active_user, 2, join_groups: [g]
675     token = create :token, user: users[0]
676     authorize_with_token token
677     get :show, id: users[1].uuid
678     check_non_admin_show
679   end
680
681   [2, 4].each do |limit|
682     test "non-admin user can limit index to #{limit}" do
683       g = act_as_system_user do
684         create :group
685       end
686       users = create_list :active_user, 4, join_groups: [g]
687       token = create :token, user: users[0]
688
689       authorize_with_token token
690       get(:index, limit: limit)
691       check_non_admin_index
692       assert_equal(limit, json_response["items"].size,
693                    "non-admin index limit was ineffective")
694     end
695   end
696
697   test "admin has full index powers" do
698     authorize_with :admin
699     check_inactive_user_findable
700   end
701
702   test "reader token can grant admin index powers" do
703     authorize_with :spectator
704     check_inactive_user_findable(reader_tokens: [api_token(:admin)])
705   end
706
707   test "admin can filter on user.is_active" do
708     authorize_with :admin
709     get(:index, filters: [["is_active", "=", "true"]])
710     assert_response :success
711     check_readable_users_index [:active, :spectator], [:inactive]
712   end
713
714   test "admin can search where user.is_active" do
715     authorize_with :admin
716     get(:index, where: {is_active: true})
717     assert_response :success
718     check_readable_users_index [:active, :spectator], [:inactive]
719   end
720
721   test "update active_no_prefs user profile and expect notification email" do
722     authorize_with :admin
723
724     put :update, {
725       id: users(:active_no_prefs).uuid,
726       user: {
727         prefs: {:profile => {'organization' => 'example.com'}}
728       }
729     }
730     assert_response :success
731
732     found_email = false
733     ActionMailer::Base.deliveries.andand.each do |email|
734       if email.subject == "Profile created by #{users(:active_no_prefs).email}"
735         found_email = true
736         break
737       end
738     end
739     assert_equal true, found_email, 'Expected email after creating profile'
740   end
741
742   test "update active_no_prefs_profile user profile and expect notification email" do
743     authorize_with :admin
744
745     user = {}
746     user[:prefs] = users(:active_no_prefs_profile_no_getting_started_shown).prefs
747     user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
748     put :update, {
749       id: users(:active_no_prefs_profile_no_getting_started_shown).uuid,
750       user: user
751     }
752     assert_response :success
753
754     found_email = false
755     ActionMailer::Base.deliveries.andand.each do |email|
756       if email.subject == "Profile created by #{users(:active_no_prefs_profile_no_getting_started_shown).email}"
757         found_email = true
758         break
759       end
760     end
761     assert_equal true, found_email, 'Expected email after creating profile'
762   end
763
764   test "update active user profile and expect no notification email" do
765     authorize_with :admin
766
767     put :update, {
768       id: users(:active).uuid,
769       user: {
770         prefs: {:profile => {'organization' => 'anotherexample.com'}}
771       }
772     }
773     assert_response :success
774
775     found_email = false
776     ActionMailer::Base.deliveries.andand.each do |email|
777       if email.subject == "Profile created by #{users(:active).email}"
778         found_email = true
779         break
780       end
781     end
782     assert_equal false, found_email, 'Expected no email after updating profile'
783   end
784
785   test "user API response includes writable_by" do
786     authorize_with :active
787     get :current
788     assert_response :success
789     assert_includes(json_response["writable_by"], users(:active).uuid,
790                     "user's writable_by should include self")
791     assert_includes(json_response["writable_by"], users(:active).owner_uuid,
792                     "user's writable_by should include its owner_uuid")
793   end
794
795
796   NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
797                          "last_name"].sort
798
799   def check_non_admin_index
800     assert_response :success
801     response_items = json_response["items"]
802     assert_not_nil response_items
803     response_items.each do |user_data|
804       check_non_admin_item user_data
805       assert(user_data["is_active"], "non-admin index returned inactive user")
806     end
807   end
808
809   def check_non_admin_show
810     assert_response :success
811     check_non_admin_item json_response
812   end
813
814   def check_non_admin_item user_data
815     assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
816                  "data in response had missing or extra attributes")
817     assert_equal("arvados#user", user_data["kind"])
818   end
819
820
821   def check_readable_users_index expect_present, expect_missing
822     response_uuids = json_response["items"].map { |u| u["uuid"] }
823     expect_present.each do |user_key|
824       assert_includes(response_uuids, users(user_key).uuid,
825                       "#{user_key} missing from index")
826     end
827     expect_missing.each do |user_key|
828       refute_includes(response_uuids, users(user_key).uuid,
829                       "#{user_key} included in index")
830     end
831   end
832
833   def check_inactive_user_findable(params={})
834     inactive_user = users(:inactive)
835     get(:index, params.merge(filters: [["email", "=", inactive_user.email]]))
836     assert_response :success
837     user_list = json_response["items"]
838     assert_equal(1, user_list.andand.count)
839     # This test needs to check a column non-admins have no access to,
840     # to ensure that admins see all user information.
841     assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
842                  "admin's filtered index did not return inactive user")
843   end
844
845   def verify_num_links (original_links, expected_additional_links)
846     links_now = Link.all
847     assert_equal expected_additional_links, Link.all.size-original_links.size,
848         "Expected #{expected_additional_links.inspect} more links"
849   end
850
851   def find_obj_in_resp (response_items, object_type, head_kind=nil)
852     return_obj = nil
853     response_items
854     response_items.each { |x|
855       if !x
856         next
857       end
858
859       if object_type == 'User'
860         if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
861           return_obj = x
862           break
863         end
864       else  # looking for a link
865         if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
866           return_obj = x
867           break
868         end
869       end
870     }
871     return return_obj
872   end
873 end