Merge branch '2288-smoke-test'
[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
5   setup do
6     @all_links_at_start = Link.all
7     @vm_uuid = virtual_machines(:testvm).uuid
8   end
9
10   test "activate a user after signing UA" do
11     authorize_with :inactive_but_signed_user_agreement
12     get :current
13     assert_response :success
14     me = JSON.parse(@response.body)
15     post :activate, uuid: me['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     authorize_with :inactive
24     get :current
25     assert_response :success
26     me = JSON.parse(@response.body)
27     post :activate, uuid: me['uuid']
28     assert_response 403
29     get :current
30     assert_response :success
31     me = JSON.parse(@response.body)
32     assert_equal false, me['is_active']
33   end
34
35   test "activate an already-active user" do
36     authorize_with :active
37     get :current
38     assert_response :success
39     me = JSON.parse(@response.body)
40     post :activate, uuid: me['uuid']
41     assert_response :success
42     me = JSON.parse(@response.body)
43     assert_equal true, me['is_active']
44   end
45
46   test "create new user with user as input" do
47     authorize_with :admin
48     post :create, user: {
49       first_name: "test_first_name",
50       last_name: "test_last_name",
51       email: "foo@example.com"
52     }
53     assert_response :success
54     created = JSON.parse(@response.body)
55     assert_equal 'test_first_name', created['first_name']
56     assert_not_nil created['uuid'], 'expected uuid for the newly created user'
57     assert_not_nil created['email'], 'expected non-nil email'
58     assert_nil created['identity_url'], 'expected no identity_url'
59   end
60
61   test "create user with user, vm and repo as input" do
62     authorize_with :admin
63     repo_name = 'test_repo'
64
65     post :setup, {
66       repo_name: repo_name,
67       openid_prefix: 'https://www.google.com/accounts/o8/id',
68       user: {
69         uuid: "this_is_agreeable",        
70         first_name: "in_create_test_first_name",
71         last_name: "test_last_name",
72         email: "foo@example.com"
73       }
74     }
75     assert_response :success
76     response_items = JSON.parse(@response.body)['items']
77
78     created = find_obj_in_resp response_items, 'User', nil
79     assert_equal 'in_create_test_first_name', created['first_name']
80     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
81     assert_equal 'this_is_agreeable', created['uuid']
82     assert_not_nil created['email'], 'expected non-nil email'
83     assert_nil created['identity_url'], 'expected no identity_url' 
84
85     # arvados#user, repo link and link add user to 'All users' group
86     verify_num_links @all_links_at_start, 3
87
88     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
89         created['uuid'], created['email'], 'arvados#user', false, 'User'
90
91     verify_link response_items, 'arvados#repository', true, 'permission', 'can_write',
92         repo_name, created['uuid'], 'arvados#repository', true, 'Repository'
93
94     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
95         'All users', created['uuid'], 'arvados#group', true, 'Group'
96
97     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
98         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
99
100     # invoke setup again with the same data
101     post :setup, {
102       repo_name: repo_name,
103       vm_uuid: @vm_uuid,
104       openid_prefix: 'https://www.google.com/accounts/o8/id',
105       user: {
106         uuid: "this_is_agreeable",
107         first_name: "in_create_test_first_name",
108         last_name: "test_last_name",
109         email: "foo@example.com"
110       }
111     }
112
113     response_items = JSON.parse(@response.body)['items']
114
115     created = find_obj_in_resp response_items, 'User', nil
116     assert_equal 'in_create_test_first_name', created['first_name']
117     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
118     assert_equal 'this_is_agreeable', created['uuid']
119     assert_not_nil created['email'], 'expected non-nil email'
120     assert_nil created['identity_url'], 'expected no identity_url'
121
122     # arvados#user, repo link and link add user to 'All users' group
123     verify_num_links @all_links_at_start, 4
124
125     verify_link response_items, 'arvados#repository', true, 'permission', 'can_write',
126         repo_name, created['uuid'], 'arvados#repository', true, 'Repository'
127
128     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
129         'All users', created['uuid'], 'arvados#group', true, 'Group'
130
131     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
132         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
133   end
134
135   test "setup user with bogus uuid and expect error" do
136     authorize_with :admin
137
138     post :setup, {
139       uuid: 'bogus_uuid',
140       repo_name: 'test_repo',
141       vm_uuid: @vm_uuid
142     }
143     response_body = JSON.parse(@response.body)
144     response_errors = response_body['errors']
145     assert_not_nil response_errors, 'Expected error in response'
146     assert (response_errors.first.include? 'Path not found'), 'Expected 404'
147   end
148
149   test "setup user with bogus uuid in user and expect error" do
150     authorize_with :admin
151
152     post :setup, {
153       user: {uuid: 'bogus_uuid'},
154       repo_name: 'test_repo',
155       vm_uuid: @vm_uuid,
156       openid_prefix: 'https://www.google.com/accounts/o8/id'
157     }
158     response_body = JSON.parse(@response.body)
159     response_errors = response_body['errors']
160     assert_not_nil response_errors, 'Expected error in response'
161     assert (response_errors.first.include? 'ArgumentError: Require user email'),
162       'Expected RuntimeError'
163   end
164
165   test "setup user with no uuid and user, expect error" do
166     authorize_with :admin
167
168     post :setup, {
169       repo_name: 'test_repo',
170       vm_uuid: @vm_uuid,
171       openid_prefix: 'https://www.google.com/accounts/o8/id'
172     }
173     response_body = JSON.parse(@response.body)
174     response_errors = response_body['errors']
175     assert_not_nil response_errors, 'Expected error in response'
176     assert (response_errors.first.include? 'Required uuid or user'),
177         'Expected ArgumentError'
178   end
179
180   test "setup user with no uuid and email, expect error" do
181     authorize_with :admin
182
183     post :setup, {
184       user: {},
185       repo_name: 'test_repo',
186       vm_uuid: @vm_uuid,
187       openid_prefix: 'https://www.google.com/accounts/o8/id'
188     }
189     response_body = JSON.parse(@response.body)
190     response_errors = response_body['errors']
191     assert_not_nil response_errors, 'Expected error in response'
192     assert (response_errors.first.include? '<ArgumentError: Require user email'),
193         'Expected ArgumentError'
194   end
195
196   test "invoke setup with existing uuid, vm and repo and verify links" do
197     authorize_with :inactive
198     get :current
199     assert_response :success
200     inactive_user = JSON.parse(@response.body)
201     
202     authorize_with :admin
203
204     post :setup, {
205       uuid: inactive_user['uuid'],
206       repo_name: 'test_repo',
207       vm_uuid: @vm_uuid
208     }
209
210     assert_response :success
211
212     response_items = JSON.parse(@response.body)['items']
213     resp_obj = find_obj_in_resp response_items, 'User', nil
214
215     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
216     assert_equal inactive_user['uuid'], resp_obj['uuid']
217     assert_equal inactive_user['email'], resp_obj['email'], 
218         'expecting inactive user email'
219
220     # expect repo and vm links
221     verify_link response_items, 'arvados#repository', true, 'permission', 'can_write',
222         'test_repo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
223
224     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
225         @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
226   end
227
228   test "invoke setup with existing uuid in user, verify response" do
229     authorize_with :inactive
230     get :current
231     assert_response :success
232     inactive_user = JSON.parse(@response.body)
233     
234     authorize_with :admin
235
236     post :setup, {
237       user: {uuid: inactive_user['uuid']},
238       openid_prefix: 'https://www.google.com/accounts/o8/id'
239     }
240
241     assert_response :success
242
243     response_items = JSON.parse(@response.body)['items']
244     resp_obj = find_obj_in_resp response_items, 'User', nil
245
246     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
247     assert_equal inactive_user['uuid'], resp_obj['uuid']
248     assert_equal inactive_user['email'], resp_obj['email'], 
249         'expecting inactive user email'
250   end
251
252   test "invoke setup with existing uuid but different email, expect original email" do
253     authorize_with :inactive
254     get :current
255     assert_response :success
256     inactive_user = JSON.parse(@response.body)
257     
258     authorize_with :admin
259
260     post :setup, {
261       uuid: inactive_user['uuid'],
262       user: {email: 'junk_email'}
263     }
264
265     assert_response :success
266
267     response_items = JSON.parse(@response.body)['items']
268     resp_obj = find_obj_in_resp response_items, 'User', nil
269
270     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
271     assert_equal inactive_user['uuid'], resp_obj['uuid']
272     assert_equal inactive_user['email'], resp_obj['email'], 
273         'expecting inactive user email'
274   end
275
276   test "setup user with valid email and repo as input" do
277     authorize_with :admin
278
279     post :setup, {
280       repo_name: 'test_repo',
281       user: {email: 'foo@example.com'},
282       openid_prefix: 'https://www.google.com/accounts/o8/id'
283     }
284
285     assert_response :success
286     response_items = JSON.parse(@response.body)['items']
287     response_object = find_obj_in_resp response_items, 'User', nil
288     assert_not_nil response_object['uuid'], 'expected uuid for the new user'
289     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
290
291     # three extra links; login link, group link and repo link
292     verify_num_links @all_links_at_start, 3
293   end
294
295   test "setup user with fake vm and expect error" do
296     authorize_with :admin
297
298     post :setup, {
299       repo_name: 'test_repo',
300       vm_uuid: 'no_such_vm',
301       user: {email: 'foo@example.com'},
302       openid_prefix: 'https://www.google.com/accounts/o8/id'
303     }
304
305     response_body = JSON.parse(@response.body)
306     response_errors = response_body['errors']
307     assert_not_nil response_errors, 'Expected error in response'
308     assert (response_errors.first.include? "No vm found for no_such_vm"), 
309           'Expected RuntimeError: No vm found for no_such_vm'
310   end
311
312   test "setup user with valid email, repo and real vm as input" do
313     authorize_with :admin
314
315     post :setup, {
316       repo_name: 'test_repo',
317       openid_prefix: 'https://www.google.com/accounts/o8/id',
318       vm_uuid: @vm_uuid,
319       user: {email: 'foo@example.com'}
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     # three extra links; login link, group link and repo link
329     verify_num_links @all_links_at_start, 4
330   end
331
332   test "setup user with valid email, no vm and repo as input" do
333     authorize_with :admin
334
335     post :setup, {
336       user: {email: 'foo@example.com'},
337       openid_prefix: 'https://www.google.com/accounts/o8/id'
338     }
339
340     assert_response :success    
341     response_items = JSON.parse(@response.body)['items']
342     response_object = find_obj_in_resp response_items, 'User', nil
343     assert_not_nil response_object['uuid'], 'expected uuid for new user'
344     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
345
346     # two extra links; login link and group link
347     verify_num_links @all_links_at_start, 2
348   end
349
350   test "setup user with email, first name, repo name and vm uuid" do
351     authorize_with :admin
352
353     post :setup, {
354       openid_prefix: 'https://www.google.com/accounts/o8/id',
355       repo_name: 'test_repo',
356       vm_uuid: @vm_uuid,
357       user: {
358         first_name: 'test_first_name',
359         email: 'foo@example.com'
360       }
361     }
362
363     assert_response :success
364     response_items = JSON.parse(@response.body)['items']
365     response_object = find_obj_in_resp response_items, 'User', nil
366     assert_not_nil response_object['uuid'], 'expected uuid for new user'
367     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
368     assert_equal 'test_first_name', response_object['first_name'], 
369         'expecting first name'
370
371     # four extra links; login link, group link, repo link and vm link
372     verify_num_links @all_links_at_start, 4
373   end
374
375   test "setup user twice with email and check two different objects created" do
376     authorize_with :admin
377
378     post :setup, {
379       openid_prefix: 'https://www.google.com/accounts/o8/id',
380       repo_name: 'test_repo',
381       user: {
382         email: 'foo@example.com'
383       }
384     }
385
386     assert_response :success
387     response_items = JSON.parse(@response.body)['items']
388     response_object = find_obj_in_resp response_items, 'User', nil
389     assert_not_nil response_object['uuid'], 'expected uuid for new user'
390     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
391     verify_num_links @all_links_at_start, 3   # openid, group, and repo. no vm
392
393     # create again
394     post :setup, {
395       user: {email: 'foo@example.com'},
396       openid_prefix: 'https://www.google.com/accounts/o8/id'
397     }
398
399     assert_response :success
400     response_items = JSON.parse(@response.body)['items']
401     response_object2 = find_obj_in_resp response_items, 'User', nil
402     assert_not_equal response_object['uuid'], response_object2['uuid'], 
403         'expected same uuid as first create operation'
404     assert_equal response_object['email'], 'foo@example.com', 'expected given email'
405
406     # extra login link only
407     verify_num_links @all_links_at_start, 4
408   end
409
410   test "setup user with openid prefix" do
411     authorize_with :admin
412
413     post :setup, {
414       repo_name: 'test_repo',
415       openid_prefix: 'http://www.example.com/account',
416       user: {
417         first_name: "in_create_test_first_name",
418         last_name: "test_last_name",
419         email: "foo@example.com"
420       }
421     }
422
423     assert_response :success
424
425     response_items = JSON.parse(@response.body)['items']
426     created = find_obj_in_resp response_items, 'User', nil
427
428     assert_equal 'in_create_test_first_name', created['first_name']
429     assert_not_nil created['uuid'], 'expected uuid for new user'
430     assert_not_nil created['email'], 'expected non-nil email'
431     assert_nil created['identity_url'], 'expected no identity_url' 
432
433     # verify links
434     # 3 new links: arvados#user, repo, and 'All users' group.
435     verify_num_links @all_links_at_start, 3
436
437     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
438         created['uuid'], created['email'], 'arvados#user', false, 'User'
439
440     verify_link response_items, 'arvados#repository', true, 'permission', 'can_write',
441         'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
442
443     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
444         'All users', created['uuid'], 'arvados#group', true, 'Group'
445
446     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
447         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
448   end
449
450   test "invoke setup with no openid prefix, expect error" do
451     authorize_with :admin
452
453     post :setup, {
454       repo_name: 'test_repo',
455       user: {
456         first_name: "in_create_test_first_name",
457         last_name: "test_last_name",
458         email: "foo@example.com"
459       }
460     }
461
462     response_body = JSON.parse(@response.body)
463     response_errors = response_body['errors']
464     assert_not_nil response_errors, 'Expected error in response'
465     assert (response_errors.first.include? 'openid_prefix parameter is missing'),
466         'Expected ArgumentError'
467   end
468
469   test "setup user with user, vm and repo and verify links" do
470     authorize_with :admin
471
472     post :setup, {
473       user: {
474         first_name: "in_create_test_first_name",
475         last_name: "test_last_name",
476         email: "foo@example.com"
477       },
478       vm_uuid: @vm_uuid,
479       repo_name: 'test_repo',
480       openid_prefix: 'https://www.google.com/accounts/o8/id'
481     }
482
483     assert_response :success
484
485     response_items = JSON.parse(@response.body)['items']
486     created = find_obj_in_resp response_items, 'User', nil
487
488     assert_equal 'in_create_test_first_name', created['first_name']
489     assert_not_nil created['uuid'], 'expected uuid for new user'
490     assert_not_nil created['email'], 'expected non-nil email'
491     assert_nil created['identity_url'], 'expected no identity_url' 
492
493     # expect 4 new links: arvados#user, repo, vm and 'All users' group link
494     verify_num_links @all_links_at_start, 4
495
496     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
497         created['uuid'], created['email'], 'arvados#user', false, 'User'
498
499     verify_link response_items, 'arvados#repository', true, 'permission', 'can_write',
500         'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
501
502     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
503         'All users', created['uuid'], 'arvados#group', true, 'Group'
504
505     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login', 
506         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
507   end
508
509   test "create user as non admin user and expect error" do
510     authorize_with :active
511
512     post :create, {
513       user: {email: 'foo@example.com'}
514     }
515
516     response_body = JSON.parse(@response.body)
517     response_errors = response_body['errors']
518     assert_not_nil response_errors, 'Expected error in response'
519     assert (response_errors.first.include? 'PermissionDenied'), 
520           'Expected PermissionDeniedError'
521   end
522
523   test "setup user as non admin user and expect error" do
524     authorize_with :active
525
526     post :setup, {
527       openid_prefix: 'https://www.google.com/accounts/o8/id',
528       user: {email: 'foo@example.com'}
529     }
530
531     response_body = JSON.parse(@response.body)
532     response_errors = response_body['errors']
533     assert_not_nil response_errors, 'Expected error in response'
534     assert (response_errors.first.include? 'PermissionDenied'), 
535           'Expected PermissionDeniedError'
536   end
537
538   test "setup user in multiple steps and verify response" do
539     authorize_with :admin
540
541     post :setup, {
542       openid_prefix: 'http://www.example.com/account',
543       user: {
544         email: "foo@example.com"
545       }
546     }
547
548     assert_response :success
549
550     response_items = JSON.parse(@response.body)['items']
551     created = find_obj_in_resp response_items, 'User', nil
552
553     assert_not_nil created['uuid'], 'expected uuid for new user'
554     assert_not_nil created['email'], 'expected non-nil email'
555     assert_equal created['email'], 'foo@example.com', 'expected input email'
556
557     # verify links; 2 new links: arvados#user, and 'All users' group.
558     verify_num_links @all_links_at_start, 2
559
560     verify_link response_items, 'arvados#user', true, 'permission', 'can_login',
561         created['uuid'], created['email'], 'arvados#user', false, 'User'
562
563     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
564         'All users', created['uuid'], 'arvados#group', true, 'Group'
565
566     verify_link response_items, 'arvados#repository', false, 'permission', 'can_write',
567         'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
568
569     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
570         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
571
572    # invoke setup with a repository
573     post :setup, {
574       openid_prefix: 'http://www.example.com/account',
575       repo_name: 'new_repo',
576       uuid: created['uuid']
577     }
578
579     assert_response :success
580
581     response_items = JSON.parse(@response.body)['items']
582     created = find_obj_in_resp response_items, 'User', nil
583
584     assert_equal 'foo@example.com', created['email'], 'expected input email'
585
586      # verify links
587     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
588         'All users', created['uuid'], 'arvados#group', true, 'Group'
589
590     verify_link response_items, 'arvados#repository', true, 'permission', 'can_write',
591         'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
592
593     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
594         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
595
596     # invoke setup with a vm_uuid
597     post :setup, {
598       vm_uuid: @vm_uuid,
599       openid_prefix: 'http://www.example.com/account',
600       user: {
601         email: 'junk_email'
602       },
603       uuid: created['uuid']
604     }
605
606     assert_response :success
607
608     response_items = JSON.parse(@response.body)['items']
609     created = find_obj_in_resp response_items, 'User', nil
610
611     assert_equal created['email'], 'foo@example.com', 'expected original email'
612
613     # verify links
614     verify_link response_items, 'arvados#group', true, 'permission', 'can_read',
615         'All users', created['uuid'], 'arvados#group', true, 'Group'
616
617     # since no repo name in input, we won't get any; even though user has one
618     verify_link response_items, 'arvados#repository', false, 'permission', 'can_write',
619         'new_repo', created['uuid'], 'arvados#repository', true, 'Repository'
620
621     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
622         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
623   end
624
625   def verify_num_links (original_links, expected_additional_links)
626     links_now = Link.all
627     assert_equal original_links.size+expected_additional_links, Link.all.size,
628         "Expected #{expected_additional_links.inspect} more links"
629   end
630
631   def find_obj_in_resp (response_items, object_type, head_kind=nil)
632     return_obj = nil
633     response_items.each { |x|
634       if !x
635         next
636       end
637
638       if object_type == 'User'
639         if !x['head_kind']
640           return_obj = x
641           break
642         end
643       else  # looking for a link
644         if x['head_kind'] == head_kind
645           return_obj = x
646           break
647         end
648       end
649     }
650     return return_obj
651   end
652
653   def verify_link(response_items, link_object_name, expect_link, link_class,
654         link_name, head_uuid, tail_uuid, head_kind, fetch_object, class_name)
655
656     link = find_obj_in_resp response_items, 'Link', link_object_name
657
658     if !expect_link 
659       assert_nil link, "Expected no link for #{link_object_name}"
660       return
661     end
662
663     assert_not_nil link, "Expected link for #{link_object_name}"
664
665     if fetch_object
666       object = Object.const_get(class_name).where(name: head_uuid)
667       assert [] != object, "expected #{class_name} with name #{head_uuid}"
668       head_uuid = object.first[:uuid]
669     end
670     assert_equal link['link_class'], link_class,
671         "did not find expected link_class for #{link_object_name}"
672  
673     assert_equal link['name'], link_name,
674         "did not find expected link_name for #{link_object_name}"
675  
676     assert_equal link['tail_uuid'], tail_uuid,
677         "did not find expected tail_uuid for #{link_object_name}"
678  
679     assert_equal link['head_kind'], head_kind,
680         "did not find expected head_kind for #{link_object_name}"
681  
682     assert_equal link['head_uuid'], head_uuid,
683         "did not find expected head_uuid for #{link_object_name}"
684   end
685
686 end