6320: API virtual machines login method include groups information.
[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', setup_email.subject
657     assert (setup_email.body.to_s.include? 'Your Arvados account has been set up'),
658         'Expected Your Arvados account has been set up in email body'
659     assert (setup_email.body.to_s.include? 'foo@example.com'),
660         'Expected user email in email body'
661     assert (setup_email.body.to_s.include? Rails.configuration.workbench_address),
662         'Expected workbench url in email body'
663   end
664
665   test "non-admin user can get basic information about readable users" do
666     authorize_with :spectator
667     get(:index)
668     check_non_admin_index
669     check_readable_users_index [:spectator], [:inactive, :active]
670   end
671
672   test "non-admin user gets only safe attributes from users#show" do
673     g = act_as_system_user do
674       create :group
675     end
676     users = create_list :active_user, 2, join_groups: [g]
677     token = create :token, user: users[0]
678     authorize_with_token token
679     get :show, id: users[1].uuid
680     check_non_admin_show
681   end
682
683   [2, 4].each do |limit|
684     test "non-admin user can limit index to #{limit}" do
685       g = act_as_system_user do
686         create :group
687       end
688       users = create_list :active_user, 4, join_groups: [g]
689       token = create :token, user: users[0]
690
691       authorize_with_token token
692       get(:index, limit: limit)
693       check_non_admin_index
694       assert_equal(limit, json_response["items"].size,
695                    "non-admin index limit was ineffective")
696     end
697   end
698
699   test "admin has full index powers" do
700     authorize_with :admin
701     check_inactive_user_findable
702   end
703
704   test "reader token can grant admin index powers" do
705     authorize_with :spectator
706     check_inactive_user_findable(reader_tokens: [api_token(:admin)])
707   end
708
709   test "admin can filter on user.is_active" do
710     authorize_with :admin
711     get(:index, filters: [["is_active", "=", "true"]])
712     assert_response :success
713     check_readable_users_index [:active, :spectator], [:inactive]
714   end
715
716   test "admin can search where user.is_active" do
717     authorize_with :admin
718     get(:index, where: {is_active: true})
719     assert_response :success
720     check_readable_users_index [:active, :spectator], [:inactive]
721   end
722
723   test "update active_no_prefs user profile and expect notification email" do
724     authorize_with :admin
725
726     put :update, {
727       id: users(:active_no_prefs).uuid,
728       user: {
729         prefs: {:profile => {'organization' => 'example.com'}}
730       }
731     }
732     assert_response :success
733
734     found_email = false
735     ActionMailer::Base.deliveries.andand.each do |email|
736       if email.subject == "Profile created by #{users(:active_no_prefs).email}"
737         found_email = true
738         break
739       end
740     end
741     assert_equal true, found_email, 'Expected email after creating profile'
742   end
743
744   test "update active_no_prefs_profile user profile and expect notification email" do
745     authorize_with :admin
746
747     user = {}
748     user[:prefs] = users(:active_no_prefs_profile_no_getting_started_shown).prefs
749     user[:prefs][:profile] = {:profile => {'organization' => 'example.com'}}
750     put :update, {
751       id: users(:active_no_prefs_profile_no_getting_started_shown).uuid,
752       user: user
753     }
754     assert_response :success
755
756     found_email = false
757     ActionMailer::Base.deliveries.andand.each do |email|
758       if email.subject == "Profile created by #{users(:active_no_prefs_profile_no_getting_started_shown).email}"
759         found_email = true
760         break
761       end
762     end
763     assert_equal true, found_email, 'Expected email after creating profile'
764   end
765
766   test "update active user profile and expect no notification email" do
767     authorize_with :admin
768
769     put :update, {
770       id: users(:active).uuid,
771       user: {
772         prefs: {:profile => {'organization' => 'anotherexample.com'}}
773       }
774     }
775     assert_response :success
776
777     found_email = false
778     ActionMailer::Base.deliveries.andand.each do |email|
779       if email.subject == "Profile created by #{users(:active).email}"
780         found_email = true
781         break
782       end
783     end
784     assert_equal false, found_email, 'Expected no email after updating profile'
785   end
786
787   test "user API response includes writable_by" do
788     authorize_with :active
789     get :current
790     assert_response :success
791     assert_includes(json_response["writable_by"], users(:active).uuid,
792                     "user's writable_by should include self")
793     assert_includes(json_response["writable_by"], users(:active).owner_uuid,
794                     "user's writable_by should include its owner_uuid")
795   end
796
797
798   NON_ADMIN_USER_DATA = ["uuid", "kind", "is_active", "email", "first_name",
799                          "last_name"].sort
800
801   def check_non_admin_index
802     assert_response :success
803     response_items = json_response["items"]
804     assert_not_nil response_items
805     response_items.each do |user_data|
806       check_non_admin_item user_data
807       assert(user_data["is_active"], "non-admin index returned inactive user")
808     end
809   end
810
811   def check_non_admin_show
812     assert_response :success
813     check_non_admin_item json_response
814   end
815
816   def check_non_admin_item user_data
817     assert_equal(NON_ADMIN_USER_DATA, user_data.keys.sort,
818                  "data in response had missing or extra attributes")
819     assert_equal("arvados#user", user_data["kind"])
820   end
821
822
823   def check_readable_users_index expect_present, expect_missing
824     response_uuids = json_response["items"].map { |u| u["uuid"] }
825     expect_present.each do |user_key|
826       assert_includes(response_uuids, users(user_key).uuid,
827                       "#{user_key} missing from index")
828     end
829     expect_missing.each do |user_key|
830       refute_includes(response_uuids, users(user_key).uuid,
831                       "#{user_key} included in index")
832     end
833   end
834
835   def check_inactive_user_findable(params={})
836     inactive_user = users(:inactive)
837     get(:index, params.merge(filters: [["email", "=", inactive_user.email]]))
838     assert_response :success
839     user_list = json_response["items"]
840     assert_equal(1, user_list.andand.count)
841     # This test needs to check a column non-admins have no access to,
842     # to ensure that admins see all user information.
843     assert_equal(inactive_user.identity_url, user_list.first["identity_url"],
844                  "admin's filtered index did not return inactive user")
845   end
846
847   def verify_num_links (original_links, expected_additional_links)
848     links_now = Link.all
849     assert_equal expected_additional_links, Link.all.size-original_links.size,
850         "Expected #{expected_additional_links.inspect} more links"
851   end
852
853   def find_obj_in_resp (response_items, object_type, head_kind=nil)
854     return_obj = nil
855     response_items
856     response_items.each { |x|
857       if !x
858         next
859       end
860
861       if object_type == 'User'
862         if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
863           return_obj = x
864           break
865         end
866       else  # looking for a link
867         if x['head_uuid'] and ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
868           return_obj = x
869           break
870         end
871       end
872     }
873     return return_obj
874   end
875 end