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