Merge branch '15397-remove-obsolete-apis'
[arvados.git] / services / api / test / integration / users_test.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 require 'test_helper'
6 require 'helpers/users_test_helper'
7
8 class UsersTest < ActionDispatch::IntegrationTest
9   include UsersTestHelper
10
11   test "setup user multiple times" do
12     post "/arvados/v1/users/setup",
13       params: {
14         user: {
15           uuid: 'zzzzz-tpzed-abcdefghijklmno',
16           first_name: "in_create_test_first_name",
17           last_name: "test_last_name",
18           email: "foo@example.com"
19         }
20       },
21       headers: auth(:admin)
22
23     assert_response :success
24
25     response_items = json_response['items']
26
27     created = find_obj_in_resp response_items, 'arvados#user', nil
28
29     assert_equal 'in_create_test_first_name', created['first_name']
30     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
31     assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
32     assert_not_nil created['email'], 'expected non-nil email'
33     assert_nil created['identity_url'], 'expected no identity_url'
34
35     # link to add user to 'All users' group
36
37     verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
38         'All users', created['uuid'], 'arvados#group', true, 'Group'
39
40     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
41         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
42
43     verify_system_group_permission_link_for created['uuid']
44
45     # invoke setup again with the same data
46     post "/arvados/v1/users/setup",
47       params: {
48         vm_uuid: virtual_machines(:testvm).uuid,
49         user: {
50           uuid: 'zzzzz-tpzed-abcdefghijklmno',
51           first_name: "in_create_test_first_name",
52           last_name: "test_last_name",
53           email: "foo@example.com"
54         }
55       },
56       headers: auth(:admin)
57     assert_response 422         # cannot create another user with same UUID
58
59     # invoke setup on the same user
60     post "/arvados/v1/users/setup",
61       params: {
62         vm_uuid: virtual_machines(:testvm).uuid,
63         uuid: 'zzzzz-tpzed-abcdefghijklmno',
64       },
65       headers: auth(:admin)
66
67     response_items = json_response['items']
68
69     created = find_obj_in_resp response_items, 'arvados#user', nil
70     assert_equal 'in_create_test_first_name', created['first_name']
71     assert_not_nil created['uuid'], 'expected non-null uuid for the new user'
72     assert_equal 'zzzzz-tpzed-abcdefghijklmno', created['uuid']
73     assert_not_nil created['email'], 'expected non-nil email'
74     assert_nil created['identity_url'], 'expected no identity_url'
75
76     # arvados#user, and link to add user to 'All users' group
77     verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
78         'All users', created['uuid'], 'arvados#group', true, 'Group'
79
80     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
81         virtual_machines(:testvm).uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
82
83     verify_system_group_permission_link_for created['uuid']
84   end
85
86   test "setup user in multiple steps and verify response" do
87     post "/arvados/v1/users/setup",
88       params: {
89         user: {
90           email: "foo@example.com"
91         }
92       },
93       headers: auth(:admin)
94
95     assert_response :success
96     response_items = json_response['items']
97     created = find_obj_in_resp response_items, 'arvados#user', nil
98
99     assert_not_nil created['uuid'], 'expected uuid for new user'
100     assert_not_nil created['email'], 'expected non-nil email'
101     assert_equal created['email'], 'foo@example.com', 'expected input email'
102
103     # two new links: system_group, and 'All users' group.
104
105     verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
106         'All users', created['uuid'], 'arvados#group', true, 'Group'
107
108     verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login',
109         nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
110
111     # invoke setup with a vm_uuid
112     post "/arvados/v1/users/setup",
113       params: {
114         vm_uuid: virtual_machines(:testvm).uuid,
115         user: {
116           email: 'junk_email'
117         },
118         uuid: created['uuid']
119       },
120       headers: auth(:admin)
121
122     assert_response :success
123
124     response_items = json_response['items']
125     created = find_obj_in_resp response_items, 'arvados#user', nil
126
127     assert_equal created['email'], 'foo@example.com', 'expected original email'
128
129     # verify links
130     verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
131         'All users', created['uuid'], 'arvados#group', true, 'Group'
132
133     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
134         virtual_machines(:testvm).uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
135   end
136
137   test "setup and unsetup user" do
138     post "/arvados/v1/users/setup",
139       params: {
140         vm_uuid: virtual_machines(:testvm).uuid,
141         user: {email: 'foo@example.com'},
142       },
143       headers: auth(:admin)
144
145     assert_response :success
146     response_items = json_response['items']
147     created = find_obj_in_resp response_items, 'arvados#user', nil
148     assert_not_nil created['uuid'], 'expected uuid for the new user'
149     assert_equal created['email'], 'foo@example.com', 'expected given email'
150
151     # three extra links: system_group, login, group and vm
152
153     verify_link response_items, 'arvados#group', true, 'permission', 'can_write',
154         'All users', created['uuid'], 'arvados#group', true, 'Group'
155
156     verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login',
157         virtual_machines(:testvm).uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine'
158
159     verify_link_existence created['uuid'], created['email'], true, true, true, true, false
160
161     # create a token
162     token = act_as_system_user do
163       ApiClientAuthorization.create!(user: User.find_by_uuid(created['uuid']), api_client: ApiClient.all.first).api_token
164     end
165
166     # share project and collections with the new user
167     act_as_system_user do
168       Link.create!(tail_uuid: created['uuid'],
169                    head_uuid: groups(:aproject).uuid,
170                    link_class: 'permission',
171                    name: 'can_manage')
172       Link.create!(tail_uuid: created['uuid'],
173                    head_uuid: collections(:collection_owned_by_active).uuid,
174                    link_class: 'permission',
175                    name: 'can_read')
176       Link.create!(tail_uuid: created['uuid'],
177                    head_uuid: collections(:collection_owned_by_active_with_file_stats).uuid,
178                    link_class: 'permission',
179                    name: 'can_write')
180     end
181
182     assert_equal 1, ApiClientAuthorization.where(user_id: User.find_by_uuid(created['uuid']).id).size, 'expected token not found'
183
184     post "/arvados/v1/users/#{created['uuid']}/unsetup", params: {}, headers: auth(:admin)
185
186     assert_response :success
187
188     created2 = json_response
189     assert_not_nil created2['uuid'], 'expected uuid for the newly created user'
190     assert_equal created['uuid'], created2['uuid'], 'expected uuid not found'
191     assert_equal 0, ApiClientAuthorization.where(user_id: User.find_by_uuid(created['uuid']).id).size, 'token should have been deleted by user unsetup'
192     # check permissions are deleted
193     assert_empty Link.where(tail_uuid: created['uuid'])
194
195     verify_link_existence created['uuid'], created['email'], false, false, false, false, false
196   end
197
198   def find_obj_in_resp (response_items, kind, head_kind=nil)
199     response_items.each do |x|
200       if x && x['kind']
201         return x if (x['kind'] == kind && x['head_kind'] == head_kind)
202       end
203     end
204     nil
205   end
206
207   test 'merge active into project_viewer account' do
208     post('/arvados/v1/groups',
209       params: {
210         group: {
211           group_class: 'project',
212           name: "active user's stuff",
213         },
214       },
215       headers: auth(:project_viewer))
216     assert_response(:success)
217     project_uuid = json_response['uuid']
218
219     post('/arvados/v1/users/merge',
220       params: {
221         new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token,
222         new_owner_uuid: project_uuid,
223         redirect_to_new_user: true,
224       },
225       headers: auth(:active_trustedclient))
226     assert_response(:success)
227
228     get('/arvados/v1/users/current', params: {}, headers: auth(:active))
229     assert_response(:success)
230     assert_equal(users(:project_viewer).uuid, json_response['uuid'])
231
232     get('/arvados/v1/authorized_keys/' + authorized_keys(:active).uuid,
233       params: {},
234       headers: auth(:active))
235     assert_response(:success)
236     assert_equal(users(:project_viewer).uuid, json_response['owner_uuid'])
237     assert_equal(users(:project_viewer).uuid, json_response['authorized_user_uuid'])
238
239     get('/arvados/v1/groups/' + groups(:aproject).uuid,
240       params: {},
241       headers: auth(:active))
242     assert_response(:success)
243     assert_equal(project_uuid, json_response['owner_uuid'])
244   end
245
246   test 'pre-activate user' do
247     post '/arvados/v1/users',
248       params: {
249         "user" => {
250           "email" => 'foo@example.com',
251           "is_active" => true,
252           "username" => "barney"
253         }
254       },
255       headers: {'HTTP_AUTHORIZATION' => "OAuth2 #{api_token(:admin)}"}
256     assert_response :success
257     rp = json_response
258     assert_not_nil rp["uuid"]
259     assert_equal true, rp["is_active"]
260     assert_equal false, rp["is_admin"]
261
262     get "/arvados/v1/users/#{rp['uuid']}",
263       params: {format: 'json'},
264       headers: auth(:admin)
265     assert_response :success
266     assert_equal rp["uuid"], json_response['uuid']
267     assert_equal false, json_response['is_admin']
268     assert_equal true, json_response['is_active']
269     assert_equal 'foo@example.com', json_response['email']
270     assert_equal 'barney', json_response['username']
271   end
272
273   test "cannot set is_active to false directly" do
274     post('/arvados/v1/users',
275       params: {
276         user: {
277           email: "bob@example.com",
278           username: "bobby"
279         },
280       },
281       headers: auth(:admin))
282     assert_response(:success)
283     user = json_response
284     assert_equal false, user['is_active']
285
286     token = act_as_system_user do
287       ApiClientAuthorization.create!(user: User.find_by_uuid(user['uuid']), api_client: ApiClient.all.first).api_token
288     end
289     post("/arvados/v1/user_agreements/sign",
290         params: {uuid: 'zzzzz-4zz18-t68oksiu9m80s4y'},
291         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"})
292     assert_response :success
293
294     post("/arvados/v1/users/#{user['uuid']}/activate",
295       params: {},
296       headers: auth(:admin))
297     assert_response(:success)
298     user = json_response
299     assert_equal true, user['is_active']
300
301     put("/arvados/v1/users/#{user['uuid']}",
302          params: {
303            user: {is_active: false}
304          },
305          headers: auth(:admin))
306     assert_response 422
307   end
308
309   test "cannot self activate when AutoSetupNewUsers is false" do
310     Rails.configuration.Users.NewUsersAreActive = false
311     Rails.configuration.Users.AutoSetupNewUsers = false
312
313     user = nil
314     token = nil
315     act_as_system_user do
316       user = User.create!(email: "bob@example.com", username: "bobby")
317       ap = ApiClientAuthorization.create!(user: user, api_client: ApiClient.all.first)
318       token = ap.api_token
319     end
320
321     get("/arvados/v1/users/#{user['uuid']}",
322         params: {},
323         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"})
324     assert_response(:success)
325     user = json_response
326     assert_equal false, user['is_active']
327
328     post("/arvados/v1/users/#{user['uuid']}/activate",
329         params: {},
330         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"})
331     assert_response 422
332     assert_match(/Cannot activate without being invited/, json_response['errors'][0])
333   end
334
335
336   test "cannot self activate after unsetup" do
337     Rails.configuration.Users.NewUsersAreActive = false
338     Rails.configuration.Users.AutoSetupNewUsers = false
339
340     user = nil
341     token = nil
342     act_as_system_user do
343       user = User.create!(email: "bob@example.com", username: "bobby")
344       ap = ApiClientAuthorization.create!(user: user, api_client_id: 0)
345       token = ap.api_token
346     end
347
348     post("/arvados/v1/users/setup",
349         params: {uuid: user['uuid']},
350         headers: auth(:admin))
351     assert_response :success
352
353     post("/arvados/v1/users/#{user['uuid']}/activate",
354         params: {},
355         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"})
356     assert_response 403
357     assert_match(/Cannot activate without user agreements/, json_response['errors'][0])
358
359     post("/arvados/v1/user_agreements/sign",
360         params: {uuid: 'zzzzz-4zz18-t68oksiu9m80s4y'},
361         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"})
362     assert_response :success
363
364     post("/arvados/v1/users/#{user['uuid']}/activate",
365         params: {},
366         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"})
367     assert_response :success
368
369     get("/arvados/v1/users/#{user['uuid']}",
370         params: {},
371         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"})
372     assert_response(:success)
373     userJSON = json_response
374     assert_equal true, userJSON['is_active']
375
376     post("/arvados/v1/users/#{user['uuid']}/unsetup",
377         params: {},
378         headers: auth(:admin))
379     assert_response :success
380
381     # Need to get a new token, the old one was invalidated by the unsetup call
382     act_as_system_user do
383       ap = ApiClientAuthorization.create!(user: user, api_client_id: 0)
384       token = ap.api_token
385     end
386
387     get("/arvados/v1/users/#{user['uuid']}",
388         params: {},
389         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"})
390     assert_response(:success)
391     userJSON = json_response
392     assert_equal false, userJSON['is_active']
393
394     post("/arvados/v1/users/#{user['uuid']}/activate",
395         params: {},
396         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"})
397     assert_response 422
398     assert_match(/Cannot activate without being invited/, json_response['errors'][0])
399   end
400
401   test "bypass_federation only accepted for admins" do
402     get "/arvados/v1/users",
403       params: {
404         bypass_federation: true
405       },
406       headers: auth(:admin)
407
408     assert_response :success
409
410     get "/arvados/v1/users",
411       params: {
412         bypass_federation: true
413       },
414       headers: auth(:active)
415
416     assert_response 403
417   end
418
419   test "disabling system root user not permitted" do
420     put("/arvados/v1/users/#{users(:system_user).uuid}",
421       params: {
422         user: {is_admin: false}
423       },
424       headers: auth(:admin))
425     assert_response 422
426
427     post("/arvados/v1/users/#{users(:system_user).uuid}/unsetup",
428       params: {},
429       headers: auth(:admin))
430     assert_response 422
431   end
432
433   test "creating users only accepted for admins" do
434     assert_equal false, users(:active).is_admin
435     post '/arvados/v1/users',
436       params: {
437         "user" => {
438           "email" => 'foo@example.com',
439           "username" => "barney"
440         }
441       },
442       headers: auth(:active)
443     assert_response 403
444   end
445
446   test "create users assigns the system root user as their owner" do
447     post '/arvados/v1/users',
448       params: {
449         "user" => {
450           "email" => 'foo@example.com',
451           "username" => "barney"
452         }
453       },
454       headers: auth(:admin)
455     assert_response :success
456     assert_not_nil json_response["uuid"]
457     assert_equal users(:system_user).uuid, json_response["owner_uuid"]
458   end
459
460   test "create users ignores provided owner_uuid field" do
461     assert_equal false, users(:admin).uuid == users(:system_user).uuid
462     post '/arvados/v1/users',
463       params: {
464         "user" => {
465           "email" => 'foo@example.com',
466           "owner_uuid" => users(:admin).uuid,
467           "username" => "barney"
468         }
469       },
470       headers: auth(:admin)
471     assert_response :success
472     assert_not_nil json_response["uuid"]
473     assert_equal users(:system_user).uuid, json_response["owner_uuid"]
474   end
475 end