[ARVADOS] updated: 1.1.0-44-g8424b5e

Git user git at public.curoverse.com
Fri Oct 20 11:30:08 EDT 2017


Summary of changes:
 .../api/app/controllers/application_controller.rb  |  4 +-
 .../api/app/models/api_client_authorization.rb     | 47 ++++++-----
 .../arvados/v1/groups_controller_test.rb           |  4 +-
 .../functional/arvados/v1/users_controller_test.rb |  4 +-
 .../test/functional/remote_user_account_test.rb    | 97 ++++++++++++++++++++++
 services/api/test/test_helper.rb                   |  4 +-
 6 files changed, 132 insertions(+), 28 deletions(-)
 create mode 100644 services/api/test/functional/remote_user_account_test.rb

       via  8424b5ef401ef05a8ca7bd0d6b4e635b7c0a8706 (commit)
       via  ef82b6ac04d9c813f2e9114c267559c6f30cb3b6 (commit)
      from  b5097189362f4cb1fb96d6993d570500a7e227ae (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 8424b5ef401ef05a8ca7bd0d6b4e635b7c0a8706
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Fri Oct 20 09:17:11 2017 -0400

    11453: Add remote authentication test.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/services/api/app/models/api_client_authorization.rb b/services/api/app/models/api_client_authorization.rb
index 29c5ef7..6ab8abd 100644
--- a/services/api/app/models/api_client_authorization.rb
+++ b/services/api/app/models/api_client_authorization.rb
@@ -110,27 +110,34 @@ class ApiClientAuthorization < ArvadosModel
         # [re]validate it.
         arv = Arvados.new(api_host: remote_host(uuid: uuid),
                           api_token: token)
-        remote_user = arv.user.current(remote: Rails.configuration.uuid_prefix)
-        if remote_user && remote_user[:uuid][0..4] == uuid[0..4]
-          act_as_system_user do
-            # Add/update user and token in our database so we can
-            # validate subsequent requests faster.
-            user = User.find_or_create_by(uuid: remote_user[:uuid])
-            user.update_attributes!(remote_user)
-            auth = ApiClientAuthorization.
-                   includes(:user).
-                   find_or_create_by(uuid: uuid,
-                                     api_token: token,
-                                     user: user,
-                                     api_client_id: 0)
-            # Accept this token (and don't reload the user record) for
-            # 5 minutes. TODO: Request the actual api_client_auth
-            # record from the remote server in case it wants the token
-            # to expire sooner.
-            auth.update_attributes!(expires_at: Time.now + 5.minutes)
-          end
-          return auth
+        begin
+          remote_user = arv.user.current(remote: Rails.configuration.uuid_prefix)
+        rescue => e
+          logger.warn "remote authentication with token #{token.inspect} failed: #{e}"
+          return nil
         end
+        if !remote_user.is_a?(Hash) || !remote_user[:uuid].is_a?(String) || remote_user[:uuid][0..4] != uuid[0..4]
+          logger.warn "remote authentication rejected: remote_user=#{remote_user.inspect}"
+          return nil
+        end
+        act_as_system_user do
+          # Add/update user and token in our database so we can
+          # validate subsequent requests faster.
+          user = User.find_or_create_by(uuid: remote_user[:uuid])
+          user.update_attributes!(remote_user.merge(is_admin: false))
+          auth = ApiClientAuthorization.
+                 includes(:user).
+                 find_or_create_by(uuid: uuid,
+                                   api_token: token,
+                                   user: user,
+                                   api_client_id: 0)
+          # Accept this token (and don't reload the user record) for
+          # 5 minutes. TODO: Request the actual api_client_auth
+          # record from the remote server in case it wants the token
+          # to expire sooner.
+          auth.update_attributes!(expires_at: Time.now + 5.minutes)
+        end
+        return auth
       end
     else
       auth = ApiClientAuthorization.
diff --git a/services/api/test/functional/remote_user_account_test.rb b/services/api/test/functional/remote_user_account_test.rb
new file mode 100644
index 0000000..8b07be5
--- /dev/null
+++ b/services/api/test/functional/remote_user_account_test.rb
@@ -0,0 +1,97 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+require 'webrick'
+require 'webrick/https'
+require 'test_helper'
+
+class RemoteUserAccountTest < ActionController::TestCase
+  def auth(remote:)
+    token = salt_token(fixture: :active, remote: remote)
+    token.sub!('/zzzzz-', '/'+remote+'-')
+    ArvadosApiToken.new.call("rack.input" => "",
+                             "HTTP_AUTHORIZATION" => "Bearer #{token}")
+  end
+
+  setup do
+    @controller = Arvados::V1::UsersController.new
+    ready = Thread::Queue.new
+    srv = WEBrick::HTTPServer.new(
+      Port: 0,
+      Logger: WEBrick::Log.new(
+        Rails.root.join("log", "webrick.log").to_s,
+        WEBrick::Log::INFO),
+      AccessLog: [[File.open(Rails.root.join(
+                              "log", "webrick_access.log").to_s, 'a+'),
+                   WEBrick::AccessLog::COMBINED_LOG_FORMAT]],
+      SSLEnable: true,
+      SSLVerifyClient: OpenSSL::SSL::VERIFY_NONE,
+      SSLPrivateKey: OpenSSL::PKey::RSA.new(
+        File.open("self-signed.key").read),
+      SSLCertificate: OpenSSL::X509::Certificate.new(
+        File.open("self-signed.pem").read),
+      SSLCertName: [["CN", WEBrick::Utils::getservername]],
+      StartCallback: lambda { ready.push(true) })
+    srv.mount_proc '/discovery/v1/apis/arvados/v1/rest' do |req, res|
+      Rails.cache.delete 'arvados_v1_rest_discovery'
+      res.body = Arvados::V1::SchemaController.new.send(:discovery_doc).to_json
+    end
+    srv.mount_proc '/arvados/v1/users/current' do |req, res|
+      res.status = @stub_status
+      res.body = @stub_content.is_a?(String) ? @stub_content : @stub_content.to_json
+    end
+    Thread.new do
+      srv.start
+    end
+    ready.pop
+    @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
+    Arvados::V1::SchemaController.any_instance.stubs(:root_url).returns "https://#{@remote_host}"
+    @stub_status = 200
+    @stub_content = {
+      uuid: 'zbbbb-tpzed-000000000000000',
+      is_admin: true,
+      is_active: true,
+    }
+  end
+
+  teardown do
+    @remote_server.stop
+  end
+
+  test 'authenticate with remote token' do
+    auth(remote: 'zbbbb')
+    get :current
+    assert_response :success
+    assert_equal 'zbbbb-tpzed-000000000000000', json_response['uuid']
+    assert_equal false, json_response['is_admin']
+  end
+
+  test 'authenticate with remote token from wrong site' do
+    @stub_content[:uuid] = 'zcccc-tpzed-000000000000000'
+    auth(remote: 'zbbbb')
+    get :current
+    assert_response 401
+  end
+
+  test 'authenticate with remote token that fails validate' do
+    @stub_status = 401
+    @stub_content = {
+      error: 'not authorized',
+    }
+    auth(remote: 'zbbbb')
+    get :current
+    assert_response 401
+  end
+
+  test 'remote api server is not an api server' do
+    @stub_status = 401
+    @stub_content = '<html>bad</html>'
+    auth(remote: 'zbbbb')
+    get :current
+    assert_response 401
+  end
+end

commit ef82b6ac04d9c813f2e9114c267559c6f30cb3b6
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Fri Oct 20 09:07:05 2017 -0400

    11453: Rename param from "remote_id" to "remote".
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/services/api/app/controllers/application_controller.rb b/services/api/app/controllers/application_controller.rb
index 57a187a..07afdfb 100644
--- a/services/api/app/controllers/application_controller.rb
+++ b/services/api/app/controllers/application_controller.rb
@@ -346,12 +346,12 @@ class ApplicationController < ActionController::Base
     @read_auths.select! { |auth| auth.scopes_allow_request? request }
 
     # Use a salted token as a reader token for /groups/ and /users/current
-    if params[:remote_id] && (
+    if params[:remote] && (
          request.path.start_with?('/arvados/v1/groups') ||
          request.path.start_with?('/arvados/v1/users/current'))
       auth = ApiClientAuthorization.
              validate(token: Thread.current[:supplied_token],
-                      remote: params[:remote_id])
+                      remote: params[:remote])
       if auth && auth.user
         Thread.current[:user] = auth.user
         @read_auths << auth
diff --git a/services/api/app/models/api_client_authorization.rb b/services/api/app/models/api_client_authorization.rb
index e7903d4..29c5ef7 100644
--- a/services/api/app/models/api_client_authorization.rb
+++ b/services/api/app/models/api_client_authorization.rb
@@ -110,7 +110,7 @@ class ApiClientAuthorization < ArvadosModel
         # [re]validate it.
         arv = Arvados.new(api_host: remote_host(uuid: uuid),
                           api_token: token)
-        remote_user = arv.user.current(remote_id: Rails.configuration.uuid_prefix)
+        remote_user = arv.user.current(remote: Rails.configuration.uuid_prefix)
         if remote_user && remote_user[:uuid][0..4] == uuid[0..4]
           act_as_system_user do
             # Add/update user and token in our database so we can
diff --git a/services/api/test/functional/arvados/v1/groups_controller_test.rb b/services/api/test/functional/arvados/v1/groups_controller_test.rb
index 0fa8430..6027dcb 100644
--- a/services/api/test/functional/arvados/v1/groups_controller_test.rb
+++ b/services/api/test/functional/arvados/v1/groups_controller_test.rb
@@ -708,10 +708,10 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase
   end
 
   test "list readable groups with salted token" do
-    salted_token = salt_token(fixture: :active, remote_id: 'zbbbb')
+    salted_token = salt_token(fixture: :active, remote: 'zbbbb')
     ArvadosApiToken.new.call("rack.input" => "",
                              "HTTP_AUTHORIZATION" => "Bearer #{salted_token}")
-    get :index, {remote_id: 'zbbbb', limit: 10000}
+    get :index, {remote: 'zbbbb', limit: 10000}
     assert_response 200
     group_uuids = json_response['items'].collect { |i| i['uuid'] }
     assert_includes(group_uuids, 'zzzzz-j7d0g-fffffffffffffff')
diff --git a/services/api/test/functional/arvados/v1/users_controller_test.rb b/services/api/test/functional/arvados/v1/users_controller_test.rb
index 646b96c..b89145b 100644
--- a/services/api/test/functional/arvados/v1/users_controller_test.rb
+++ b/services/api/test/functional/arvados/v1/users_controller_test.rb
@@ -873,10 +873,10 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
 
   ['zbbbb', 'z0000'].each do |token_valid_for|
     test "validate #{token_valid_for}-salted token for remote cluster zbbbb" do
-      salted_token = salt_token(fixture: :active, remote_id: token_valid_for)
+      salted_token = salt_token(fixture: :active, remote: token_valid_for)
       ArvadosApiToken.new.call("rack.input" => "",
                                "HTTP_AUTHORIZATION" => "Bearer #{salted_token}")
-      get :current, {remote_id: 'zbbbb'}
+      get :current, {remote: 'zbbbb'}
       if token_valid_for == 'zbbbb'
         assert_equal(users(:active).uuid, json_response['uuid'])
         assert_response 200
diff --git a/services/api/test/test_helper.rb b/services/api/test/test_helper.rb
index e1f7542..c834250 100644
--- a/services/api/test/test_helper.rb
+++ b/services/api/test/test_helper.rb
@@ -127,11 +127,11 @@ class ActiveSupport::TestCase
                              "HTTP_AUTHORIZATION" => "OAuth2 #{t}")
   end
 
-  def salt_token(fixture:, remote_id:)
+  def salt_token(fixture:, remote:)
     auth = api_client_authorizations(fixture)
     uuid = auth.uuid
     token = auth.api_token
-    hmac = OpenSSL::HMAC.hexdigest('sha1', token, remote_id)
+    hmac = OpenSSL::HMAC.hexdigest('sha1', token, remote)
     return "v2/#{uuid}/#{hmac}"
   end
 

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list