Switch to using auth helpers instead of messing with Thread.current in the user tests.
[arvados.git] / services / api / test / unit / user_test.rb
1 require 'test_helper'
2
3 class UserTest < ActiveSupport::TestCase
4   include CurrentApiClient
5
6   test "check non-admin active user properties" do
7     @active_user = users(:active)     # get the active user
8     assert !@active_user.is_admin, 'is_admin should not be set for a non-admin user'
9     assert @active_user.is_active, 'user should be active'
10     assert @active_user.is_invited, 'is_invited should be set'
11     assert_not_nil @active_user.prefs, "user's preferences should be non-null, but may be size zero"
12     assert (@active_user.can? :read=>"#{@active_user.uuid}"), "user should be able to read own object"
13     assert (@active_user.can? :write=>"#{@active_user.uuid}"), "user should be able to write own object"
14     assert (@active_user.can? :manage=>"#{@active_user.uuid}"), "user should be able to manage own object"
15
16     assert @active_user.groups_i_can(:read).size > 0, "active user should be able read at least one group"
17
18     # non-admin user cannot manage or write other user objects
19     @uninvited_user = users(:inactive_uninvited)     # get the uninvited user
20     assert !(@active_user.can? :read=>"#{@uninvited_user.uuid}")
21     assert !(@active_user.can? :write=>"#{@uninvited_user.uuid}")
22     assert !(@active_user.can? :manage=>"#{@uninvited_user.uuid}")
23   end
24
25   test "check admin user properties" do
26     @admin_user = users(:admin)     # get the admin user
27     assert @admin_user.is_admin, 'is_admin should be set for admin user'
28     assert @admin_user.is_active, 'admin user cannot be inactive'
29     assert @admin_user.is_invited, 'is_invited should be set'
30     assert_not_nil @admin_user.uuid.size, "user's uuid should be non-null"
31     assert_not_nil @admin_user.prefs, "user's preferences should be non-null, but may be size zero"
32     assert @admin_user.identity_url.size > 0, "user's identity url is expected"
33     assert @admin_user.can? :read=>"#{@admin_user.uuid}"
34     assert @admin_user.can? :write=>"#{@admin_user.uuid}"
35     assert @admin_user.can? :manage=>"#{@admin_user.uuid}"
36
37     assert @admin_user.groups_i_can(:read).size > 0, "admin active user should be able read at least one group"
38     assert @admin_user.groups_i_can(:write).size > 0, "admin active user should be able write to at least one group"
39     assert @admin_user.groups_i_can(:manage).size > 0, "admin active user should be able manage at least one group"
40
41     # admin user can also write or manage other users
42     @uninvited_user = users(:inactive_uninvited)     # get the uninvited user
43     assert @admin_user.can? :read=>"#{@uninvited_user.uuid}"
44     assert @admin_user.can? :write=>"#{@uninvited_user.uuid}"
45     assert @admin_user.can? :manage=>"#{@uninvited_user.uuid}"
46   end
47
48   test "check inactive and uninvited user properties" do
49     @uninvited_user = users(:inactive_uninvited)     # get the uninvited user
50     assert !@uninvited_user.is_admin, 'is_admin should not be set for a non-admin user'
51     assert !@uninvited_user.is_active, 'user should be inactive'
52     assert !@uninvited_user.is_invited, 'is_invited should not be set'
53     assert @uninvited_user.can? :read=>"#{@uninvited_user.uuid}"
54     assert @uninvited_user.can? :write=>"#{@uninvited_user.uuid}"
55     assert @uninvited_user.can? :manage=>"#{@uninvited_user.uuid}"
56
57     assert @uninvited_user.groups_i_can(:read).size == 0, "inactive and uninvited user should not be able read any groups"
58     assert @uninvited_user.groups_i_can(:write).size == 0, "inactive and uninvited user should not be able write to any groups"
59     assert @uninvited_user.groups_i_can(:manage).size == 0, "inactive and uninvited user should not be able manage any groups"
60   end
61
62   test "find user method checks" do
63     User.find(:all).each do |user|
64       assert_not_nil user.uuid, "non-null uuid expected for " + user.full_name
65     end
66
67     user = users(:active)     # get the active user
68
69     found_user = User.find(user.id)   # find a user by the row id
70
71     assert_equal found_user.full_name, user.first_name + ' ' + user.last_name
72     assert_equal found_user.identity_url, user.identity_url
73   end
74
75   test "full name should not contain spurious whitespace" do
76     set_user_from_auth :admin
77
78     user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: 'foo@example.com' })
79
80     assert_equal '', user.full_name
81
82     user.first_name = 'John'
83     user.last_name = 'Smith'
84
85     assert_equal user.first_name + ' ' + user.last_name, user.full_name
86   end
87
88   test "create new user" do
89     set_user_from_auth :admin
90
91     @all_users = User.find(:all)
92
93     user = User.new
94     user.first_name = "first_name_for_newly_created_user"
95     user.save
96
97     # verify there is one extra user in the db now
98     assert_equal @all_users.size+1, User.find(:all).size
99
100     user = User.find(user.id)   # get the user back
101     assert_equal(user.first_name, 'first_name_for_newly_created_user')
102     assert_not_nil user.uuid, 'uuid should be set for newly created user'
103     assert_nil user.email, 'email should be null for newly created user, because it was not passed in'
104     assert_nil user.identity_url, 'identity_url should be null for newly created user, because it was not passed in'
105
106     user.first_name = 'first_name_for_newly_created_user_updated'
107     user.save
108     user = User.find(user.id)   # get the user back
109     assert_equal(user.first_name, 'first_name_for_newly_created_user_updated')
110   end
111
112   test "create new inactive user with new_inactive_user_notification_recipients empty" do
113     set_user_from_auth :admin
114
115     Rails.configuration.new_inactive_user_notification_recipients = ''
116
117     ActionMailer::Base.deliveries = []
118
119     user = User.new
120     user.first_name = "first_name_for_newly_created_user"
121     user.is_active = false
122     user.save
123
124     assert_equal '', Rails.configuration.new_inactive_user_notification_recipients
125
126     ActionMailer::Base.deliveries.each do |d|
127       assert_not_equal "#{Rails.configuration.email_subject_prefix}New inactive user notification", setup_email.subject
128     end
129
130   end
131
132   test "create new inactive user with new_user_notification_recipients empty" do
133     set_user_from_auth :admin
134
135     Rails.configuration.new_user_notification_recipients = ''
136
137     ActionMailer::Base.deliveries = []
138
139     user = User.new
140     user.first_name = "first_name_for_newly_created_user"
141     user.is_active = false
142     user.save
143
144     assert_equal '', Rails.configuration.new_user_notification_recipients
145
146     ActionMailer::Base.deliveries.each do |d|
147       assert_not_equal "#{Rails.configuration.email_subject_prefix}New user notification", d.subject
148     end
149
150   end
151
152   test "create new inactive user with new_user_notification_recipients and new_inactive_user_notification_recipients set" do
153     set_user_from_auth :admin
154
155     Rails.configuration.new_user_notification_recipients = 'foo_new@example.com'
156     Rails.configuration.new_inactive_user_notification_recipients = 'foo_new_inactive@example.com'
157
158     ActionMailer::Base.deliveries = []
159
160     user = User.new
161     user.first_name = "first_name_for_newly_created_user"
162     user.is_active = false
163     user.save
164
165     new_user_email = nil
166     new_inactive_user_email = nil
167     ActionMailer::Base.deliveries.each do |d|
168       if d.subject == "#{Rails.configuration.email_subject_prefix}New inactive user notification" then
169         new_inactive_user_email = d
170       end
171       if d.subject == "#{Rails.configuration.email_subject_prefix}New user notification" then
172         new_user_email = d
173       end
174     end
175
176     assert_not_nil new_inactive_user_email, 'Expected new inactive user email after setup'
177     assert_not_nil new_user_email, 'Expected new user email after setup'
178
179     assert_equal 'foo_new@example.com', Rails.configuration.new_user_notification_recipients
180     assert_equal 'foo_new_inactive@example.com', Rails.configuration.new_inactive_user_notification_recipients
181
182     assert_equal Rails.configuration.user_notifier_email_from, new_inactive_user_email.from[0]
183     assert_equal 'foo_new_inactive@example.com', new_inactive_user_email.to[0]
184     assert_equal "#{Rails.configuration.email_subject_prefix}New inactive user notification", new_inactive_user_email.subject
185
186     assert_equal Rails.configuration.user_notifier_email_from, new_user_email.from[0]
187     assert_equal 'foo_new@example.com', new_user_email.to[0]
188     assert_equal "#{Rails.configuration.email_subject_prefix}New user notification", new_user_email.subject
189   end
190
191   test "create new inactive user with new_user_notification_recipients set" do
192     set_user_from_auth :admin
193
194     Rails.configuration.new_user_notification_recipients = 'foo@example.com'
195
196     user = User.new
197     user.first_name = "first_name_for_newly_created_user"
198     user.is_active = false
199     user.save
200
201     new_user_email = nil
202
203     ActionMailer::Base.deliveries.each do |d|
204       if d.subject == "#{Rails.configuration.email_subject_prefix}New user notification" then
205         new_user_email = d
206         break
207       end
208     end
209
210     assert_not_nil new_user_email, 'Expected email after setup'
211
212     assert_equal 'foo@example.com', Rails.configuration.new_user_notification_recipients
213
214     assert_equal Rails.configuration.user_notifier_email_from, new_user_email.from[0]
215     assert_equal 'foo@example.com', new_user_email.to[0]
216     assert_equal "#{Rails.configuration.email_subject_prefix}New user notification", new_user_email.subject
217   end
218
219   test "create new active user with new_inactive_user_notification_recipients set" do
220     set_user_from_auth :admin
221
222     Rails.configuration.new_inactive_user_notification_recipients = 'foo@example.com'
223
224     ActionMailer::Base.deliveries = []
225
226     user = User.new
227     user.first_name = "first_name_for_newly_created_user"
228     user.is_active = true
229     user.save
230
231     assert_equal 'foo@example.com', Rails.configuration.new_inactive_user_notification_recipients
232
233     ActionMailer::Base.deliveries.each do |d|
234       assert_not_equal "#{Rails.configuration.email_subject_prefix}New inactive user notification", setup_email.subject
235     end
236
237   end
238
239
240   test "update existing user" do
241     set_user_from_auth :active    # set active user as current user
242
243     @active_user = users(:active)     # get the active user
244
245     @active_user.first_name = "first_name_changed"
246     @active_user.save
247
248     @active_user = User.find(@active_user.id)   # get the user back
249     assert_equal(@active_user.first_name, 'first_name_changed')
250
251     # admin user also should be able to update the "active" user info
252     set_user_from_auth :admin # set admin user as current user
253     @active_user.first_name = "first_name_changed_by_admin_for_active_user"
254     @active_user.save
255
256     @active_user = User.find(@active_user.id)   # get the user back
257     assert_equal(@active_user.first_name, 'first_name_changed_by_admin_for_active_user')
258   end
259
260   test "delete a user and verify" do
261     @active_user = users(:active)     # get the active user
262     active_user_uuid = @active_user.uuid
263
264     set_user_from_auth :admin
265     @active_user.delete
266
267     found_deleted_user = false
268     User.find(:all).each do |user|
269       if user.uuid == active_user_uuid
270         found_deleted_user = true
271         break
272       end
273     end
274     assert !found_deleted_user, "found deleted user: "+active_user_uuid
275
276   end
277
278   test "create new user as non-admin user" do
279     set_user_from_auth :active
280
281     begin
282       user = User.new
283       user.save
284     rescue ArvadosModel::PermissionDeniedError => e
285     end
286     assert (e.message.include? 'PermissionDeniedError'),
287         'Expected PermissionDeniedError'
288   end
289
290   test "setup new user" do
291     set_user_from_auth :admin
292
293     email = 'foo@example.com'
294     openid_prefix = 'http://openid/prefix'
295
296     user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
297
298     vm = VirtualMachine.create
299
300     response = User.setup user, openid_prefix, 'test_repo', vm.uuid
301
302     resp_user = find_obj_in_resp response, 'User'
303     verify_user resp_user, email
304
305     oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
306
307     verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
308         resp_user[:uuid]
309
310     assert_equal openid_prefix, oid_login_perm[:properties]['identity_url_prefix'],
311         'expected identity_url_prefix not found for oid_login_perm'
312
313     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
314     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
315
316     repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
317     verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
318
319     vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
320     verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
321   end
322
323   test "setup new user with junk in database" do
324     set_user_from_auth :admin
325
326     email = 'foo@example.com'
327     openid_prefix = 'http://openid/prefix'
328
329     user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
330
331     vm = VirtualMachine.create
332
333     # Set up the bogus Link
334     bad_uuid = 'zzzzz-tpzed-xyzxyzxyzxyzxyz'
335
336     resp_link = Link.create ({tail_uuid: email, link_class: 'permission',
337         name: 'can_login', head_uuid: bad_uuid})
338     resp_link.save(validate: false)
339
340     verify_link resp_link, 'permission', 'can_login', email, bad_uuid
341
342     response = User.setup user, openid_prefix, 'test_repo', vm.uuid
343
344     resp_user = find_obj_in_resp response, 'User'
345     verify_user resp_user, email
346
347     oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
348
349     verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
350         resp_user[:uuid]
351
352     assert_equal openid_prefix, oid_login_perm[:properties]['identity_url_prefix'],
353         'expected identity_url_prefix not found for oid_login_perm'
354
355     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
356     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
357
358     repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
359     verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
360
361     vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
362     verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
363   end
364
365
366
367   test "setup new user in multiple steps" do
368     set_user_from_auth :admin
369
370     email = 'foo@example.com'
371     openid_prefix = 'http://openid/prefix'
372
373     user = User.create ({uuid: 'zzzzz-tpzed-abcdefghijklmno', email: email})
374
375     response = User.setup user, openid_prefix
376
377     resp_user = find_obj_in_resp response, 'User'
378     verify_user resp_user, email
379
380     oid_login_perm = find_obj_in_resp response, 'Link', 'arvados#user'
381     verify_link oid_login_perm, 'permission', 'can_login', resp_user[:email],
382         resp_user[:uuid]
383     assert_equal openid_prefix, oid_login_perm[:properties]['identity_url_prefix'],
384         'expected identity_url_prefix not found for oid_login_perm'
385
386     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
387     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
388
389     # invoke setup again with repo_name
390     response = User.setup user, openid_prefix, 'test_repo'
391     resp_user = find_obj_in_resp response, 'User', nil
392     verify_user resp_user, email
393     assert_equal user.uuid, resp_user[:uuid], 'expected uuid not found'
394
395     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
396     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
397
398     repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
399     verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
400
401     # invoke setup again with a vm_uuid
402     vm = VirtualMachine.create
403
404     response = User.setup user, openid_prefix, 'test_repo', vm.uuid
405
406     resp_user = find_obj_in_resp response, 'User', nil
407     verify_user resp_user, email
408     assert_equal user.uuid, resp_user[:uuid], 'expected uuid not found'
409
410     group_perm = find_obj_in_resp response, 'Link', 'arvados#group'
411     verify_link group_perm, 'permission', 'can_read', resp_user[:uuid], nil
412
413     repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository'
414     verify_link repo_perm, 'permission', 'can_write', resp_user[:uuid], nil
415
416     vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine'
417     verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid
418   end
419
420   def find_obj_in_resp (response_items, object_type, head_kind=nil)
421     return_obj = nil
422     response_items.each { |x|
423       if !x
424         next
425       end
426
427       if object_type == 'User'
428         if ArvadosModel::resource_class_for_uuid(x['uuid']) == User
429           return_obj = x
430           break
431         end
432       else  # looking for a link
433         if ArvadosModel::resource_class_for_uuid(x['head_uuid']).kind == head_kind
434           return_obj = x
435           break
436         end
437       end
438     }
439     return return_obj
440   end
441
442   def verify_user (resp_user, email)
443     assert_not_nil resp_user, 'expected user object'
444     assert_not_nil resp_user['uuid'], 'expected user object'
445     assert_equal email, resp_user['email'], 'expected email not found'
446
447   end
448
449   def verify_link (link_object, link_class, link_name, tail_uuid, head_uuid)
450     assert_not_nil link_object, "expected link for #{link_class} #{link_name}"
451     assert_not_nil link_object[:uuid],
452         "expected non-nil uuid for link for #{link_class} #{link_name}"
453     assert_equal link_class, link_object[:link_class],
454         "expected link_class not found for #{link_class} #{link_name}"
455     assert_equal link_name, link_object[:name],
456         "expected link_name not found for #{link_class} #{link_name}"
457     assert_equal tail_uuid, link_object[:tail_uuid],
458         "expected tail_uuid not found for #{link_class} #{link_name}"
459     if head_uuid
460       assert_equal head_uuid, link_object[:head_uuid],
461           "expected head_uuid not found for #{link_class} #{link_name}"
462     end
463   end
464
465 end