X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/5881feb407af2d4e5785ad57232cc3bfd12b86ec..74fec3cd8284eae4829dad2c287588d52c621c4b:/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 ca09aa719d..2abcf49e57 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| @@ -121,7 +130,7 @@ class ArvadosApiClient elsif v == false query[k] = 0 else - query[k] = JSON.dump(v) + query[k] = Oj.dump(v, mode: :compat) end end else @@ -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,25 +235,45 @@ 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') + if Rails.configuration.testing_override_login_url + uri = URI(Rails.configuration.testing_override_login_url) + uri.path = "/login" + uri.query = URI.encode_www_form(params) + return uri.to_s end - if params.size > 0 - uri += '?' << params.collect { |k,v| - CGI.escape(k.to_s) + '=' + CGI.escape(v.to_s) - }.join('&') + + case + when Rails.configuration.Login.PAM.Enable, + Rails.configuration.Login.LDAP.Enable, + Rails.configuration.Login.Test.Enable + + uri = URI.parse(Rails.configuration.Services.Workbench1.ExternalURL.to_s) + uri.path = "/users/welcome" + uri.query = URI.encode_www_form(params) + else + uri = URI.parse(Rails.configuration.Services.Controller.ExternalURL.to_s) + uri.path = "/login" + uri.query = URI.encode_www_form(params) end - uri + uri.to_s end def arvados_logout_url(params={}) - arvados_login_url(params).sub('/login','/logout') + 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.path = "/logout" + uri.query = URI.encode_www_form(params) + uri.to_s 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