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