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