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