Raise error if both uuid and user.email are omitted in input parameters
[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
77     response_items = JSON.parse(@response.body)['items']
78     created = response_items['user']
79
80     assert_equal 'in_create_test_first_name', created['first_name']
81     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
82     assert_equal 'this_is_agreeable', created['uuid']
83     assert_not_nil created['email'], 'expected non-nil email'
84     assert_nil created['identity_url'], 'expected no identity_url' 
85
86     # since no such vm exists, expect only three new links: 
87     # oid_login_perm, repo link and link add user to 'All users' group
88     verify_num_links @all_links_at_start, 3
89
90     verify_link response_items, 'oid_login_perm', true, 'permission', 'can_login',
91         created['uuid'], created['email'], 'arvados#user', false, 'User'
92
93     verify_link response_items, 'repo_perm', true, 'permission', 'can_write',
94         repo_name, created['uuid'], 'arvados#repository', true, 'Repository'
95
96     verify_link response_items, 'group_perm', true, 'permission', 'can_read',
97         'All users', created['uuid'], 'arvados#group', true, 'Group'
98
99     verify_link response_items, 'vm_login_perm', false, 'permission', 'can_login',
100         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
101   end
102
103   test "setup user with bogus uuid and expect error" do
104     authorize_with :admin
105
106     post :setup, {
107       uuid: 'bogus_uuid',
108       repo_name: 'test_repo',
109       vm_uuid: @vm_uuid,
110       openid_prefix: 'https://www.google.com/accounts/o8/id'
111     }
112     response_body = JSON.parse(@response.body)
113     response_errors = response_body['errors']
114     assert_not_nil response_errors, 'Expected error in response'
115     assert (response_errors.first.include? 'Path not found'), 'Expected 404'
116   end
117
118   test "setup user with bogus uuid in user and expect error" do
119     authorize_with :admin
120
121     post :setup, {
122       user: {uuid: 'bogus_uuid'},
123       repo_name: 'test_repo',
124       vm_uuid: @vm_uuid,
125       openid_prefix: 'https://www.google.com/accounts/o8/id'
126     }
127     response_body = JSON.parse(@response.body)
128     response_errors = response_body['errors']
129     assert_not_nil response_errors, 'Expected error in response'
130     assert (response_errors.first.include? 'RuntimeError: No email found'),
131       'Expected RuntimeError'
132   end
133
134   test "setup user with no uuid and user, expect error" do
135     authorize_with :admin
136
137     post :setup, {
138       #uuid: 'not_an_existing_uuid_and_not_email_format',
139       repo_name: 'test_repo',
140       vm_uuid: @vm_uuid,
141       openid_prefix: 'https://www.google.com/accounts/o8/id'
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? 'Required uuid or email'),
147         'Expected ArgumentError'
148   end
149
150   test "setup user with no uuid and email, expect error" do
151     authorize_with :admin
152
153     post :setup, {
154       user: {},
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? '<RuntimeError: No email found'),
163         'Expected RuntimeError'
164   end
165
166   test "invoke setup with existing uuid, vm and repo and verify links" do
167     authorize_with :inactive
168     get :current
169     assert_response :success
170     inactive_user = JSON.parse(@response.body)
171     
172     authorize_with :admin
173
174     post :setup, {
175       uuid: inactive_user['uuid'],
176       repo_name: 'test_repo',
177       vm_uuid: @vm_uuid,
178       openid_prefix: 'https://www.google.com/accounts/o8/id'
179     }
180
181     assert_response :success
182
183     response_items = JSON.parse(@response.body)['items']
184     resp_obj = response_items['user']
185
186     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
187     assert_equal inactive_user['uuid'], resp_obj['uuid']
188     assert_equal inactive_user['email'], resp_obj['email'], 
189         'expecting inactive user email'
190
191     # expect repo and vm links
192     verify_link response_items, 'repo_perm', true, 'permission', 'can_write',
193         'test_repo', resp_obj['uuid'], 'arvados#repository', true, 'Repository'
194
195     verify_link response_items, 'vm_login_perm', true, 'permission', 'can_login',
196         @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
197   end
198
199   test "invoke setup with existing uuid in user, verify response" do
200     authorize_with :inactive
201     get :current
202     assert_response :success
203     inactive_user = JSON.parse(@response.body)
204     
205     authorize_with :admin
206
207     post :setup, {
208       user: {uuid: inactive_user['uuid']},
209       openid_prefix: 'https://www.google.com/accounts/o8/id'
210     }
211
212     assert_response :success
213
214     response_items = JSON.parse(@response.body)['items']
215     resp_obj = response_items['user']
216
217     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
218     assert_equal inactive_user['uuid'], resp_obj['uuid']
219     assert_equal inactive_user['email'], resp_obj['email'], 
220         'expecting inactive user email'
221   end
222
223   test "invoke setup with existing uuid but different email, expect original email" do
224     authorize_with :inactive
225     get :current
226     assert_response :success
227     inactive_user = JSON.parse(@response.body)
228     
229     authorize_with :admin
230
231     post :setup, {
232       uuid: inactive_user['uuid'],
233       user: {email: 'junk_email'},
234       openid_prefix: 'https://www.google.com/accounts/o8/id'
235     }
236
237     assert_response :success
238
239     response_items = JSON.parse(@response.body)['items']
240     resp_obj = response_items['user']
241
242     assert_not_nil resp_obj['uuid'], 'expected uuid for the new user'
243     assert_equal inactive_user['uuid'], resp_obj['uuid']
244     assert_equal inactive_user['email'], resp_obj['email'], 
245         'expecting inactive user email'
246   end
247
248   test "setup user with valid email and repo as input" do
249     authorize_with :admin
250
251     post :setup, {
252       repo_name: 'test_repo',
253       user: {email: 'abc@xyz.com'},
254       openid_prefix: 'https://www.google.com/accounts/o8/id'
255     }
256
257     assert_response :success
258     response_object = JSON.parse(@response.body)['items']['user']
259     assert_not_nil response_object['uuid'], 'expected uuid for the new user'
260     assert_equal response_object['email'], 'abc@xyz.com', 'expected given email'
261
262     # three extra links; login link, group link and repo link
263     verify_num_links @all_links_at_start, 3
264   end
265
266   test "setup user with fake vm and expect error" do
267     authorize_with :admin
268
269     post :setup, {
270       repo_name: 'test_repo',
271       vm_uuid: 'no_such_vm',
272       user: {email: 'abc@xyz.com'},
273       openid_prefix: 'https://www.google.com/accounts/o8/id'
274     }
275
276     response_body = JSON.parse(@response.body)
277     response_errors = response_body['errors']
278     assert_not_nil response_errors, 'Expected error in response'
279     assert (response_errors.first.include? "No vm found for no_such_vm"), 
280           'Expected RuntimeError: No vm found for no_such_vm'
281   end
282
283   test "setup user with valid email, repo and real vm as input" do
284     authorize_with :admin
285
286     post :setup, {
287       repo_name: 'test_repo',
288       openid_prefix: 'https://www.google.com/accounts/o8/id',
289       vm_uuid: @vm_uuid,
290       user: {email: 'abc@xyz.com'}
291     }
292
293     assert_response :success
294     response_object = JSON.parse(@response.body)['items']['user']
295     assert_not_nil response_object['uuid'], 'expected uuid for the new user'
296     assert_equal response_object['email'], 'abc@xyz.com', 'expected given email'
297
298     # three extra links; login link, group link and repo link
299     verify_num_links @all_links_at_start, 4
300   end
301
302   test "setup user with valid email, no vm and repo as input" do
303     authorize_with :admin
304
305     post :setup, {
306       user: {email: 'abc@xyz.com'},
307       openid_prefix: 'https://www.google.com/accounts/o8/id'
308     }
309
310     assert_response :success    
311     response_object = JSON.parse(@response.body)['items']['user']
312     assert_not_nil response_object['uuid'], 'expected uuid for new user'
313     assert_equal response_object['email'], 'abc@xyz.com', 'expected given email'
314
315     # two extra links; login link and group link
316     verify_num_links @all_links_at_start, 2
317   end
318
319   test "setup user with email, first name, repo name and vm uuid" do
320     authorize_with :admin
321
322     post :setup, {
323       openid_prefix: 'https://www.google.com/accounts/o8/id',
324       repo_name: 'test_repo',
325       vm_uuid: @vm_uuid,
326       user: {
327         first_name: 'test_first_name',
328         email: 'abc@xyz.com'
329       }
330     }
331
332     assert_response :success
333     response_object = JSON.parse(@response.body)['items']['user']
334     assert_not_nil response_object['uuid'], 'expected uuid for new user'
335     assert_equal response_object['email'], 'abc@xyz.com', 'expected given email'
336     assert_equal 'test_first_name', response_object['first_name'], 
337         'expecting first name'
338
339     # four extra links; login link, group link, repo link and vm link
340     verify_num_links @all_links_at_start, 4
341   end
342
343   test "setup user twice with email and check two different objects created" do
344     authorize_with :admin
345
346     post :setup, {
347       openid_prefix: 'https://www.google.com/accounts/o8/id',
348       repo_name: 'test_repo',
349       user: {
350         email: 'abc@xyz.com'
351       }
352     }
353
354     assert_response :success
355     response_object = JSON.parse(@response.body)['items']['user']
356     assert_not_nil response_object['uuid'], 'expected uuid for new user'
357     assert_equal response_object['email'], 'abc@xyz.com', 'expected given email'
358     verify_num_links @all_links_at_start, 3   # openid, group, and repo. no vm
359
360     # create again
361     post :setup, {
362       user: {email: 'abc@xyz.com'},
363       openid_prefix: 'https://www.google.com/accounts/o8/id'
364     }
365
366     assert_response :success
367     response_object2 = JSON.parse(@response.body)['items']['user']
368     assert_not_equal response_object['uuid'], response_object2['uuid'], 
369         'expected same uuid as first create operation'
370     assert_equal response_object['email'], 'abc@xyz.com', 'expected given email'
371
372     # extra login link only
373     verify_num_links @all_links_at_start, 4
374   end
375
376   test "setup user with openid prefix" do
377     authorize_with :admin
378
379     post :setup, {
380       repo_name: 'test_repo',
381       openid_prefix: 'http://www.xyz.com/account',
382       user: {
383         first_name: "in_create_test_first_name",
384         last_name: "test_last_name",
385         email: "test@abc.com"
386       }
387     }
388
389     assert_response :success
390
391     response_items = JSON.parse(@response.body)['items']
392     created = response_items['user']
393
394     assert_equal 'in_create_test_first_name', created['first_name']
395     assert_not_nil created['uuid'], 'expected uuid for new user'
396     assert_not_nil created['email'], 'expected non-nil email'
397     assert_nil created['identity_url'], 'expected no identity_url' 
398
399     # verify links
400     # 3 new links: oid_login_perm, repo, and 'All users' group.
401     verify_num_links @all_links_at_start, 3
402
403     verify_link response_items, 'oid_login_perm', true, 'permission', 'can_login',
404         created['uuid'], created['email'], 'arvados#user', false, 'User'
405
406     verify_link response_items, 'repo_perm', true, 'permission', 'can_write',
407         'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
408
409     verify_link response_items, 'group_perm', true, 'permission', 'can_read',
410         'All users', created['uuid'], 'arvados#group', true, 'Group'
411
412     verify_link response_items, 'vm_login_perm', false, 'permission', 'can_login',
413         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
414   end
415
416   test "invoke setup with no openid prefix, expect error" do
417     authorize_with :admin
418
419     post :setup, {
420       repo_name: 'test_repo',
421       user: {
422         first_name: "in_create_test_first_name",
423         last_name: "test_last_name",
424         email: "test@abc.com"
425       }
426     }
427
428     response_body = JSON.parse(@response.body)
429     response_errors = response_body['errors']
430     assert_not_nil response_errors, 'Expected error in response'
431     assert (response_errors.first.include? 'openid_prefix parameter is missing'),
432         'Expected ArgumentError'
433   end
434
435   test "setup user with user, vm and repo and verify links" do
436     authorize_with :admin
437
438     post :setup, {
439       user: {
440         first_name: "in_create_test_first_name",
441         last_name: "test_last_name",
442         email: "test@abc.com"
443       },
444       vm_uuid: @vm_uuid,
445       repo_name: 'test_repo',
446       openid_prefix: 'https://www.google.com/accounts/o8/id'
447     }
448
449     assert_response :success
450
451     response_items = JSON.parse(@response.body)['items']
452     created = response_items['user']
453
454     assert_equal 'in_create_test_first_name', created['first_name']
455     assert_not_nil created['uuid'], 'expected uuid for new user'
456     assert_not_nil created['email'], 'expected non-nil email'
457     assert_nil created['identity_url'], 'expected no identity_url' 
458
459     # expect 4 new links: oid_login_perm, repo, vm and 'All users' group link
460     verify_num_links @all_links_at_start, 4
461
462     verify_link response_items, 'oid_login_perm', true, 'permission', 'can_login',
463         created['uuid'], created['email'], 'arvados#user', false, 'User'
464
465     verify_link response_items, 'repo_perm', true, 'permission', 'can_write',
466         'test_repo', created['uuid'], 'arvados#repository', true, 'Repository'
467
468     verify_link response_items, 'group_perm', true, 'permission', 'can_read',
469         'All users', created['uuid'], 'arvados#group', true, 'Group'
470
471     verify_link response_items, 'vm_login_perm', true, 'permission', 'can_login', 
472         @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
473   end
474
475   test "create user as non admin user and expect error" do
476     authorize_with :active
477
478     post :create, {
479       user: {email: 'abc@xyz.com'}
480     }
481
482     response_body = JSON.parse(@response.body)
483     response_errors = response_body['errors']
484     assert_not_nil response_errors, 'Expected error in response'
485     assert (response_errors.first.include? 'PermissionDenied'), 
486           'Expected PermissionDeniedError'
487   end
488
489   test "setup user as non admin user and expect error" do
490     authorize_with :active
491
492     post :setup, {
493       openid_prefix: 'https://www.google.com/accounts/o8/id',
494       user: {email: 'abc@xyz.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   def verify_num_links (original_links, expected_additional_links)
505     links_now = Link.all
506     assert_equal original_links.size+expected_additional_links, Link.all.size,
507         "Expected #{expected_additional_links.inspect} more links"
508   end
509
510   def verify_link(response_items, link_object_name, expect_link, link_class,
511         link_name, head_uuid, tail_uuid, head_kind, fetch_object, class_name)
512     link = response_items[link_object_name]
513
514     if !expect_link 
515       assert_nil link
516       return
517     end
518
519     assert_not_nil link
520
521     if fetch_object
522       object = Object.const_get(class_name).where(name: head_uuid)
523       assert [] != object, "expected #{class_name} with name #{head_uuid}"
524       head_uuid = object.first[:uuid]
525     end
526
527     assert_equal link['link_class'], link_class,
528         "did not find expected link_class for #{link_object_name}"
529  
530     assert_equal link['name'], link_name,
531         "did not find expected link_name for #{link_object_name}"
532  
533     assert_equal link['tail_uuid'], tail_uuid,
534         "did not find expected tail_uuid for #{link_object_name}"
535  
536     assert_equal link['head_kind'], head_kind,
537         "did not find expected head_kind for #{link_object_name}"
538  
539     assert_equal link['head_uuid'], head_uuid,
540         "did not find expected head_uuid for #{link_object_name}"
541   end
542
543 end