X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/1a98070dcdd379ab6effdc3fc4301c9435a137b1..42c20b25e1325124b88e3b9b285544dc41122b56:/apps/workbench/app/models/arvados_api_client.rb diff --git a/apps/workbench/app/models/arvados_api_client.rb b/apps/workbench/app/models/arvados_api_client.rb index 4d549d1947..47fcc4ce51 100644 --- a/apps/workbench/app/models/arvados_api_client.rb +++ b/apps/workbench/app/models/arvados_api_client.rb @@ -1,3 +1,7 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + require 'httpclient' require 'thread' @@ -36,7 +40,7 @@ class ArvadosApiClient def initialize(request_url, api_response) @api_status = api_response.status_code @api_response_s = api_response.content - @api_response = Oj.load(@api_response_s, :symbol_keys => true) + @api_response = Oj.strict_load(@api_response_s, :symbol_keys => true) errors = @api_response[:errors] if errors.respond_to?(:join) errors = errors.join("\n\n") @@ -57,7 +61,7 @@ class ArvadosApiClient 404 => NotFoundException, } - @@profiling_enabled = Rails.configuration.profiling_enabled + @@profiling_enabled = Rails.configuration.Workbench.ProfilingEnabled @@discovery = nil # An API client object suitable for handling API requests on behalf @@ -78,20 +82,26 @@ class ArvadosApiClient @client_mtx = Mutex.new end - def api(resources_kind, action, data=nil, tokens={}) + def api(resources_kind, action, data=nil, tokens={}, include_anon_token=true) profile_checkpoint if not @api_client @client_mtx.synchronize do @api_client = HTTPClient.new - if Rails.configuration.arvados_insecure_https + @api_client.ssl_config.timeout = Rails.configuration.Workbench.APIClientConnectTimeout + @api_client.connect_timeout = Rails.configuration.Workbench.APIClientConnectTimeout + @api_client.receive_timeout = Rails.configuration.Workbench.APIClientReceiveTimeout + if Rails.configuration.TLS.Insecure @api_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE else # Use system CA certificates - @api_client.ssl_config.add_trust_ca('/etc/ssl/certs') + ["/etc/ssl/certs/ca-certificates.crt", + "/etc/pki/tls/certs/ca-bundle.crt"] + .select { |ca_path| File.readable?(ca_path) } + .each { |ca_path| @api_client.ssl_config.add_trust_ca(ca_path) } end - if Rails.configuration.api_response_compression + if Rails.configuration.Workbench.APIResponseCompression @api_client.transparent_gzip_decompression = true end end @@ -103,14 +113,13 @@ class ArvadosApiClient # Clean up /arvados/v1/../../discovery/v1 to /discovery/v1 url.sub! '/arvados/v1/../../', '/' + anon_tokens = [Rails.configuration.Users.AnonymousUserToken].select { |x| !x.empty? && include_anon_token } + query = { - 'api_token' => (tokens[:arvados_api_token] || - Thread.current[:arvados_api_token] || - ''), 'reader_tokens' => ((tokens[:reader_tokens] || Thread.current[:reader_tokens] || []) + - [Rails.configuration.anonymous_user_token]).to_json, + anon_tokens).to_json, } if !data.nil? data.each do |k,v| @@ -132,12 +141,19 @@ class ArvadosApiClient query["_profile"] = "true" end - header = {"Accept" => "application/json"} + headers = { + "Accept" => "application/json", + "Authorization" => "OAuth2 " + + (tokens[:arvados_api_token] || + Thread.current[:arvados_api_token] || + ''), + "X-Request-Id" => Thread.current[:request_id] || '', + } profile_checkpoint { "Prepare request #{query["_method"] or "POST"} #{url} #{query[:uuid]} #{query.inspect[0,256]}" } msg = @client_mtx.synchronize do begin - @api_client.post(url, query, header: header) + @api_client.post(url, query, headers) rescue => exception raise NoApiResponseException.new(url, exception) end @@ -151,7 +167,7 @@ class ArvadosApiClient end begin - resp = Oj.load(msg.content, :symbol_keys => true) + resp = Oj.strict_load(msg.content, :symbol_keys => true) rescue Oj::ParseError resp = nil end @@ -219,17 +235,13 @@ class ArvadosApiClient end def arvados_login_url(params={}) - if Rails.configuration.respond_to? :arvados_login_base - uri = Rails.configuration.arvados_login_base - else - uri = self.arvados_v1_base.sub(%r{/arvados/v\d+.*}, '/login') - end - if params.size > 0 - uri += '?' << params.collect { |k,v| - CGI.escape(k.to_s) + '=' + CGI.escape(v.to_s) - }.join('&') + uri = URI.parse(Rails.configuration.Services.Controller.ExternalURL.to_s) + if Rails.configuration.testing_override_login_url + uri = URI(Rails.configuration.testing_override_login_url) end - uri + uri.path = "/login" + uri.query = URI.encode_www_form(params) + uri.to_s end def arvados_logout_url(params={}) @@ -237,7 +249,11 @@ class ArvadosApiClient end def arvados_v1_base - Rails.configuration.arvados_v1_base + # workaround Ruby 2.3 bug, can't duplicate URI objects + # https://github.com/httprb/http/issues/388 + u = URI.parse(Rails.configuration.Services.Controller.ExternalURL.to_s) + u.path = "/arvados/v1" + u.to_s end def discovery