21461: Fixes log line-breaking behavior for really long strings.
[arvados.git] / services / api / test / integration / remote_user_test.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 require 'webrick'
6 require 'webrick/https'
7 require 'test_helper'
8 require 'helpers/users_test_helper'
9
10 class RemoteUsersTest < ActionDispatch::IntegrationTest
11   include DbCurrentTime
12
13   def salted_active_token(remote:)
14     salt_token(fixture: :active, remote: remote).sub('/zzzzz-', '/'+remote+'-')
15   end
16
17   def auth(remote:)
18     token = salted_active_token(remote: remote)
19     {"HTTP_AUTHORIZATION" => "Bearer #{token}"}
20   end
21
22   # For remote authentication tests, we bring up a simple stub server
23   # (on a port chosen by webrick) and configure the SUT so the stub is
24   # responsible for clusters "zbbbb" (a well-behaved cluster) and
25   # "zbork" (a misbehaving cluster).
26   #
27   # Test cases can override the stub's default response to
28   # .../users/current by changing @stub_status and @stub_content.
29   setup do
30     clnt = HTTPClient.new
31     clnt.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
32     HTTPClient.stubs(:new).returns clnt
33
34     @controller = Arvados::V1::UsersController.new
35     ready = Thread::Queue.new
36
37     @remote_server = []
38     @remote_host = []
39
40     ['zbbbb', 'zbork'].each do |clusterid|
41       srv = WEBrick::HTTPServer.new(
42         Port: 0,
43         Logger: WEBrick::Log.new(
44           Rails.root.join("log", "webrick.log").to_s,
45           WEBrick::Log::INFO),
46         AccessLog: [[File.open(Rails.root.join(
47                                  "log", "webrick_access.log").to_s, 'a+'),
48                      WEBrick::AccessLog::COMBINED_LOG_FORMAT]],
49         SSLEnable: true,
50         SSLVerifyClient: OpenSSL::SSL::VERIFY_NONE,
51         SSLPrivateKey: OpenSSL::PKey::RSA.new(
52           File.open(Rails.root.join("tmp", "self-signed.key")).read),
53         SSLCertificate: OpenSSL::X509::Certificate.new(
54           File.open(Rails.root.join("tmp", "self-signed.pem")).read),
55         SSLCertName: [["CN", WEBrick::Utils::getservername]],
56         StartCallback: lambda { ready.push(true) })
57       srv.mount_proc '/discovery/v1/apis/arvados/v1/rest' do |req, res|
58         res.body = Arvados::V1::SchemaController.new.send(:discovery_doc).to_json
59       end
60       srv.mount_proc '/arvados/v1/users/current' do |req, res|
61         if clusterid == 'zbbbb' and req.header['authorization'][0][10..14] == 'zbork'
62           # asking zbbbb about zbork should yield an error, zbbbb doesn't trust zbork
63           res.status = 401
64           return
65         end
66         res.status = @stub_status
67         res.body = @stub_content.is_a?(String) ? @stub_content : @stub_content.to_json
68       end
69       srv.mount_proc '/arvados/v1/api_client_authorizations/current' do |req, res|
70         if clusterid == 'zbbbb' and req.header['authorization'][0][10..14] == 'zbork'
71           # asking zbbbb about zbork should yield an error, zbbbb doesn't trust zbork
72           res.status = 401
73           return
74         end
75         res.status = @stub_token_status
76         if res.status == 200
77           body = {
78             uuid: api_client_authorizations(:active).uuid.sub('zzzzz', clusterid),
79             owner_uuid: "#{clusterid}-tpzed-00000000000000z",
80             scopes: @stub_token_scopes,
81           }
82           if @stub_content.is_a?(Hash) and owner_uuid = @stub_content[:uuid]
83             body[:owner_uuid] = owner_uuid
84           end
85           res.body = body.to_json
86         end
87       end
88       Thread.new do
89         srv.start
90       end
91       ready.pop
92       @remote_server << srv
93       @remote_host << "127.0.0.1:#{srv.config[:Port]}"
94     end
95     Rails.configuration.RemoteClusters = Rails.configuration.RemoteClusters.merge({zbbbb: ActiveSupport::InheritableOptions.new({Host: @remote_host[0]}),
96                                                                                    zbork: ActiveSupport::InheritableOptions.new({Host: @remote_host[1]})})
97     Arvados::V1::SchemaController.any_instance.stubs(:root_url).returns "https://#{@remote_host[0]}"
98     @stub_status = 200
99     @stub_content = {
100       uuid: 'zbbbb-tpzed-000000000000001',
101       email: 'foo@example.com',
102       username: 'barney',
103       first_name: "Barney",
104       last_name: "Foo",
105       is_admin: true,
106       is_active: true,
107       is_invited: true,
108     }
109     @stub_token_status = 200
110     @stub_token_scopes = ["all"]
111     ActionMailer::Base.deliveries = []
112   end
113
114   teardown do
115     @remote_server.each do |srv|
116       srv.stop
117     end
118   end
119
120   def uncache_token(src)
121     if match = src.match(/\b(?:[a-z0-9]{5}-){2}[a-z0-9]{15}\b/)
122       tokens = ApiClientAuthorization.where(uuid: match[0])
123     else
124       tokens = ApiClientAuthorization.where("uuid like ?", "#{src}-%")
125     end
126     tokens.update_all(expires_at: "1995-05-15T01:02:03Z")
127   end
128
129   test 'authenticate with remote token that has limited scope' do
130     get '/arvados/v1/collections',
131         params: {format: 'json'},
132         headers: auth(remote: 'zbbbb')
133     assert_response :success
134
135     @stub_token_scopes = ["GET /arvados/v1/users/current"]
136
137     # re-authorize before cache expires
138     get '/arvados/v1/collections',
139         params: {format: 'json'},
140         headers: auth(remote: 'zbbbb')
141     assert_response :success
142
143     uncache_token('zbbbb')
144     # re-authorize after cache expires
145     get '/arvados/v1/collections',
146         params: {format: 'json'},
147         headers: auth(remote: 'zbbbb')
148     assert_response 403
149   end
150
151   test "authenticate with remote token with limited initial scope" do
152     @stub_token_scopes = ["GET /arvados/v1/users/"]
153     get "/arvados/v1/users/#{@stub_content[:uuid]}",
154         params: {format: "json"},
155         headers: auth(remote: "zbbbb")
156     assert_response :success
157   end
158
159   test 'authenticate with remote token' do
160     get '/arvados/v1/users/current',
161       params: {format: 'json'},
162       headers: auth(remote: 'zbbbb')
163     assert_response :success
164     assert_equal 'zbbbb-tpzed-000000000000001', json_response['uuid']
165     assert_equal false, json_response['is_admin']
166     assert_equal false, json_response['is_active']
167     assert_equal 'foo@example.com', json_response['email']
168     assert_equal 'barney', json_response['username']
169
170     # revoke original token
171     @stub_token_status = 401
172
173     # re-authorize before cache expires
174     get '/arvados/v1/users/current',
175       params: {format: 'json'},
176       headers: auth(remote: 'zbbbb')
177     assert_response :success
178
179     uncache_token('zbbbb')
180     # re-authorize after cache expires
181     get '/arvados/v1/users/current',
182       params: {format: 'json'},
183       headers: auth(remote: 'zbbbb')
184     assert_response 401
185
186     # simulate cached token indicating wrong user (e.g., local user
187     # entry was migrated out of the way taking the cached token with
188     # it, or authorizing cluster reassigned auth to a different user)
189     ApiClientAuthorization.where(
190       uuid: salted_active_token(remote: 'zbbbb').split('/')[1]).
191       update_all(user_id: users(:active).id)
192
193     # revive original token and re-authorize
194     @stub_token_status = 200
195     @stub_content[:username] = 'blarney'
196     @stub_content[:email] = 'blarney@example.com'
197     get '/arvados/v1/users/current',
198       params: {format: 'json'},
199       headers: auth(remote: 'zbbbb')
200     assert_response :success
201     assert_equal 'barney', json_response['username'], 'local username should not change once assigned'
202     assert_equal 'blarney@example.com', json_response['email']
203   end
204
205   test 'remote user is deactivated' do
206     Rails.configuration.RemoteClusters['zbbbb'].ActivateUsers = true
207     get '/arvados/v1/users/current',
208       params: {format: 'json'},
209       headers: auth(remote: 'zbbbb')
210     assert_response :success
211     assert_equal true, json_response['is_active']
212
213     # revoke original token
214     @stub_content[:is_active] = false
215     @stub_content[:is_invited] = false
216
217     uncache_token('zbbbb')
218     # re-authorize after cache expires
219     get '/arvados/v1/users/current',
220       params: {format: 'json'},
221       headers: auth(remote: 'zbbbb')
222     assert_equal false, json_response['is_active']
223
224   end
225
226   test 'authenticate with remote token, remote username conflicts with local' do
227     @stub_content[:username] = 'active'
228     get '/arvados/v1/users/current',
229       params: {format: 'json'},
230       headers: auth(remote: 'zbbbb')
231     assert_response :success
232     assert_equal 'active2', json_response['username']
233   end
234
235   test 'authenticate with remote token, remote username is nil' do
236     @stub_content.delete :username
237     get '/arvados/v1/users/current',
238       params: {format: 'json'},
239       headers: auth(remote: 'zbbbb')
240     assert_response :success
241     assert_equal 'foo', json_response['username']
242   end
243
244   test 'authenticate with remote token from misbehaving remote cluster' do
245     get '/arvados/v1/users/current',
246       params: {format: 'json'},
247       headers: auth(remote: 'zbork')
248     assert_response 401
249   end
250
251   test 'authenticate with remote token that fails validate' do
252     @stub_status = 401
253     @stub_content = {
254       error: 'not authorized',
255     }
256     get '/arvados/v1/users/current',
257       params: {format: 'json'},
258       headers: auth(remote: 'zbbbb')
259     assert_response 401
260   end
261
262   ['v2',
263    'v2/',
264    'v2//',
265    'v2///',
266    "v2/'; delete from users where 1=1; commit; select '/lol",
267    'v2/foo/bar',
268    'v2/zzzzz-gj3su-077z32aux8dg2s1',
269    'v2/zzzzz-gj3su-077z32aux8dg2s1/',
270    'v2/3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi',
271    'v2/3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi/zzzzz-gj3su-077z32aux8dg2s1',
272    'v2//3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi',
273    'v8/zzzzz-gj3su-077z32aux8dg2s1/3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi',
274    '/zzzzz-gj3su-077z32aux8dg2s1/3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi',
275    '"v2/zzzzz-gj3su-077z32aux8dg2s1/3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi"',
276    '/',
277    '//',
278    '///',
279   ].each do |token|
280     test "authenticate with malformed remote token #{token}" do
281       get '/arvados/v1/users/current',
282         params: {format: 'json'},
283         headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}
284       assert_response 401
285     end
286   end
287
288   test "ignore extra fields in remote token" do
289     token = salted_active_token(remote: 'zbbbb') + '/foo/bar/baz/*'
290     get '/arvados/v1/users/current',
291       params: {format: 'json'},
292       headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}
293     assert_response :success
294   end
295
296   test 'remote api server is not an api server' do
297     @stub_status = 200
298     @stub_content = '<html>bad</html>'
299     get '/arvados/v1/users/current',
300       params: {format: 'json'},
301       headers: auth(remote: 'zbbbb')
302     assert_response 401
303   end
304
305   ['zbbbb', 'z0000'].each do |token_valid_for|
306     test "validate #{token_valid_for}-salted token for remote cluster zbbbb" do
307       salted_token = salt_token(fixture: :active, remote: token_valid_for)
308       get '/arvados/v1/users/current',
309         params: {format: 'json', remote: 'zbbbb'},
310         headers: {"HTTP_AUTHORIZATION" => "Bearer #{salted_token}"}
311       if token_valid_for == 'zbbbb'
312         assert_response 200
313         assert_equal(users(:active).uuid, json_response['uuid'])
314       else
315         assert_response 401
316       end
317     end
318   end
319
320   test "list readable groups with salted token" do
321     Rails.configuration.Users.RoleGroupsVisibleToAll = false
322     salted_token = salt_token(fixture: :active, remote: 'zbbbb')
323     get '/arvados/v1/groups',
324       params: {
325         format: 'json',
326         remote: 'zbbbb',
327         limit: 10000,
328       },
329       headers: {"HTTP_AUTHORIZATION" => "Bearer #{salted_token}"}
330     assert_response 200
331     group_uuids = json_response['items'].collect { |i| i['uuid'] }
332     assert_includes(group_uuids, 'zzzzz-j7d0g-fffffffffffffff')
333     refute_includes(group_uuids, 'zzzzz-j7d0g-000000000000000')
334     assert_includes(group_uuids, groups(:aproject).uuid)
335     refute_includes(group_uuids, groups(:trashed_project).uuid)
336     refute_includes(group_uuids, groups(:testusergroup_admins).uuid)
337   end
338
339   test 'do not auto-activate user from untrusted cluster' do
340     Rails.configuration.RemoteClusters['zbbbb'].AutoSetupNewUsers = false
341     Rails.configuration.RemoteClusters['zbbbb'].ActivateUsers = false
342     get '/arvados/v1/users/current',
343       params: {format: 'json'},
344       headers: auth(remote: 'zbbbb')
345     assert_response :success
346     assert_equal 'zbbbb-tpzed-000000000000001', json_response['uuid']
347     assert_equal false, json_response['is_admin']
348     assert_equal false, json_response['is_active']
349     assert_equal 'foo@example.com', json_response['email']
350     assert_equal 'barney', json_response['username']
351     post '/arvados/v1/users/zbbbb-tpzed-000000000000001/activate',
352       params: {format: 'json'},
353       headers: auth(remote: 'zbbbb')
354     assert_response 422
355   end
356
357   test 'auto-activate user from trusted cluster' do
358     Rails.configuration.RemoteClusters['zbbbb'].ActivateUsers = true
359     get '/arvados/v1/users/current',
360       params: {format: 'json'},
361       headers: auth(remote: 'zbbbb')
362     assert_response :success
363     assert_equal 'zbbbb-tpzed-000000000000001', json_response['uuid']
364     assert_equal false, json_response['is_admin']
365     assert_equal true, json_response['is_active']
366     assert_equal 'foo@example.com', json_response['email']
367     assert_equal 'barney', json_response['username']
368   end
369
370   test 'get user from Login cluster' do
371     Rails.configuration.Login.LoginCluster = 'zbbbb'
372     email_dest = ActiveSupport::OrderedOptions.new
373     email_dest[:'arvados-admin@example.com'] = ActiveSupport::OrderedOptions.new
374     Rails.configuration.Users.UserNotifierEmailBcc = email_dest
375     Rails.configuration.Users.NewUserNotificationRecipients = email_dest
376     Rails.configuration.Users.NewInactiveUserNotificationRecipients = email_dest
377
378     get '/arvados/v1/users/current',
379       params: {format: 'json'},
380       headers: auth(remote: 'zbbbb')
381     assert_response :success
382     assert_equal 'zbbbb-tpzed-000000000000001', json_response['uuid']
383     assert_equal true, json_response['is_admin']
384     assert_equal true, json_response['is_active']
385     assert_equal 'foo@example.com', json_response['email']
386     assert_equal 'barney', json_response['username']
387
388     assert_equal 2, ActionMailer::Base.deliveries.length
389     assert_equal "Welcome to Arvados - account enabled", ActionMailer::Base.deliveries[0].subject
390     assert_equal "[ARVADOS] New user created notification", ActionMailer::Base.deliveries[1].subject
391   end
392
393   [true, false].each do |trusted|
394     [true, false].each do |logincluster|
395       [true, false, nil].each do |admin|
396         [true, false, nil].each do |active|
397           [true, false].each do |autosetup|
398             [true, false, nil].each do |invited|
399               test "get invited=#{invited}, active=#{active}, admin=#{admin} user from #{if logincluster then "Login" else "peer" end} cluster when AutoSetupNewUsers=#{autosetup} ActivateUsers=#{trusted}" do
400                 Rails.configuration.Login.LoginCluster = 'zbbbb' if logincluster
401                 Rails.configuration.RemoteClusters['zbbbb'].ActivateUsers = trusted
402                 Rails.configuration.Users.AutoSetupNewUsers = autosetup
403                 @stub_content = {
404                   uuid: 'zbbbb-tpzed-000000000000001',
405                   email: 'foo@example.com',
406                   username: 'barney',
407                   is_admin: admin,
408                   is_active: active,
409                   is_invited: invited,
410                 }
411                 get '/arvados/v1/users/current',
412                     params: {format: 'json'},
413                     headers: auth(remote: 'zbbbb')
414                 assert_response :success
415                 assert_equal 'zbbbb-tpzed-000000000000001', json_response['uuid']
416                 assert_equal (logincluster && !!admin && (invited != false) && !!active), json_response['is_admin']
417                 assert_equal ((invited == true || (invited == nil && !!active)) && (logincluster || trusted || autosetup)), json_response['is_invited']
418                 assert_equal ((invited != false) && (logincluster || trusted) && !!active), json_response['is_active']
419                 assert_equal 'foo@example.com', json_response['email']
420                 assert_equal 'barney', json_response['username']
421               end
422             end
423           end
424         end
425       end
426     end
427   end
428
429   test 'get active user from Login cluster when AutoSetupNewUsers is set' do
430     Rails.configuration.Login.LoginCluster = 'zbbbb'
431     Rails.configuration.Users.AutoSetupNewUsers = true
432     @stub_content = {
433       uuid: 'zbbbb-tpzed-000000000000001',
434       email: 'foo@example.com',
435       username: 'barney',
436       is_admin: false,
437       is_active: true,
438       is_invited: true,
439     }
440     get '/arvados/v1/users/current',
441       params: {format: 'json'},
442       headers: auth(remote: 'zbbbb')
443     assert_response :success
444     assert_equal 'zbbbb-tpzed-000000000000001', json_response['uuid']
445     assert_equal false, json_response['is_admin']
446     assert_equal true, json_response['is_active']
447     assert_equal true, json_response['is_invited']
448     assert_equal 'foo@example.com', json_response['email']
449     assert_equal 'barney', json_response['username']
450
451     @stub_content = {
452       uuid: 'zbbbb-tpzed-000000000000001',
453       email: 'foo@example.com',
454       username: 'barney',
455       is_admin: false,
456       is_active: false,
457       is_invited: false,
458     }
459
460     # Use cached value.  User will still be active because we haven't
461     # re-queried the upstream cluster.
462     get '/arvados/v1/users/current',
463       params: {format: 'json'},
464       headers: auth(remote: 'zbbbb')
465     assert_response :success
466     assert_equal 'zbbbb-tpzed-000000000000001', json_response['uuid']
467     assert_equal false, json_response['is_admin']
468     assert_equal true, json_response['is_active']
469     assert_equal true, json_response['is_invited']
470     assert_equal 'foo@example.com', json_response['email']
471     assert_equal 'barney', json_response['username']
472
473     uncache_token('zbbbb')
474     # User should be inactive now.
475     get '/arvados/v1/users/current',
476       params: {format: 'json'},
477       headers: auth(remote: 'zbbbb')
478     assert_response :success
479     assert_equal 'zbbbb-tpzed-000000000000001', json_response['uuid']
480     assert_equal false, json_response['is_admin']
481     assert_equal false, json_response['is_active']
482     assert_equal false, json_response['is_invited']
483     assert_equal 'foo@example.com', json_response['email']
484     assert_equal 'barney', json_response['username']
485
486   end
487
488   test 'pre-activate remote user' do
489     @stub_content = {
490       uuid: 'zbbbb-tpzed-000000000001234',
491       email: 'foo@example.com',
492       username: 'barney',
493       is_admin: true,
494       is_active: true,
495       is_invited: true,
496     }
497
498     post '/arvados/v1/users',
499       params: {
500         "user" => {
501           "uuid" => "zbbbb-tpzed-000000000001234",
502           "email" => 'foo@example.com',
503           "username" => 'barney',
504           "is_active" => true,
505           "is_admin" => false
506         }
507       },
508       headers: {'HTTP_AUTHORIZATION' => "OAuth2 #{api_token(:admin)}"}
509     assert_response :success
510
511     get '/arvados/v1/users/current',
512       params: {format: 'json'},
513       headers: auth(remote: 'zbbbb')
514     assert_response :success
515     assert_equal 'zbbbb-tpzed-000000000001234', json_response['uuid']
516     assert_equal false, json_response['is_admin']
517     assert_equal true, json_response['is_active']
518     assert_equal 'foo@example.com', json_response['email']
519     assert_equal 'barney', json_response['username']
520   end
521
522
523   test 'remote user inactive without pre-activation' do
524     @stub_content = {
525       uuid: 'zbbbb-tpzed-000000000001234',
526       email: 'foo@example.com',
527       username: 'barney',
528       is_admin: true,
529       is_active: true,
530       is_invited: true,
531     }
532
533     get '/arvados/v1/users/current',
534       params: {format: 'json'},
535       headers: auth(remote: 'zbbbb')
536     assert_response :success
537     assert_equal 'zbbbb-tpzed-000000000001234', json_response['uuid']
538     assert_equal false, json_response['is_admin']
539     assert_equal false, json_response['is_active']
540     assert_equal 'foo@example.com', json_response['email']
541     assert_equal 'barney', json_response['username']
542   end
543
544   test "validate unsalted v2 token for remote cluster zbbbb" do
545     auth = api_client_authorizations(:active)
546     token = "v2/#{auth.uuid}/#{auth.api_token}"
547     get '/arvados/v1/users/current',
548       params: {format: 'json', remote: 'zbbbb'},
549       headers: {"HTTP_AUTHORIZATION" => "Bearer #{token}"}
550     assert_response :success
551     assert_equal(users(:active).uuid, json_response['uuid'])
552   end
553
554   test 'container request with runtime_token' do
555     [["valid local", "v2/#{api_client_authorizations(:active).uuid}/#{api_client_authorizations(:active).api_token}"],
556      ["valid remote", "v2/zbbbb-gj3su-000000000000000/abc"],
557      ["invalid local", "v2/#{api_client_authorizations(:active).uuid}/fakefakefake"],
558      ["invalid remote", "v2/zbork-gj3su-000000000000000/abc"],
559     ].each do |label, runtime_token|
560       post '/arvados/v1/container_requests',
561         params: {
562           "container_request" => {
563             "command" => ["echo"],
564             "container_image" => "xyz",
565             "output_path" => "/",
566             "cwd" => "/",
567             "runtime_token" => runtime_token
568           }
569         },
570         headers: {"HTTP_AUTHORIZATION" => "Bearer #{api_client_authorizations(:active).api_token}"}
571       if label.include? "invalid"
572         assert_response 422
573       else
574         assert_response :success
575       end
576     end
577   end
578
579   test 'authenticate with remote token, remote user is system user' do
580     @stub_content[:uuid] = 'zbbbb-tpzed-000000000000000'
581     get '/arvados/v1/users/current',
582       params: {format: 'json'},
583       headers: auth(remote: 'zbbbb')
584     assert_equal 'from cluster zbbbb', json_response['last_name']
585   end
586
587   test 'authenticate with remote token, remote user is anonymous user' do
588     @stub_content[:uuid] = 'zbbbb-tpzed-anonymouspublic'
589     get '/arvados/v1/users/current',
590       params: {format: 'json'},
591       headers: auth(remote: 'zbbbb')
592     assert_response :success
593     assert_equal 'zzzzz-tpzed-anonymouspublic', json_response['uuid']
594   end
595
596   [401, 403, 422, 500, 502, 503].each do |status|
597     test "propagate #{status} response from getting remote token" do
598       @stub_token_status = status
599       get "/arvados/v1/users/#{@stub_content[:uuid]}",
600           params: {format: "json"},
601           headers: auth(remote: "zbbbb")
602       assert_response status
603     end
604
605     test "propagate #{status} response from getting uncached user" do
606       @stub_status = status
607       get "/arvados/v1/users/#{@stub_content[:uuid]}",
608           params: {format: "json"},
609           headers: auth(remote: "zbbbb")
610       assert_response status
611     end
612
613     test "use cached user after getting #{status} response" do
614       url_path = "/arvados/v1/users/#{@stub_content[:uuid]}"
615       params = {format: "json"}
616       headers = auth(remote: "zbbbb")
617
618       get url_path, params: params, headers: headers
619       assert_response :success
620
621       uncache_token(headers["HTTP_AUTHORIZATION"])
622       expect_email = @stub_content[:email]
623       @stub_content[:email] = "new#{expect_email}"
624       @stub_status = status
625       get url_path, params: params, headers: headers
626       assert_response :success
627       user = User.find_by_uuid(@stub_content[:uuid])
628       assert_not_nil user
629       assert_equal expect_email, user.email
630     end
631   end
632 end