11453: Fix & test remote token caching.
[arvados.git] / services / api / test / integration / remote_user_test.rb
index a7a789907739fbdd2bec21badd31842b93247502..6b49d31555acf69fbc8be0aa470033e1b1f9576e 100644 (file)
@@ -8,13 +8,29 @@ require 'test_helper'
 require 'helpers/users_test_helper'
 
 class RemoteUsersTest < ActionDispatch::IntegrationTest
+  include DbCurrentTime
+
+  def salted_active_token(remote:)
+    salt_token(fixture: :active, remote: remote).sub('/zzzzz-', '/'+remote+'-')
+  end
+
   def auth(remote:)
-    token = salt_token(fixture: :active, remote: remote)
-    token.sub!('/zzzzz-', '/'+remote+'-')
+    token = salted_active_token(remote: remote)
     {"HTTP_AUTHORIZATION" => "Bearer #{token}"}
   end
 
+  # For remote authentication tests, we bring up a simple stub server
+  # (on a port chosen by webrick) and configure the SUT so the stub is
+  # responsible for clusters "zbbbb" (a well-behaved cluster) and
+  # "zbork" (a misbehaving cluster).
+  #
+  # Test cases can override the stub's default response to
+  # .../users/current by changing @stub_status and @stub_content.
   setup do
+    clnt = HTTPClient.new
+    clnt.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
+    HTTPClient.stubs(:new).returns clnt
+
     @controller = Arvados::V1::UsersController.new
     ready = Thread::Queue.new
     srv = WEBrick::HTTPServer.new(
@@ -48,7 +64,7 @@ class RemoteUsersTest < ActionDispatch::IntegrationTest
     @remote_server = srv
     @remote_host = "127.0.0.1:#{srv.config[:Port]}"
     Rails.configuration.remote_hosts['zbbbb'] = @remote_host
-    Rails.configuration.remote_hosts['zcccc'] = @remote_host
+    Rails.configuration.remote_hosts['zbork'] = @remote_host
     Arvados::V1::SchemaController.any_instance.stubs(:root_url).returns "https://#{@remote_host}"
     @stub_status = 200
     @stub_content = {
@@ -63,15 +79,31 @@ class RemoteUsersTest < ActionDispatch::IntegrationTest
   end
 
   test 'authenticate with remote token' do
-    get '/arvados/v1/users/current', {}, auth(remote: 'zbbbb')
+    get '/arvados/v1/users/current', {format: 'json'}, auth(remote: 'zbbbb')
     assert_response :success
     assert_equal 'zbbbb-tpzed-000000000000000', json_response['uuid']
     assert_equal false, json_response['is_admin']
+
+    # revoke original token
+    @stub_status = 401
+    @stub_content = {error: 'not authorized'}
+
+    # re-authorize before cache expires
+    get '/arvados/v1/users/current', {format: 'json'}, auth(remote: 'zbbbb')
+    assert_response :success
+
+    # simulate cache expiry
+    ApiClientAuthorization.where(
+      uuid: salted_active_token(remote: 'zbbbb').split('/')[1]).
+      update_all(expires_at: db_current_time - 1.minute)
+
+    # re-authorize after cache expires
+    get '/arvados/v1/users/current', {format: 'json'}, auth(remote: 'zbbbb')
+    assert_response 401
   end
 
-  test 'authenticate with remote token from wrong site' do
-    @stub_content[:uuid] = 'zcccc-tpzed-000000000000000'
-    get '/arvados/v1/users/current', {}, auth(remote: 'zbbbb')
+  test 'authenticate with remote token from misbhehaving remote cluster' do
+    get '/arvados/v1/users/current', {format: 'json'}, auth(remote: 'zbork')
     assert_response 401
   end
 
@@ -80,14 +112,14 @@ class RemoteUsersTest < ActionDispatch::IntegrationTest
     @stub_content = {
       error: 'not authorized',
     }
-    get '/arvados/v1/users/current', {}, auth(remote: 'zbbbb')
+    get '/arvados/v1/users/current', {format: 'json'}, auth(remote: 'zbbbb')
     assert_response 401
   end
 
   test 'remote api server is not an api server' do
     @stub_status = 200
     @stub_content = '<html>bad</html>'
-    get '/arvados/v1/users/current', {}, auth(remote: 'zbbbb')
+    get '/arvados/v1/users/current', {format: 'json'}, auth(remote: 'zbbbb')
     assert_response 401
   end
 
@@ -105,4 +137,19 @@ class RemoteUsersTest < ActionDispatch::IntegrationTest
       end
     end
   end
+
+  test "list readable groups with salted token" do
+    salted_token = salt_token(fixture: :active, remote: 'zbbbb')
+    get '/arvados/v1/groups', {
+          format: 'json',
+          remote: 'zbbbb',
+          limit: 10000,
+        }, {
+          "HTTP_AUTHORIZATION" => "Bearer #{salted_token}"
+        }
+    assert_response 200
+    group_uuids = json_response['items'].collect { |i| i['uuid'] }
+    assert_includes(group_uuids, 'zzzzz-j7d0g-fffffffffffffff')
+    refute_includes(group_uuids, 'zzzzz-j7d0g-000000000000000')
+  end
 end