From 9a7bc193e4b138355032258a6ec2878c7d0a3a3f Mon Sep 17 00:00:00 2001 From: Fernando Briano Date: Fri, 28 Oct 2022 10:33:02 +0100 Subject: [PATCH] [GEM] Fixes bug instantiating client with api_key and transport_options When passing in `api_key` and `transport_options` that don't include headers to the client, the api_key code would overwrite the arguments passed in for `transport_options`. This code fixes this, checking if there are transport options and merging the auth headers with that instead. Fixes #1940 --- elasticsearch/lib/elasticsearch.rb | 5 ++-- elasticsearch/spec/unit/api_key_spec.rb | 38 ++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/elasticsearch/lib/elasticsearch.rb b/elasticsearch/lib/elasticsearch.rb index 53684be342..98f2895a3a 100644 --- a/elasticsearch/lib/elasticsearch.rb +++ b/elasticsearch/lib/elasticsearch.rb @@ -144,9 +144,8 @@ def api_key(arguments) if (headers = arguments.dig(:transport_options, :headers)) headers.merge!(authorization) else - arguments[:transport_options] = { - headers: authorization - } + arguments[:transport_options] ||= {} + arguments[:transport_options].merge!({ headers: authorization }) end end diff --git a/elasticsearch/spec/unit/api_key_spec.rb b/elasticsearch/spec/unit/api_key_spec.rb index 2c26d1fb2e..cc43f65604 100644 --- a/elasticsearch/spec/unit/api_key_spec.rb +++ b/elasticsearch/spec/unit/api_key_spec.rb @@ -57,7 +57,7 @@ end end - context 'when other headers where specified' do + context 'when other headers were specified' do let(:client) do described_class.new( api_key: 'elasticsearch_api_key', @@ -72,6 +72,42 @@ end end + context 'when sending transport_options but no headers were specified' do + let(:client) do + described_class.new( + api_key: 'elasticsearch_api_key', + transport_options: { ssl: { verify: false } } + ) + end + + it 'Adds the ApiKey header to the connection and keeps the options' do + header = client.transport.connections.first.connection.headers + expect(header['Authorization']).to eq('ApiKey elasticsearch_api_key') + expect(client.transport.options[:transport_options]).to include({ ssl: { verify: false } }) + expect(client.transport.options[:transport_options][:headers]).to include('Authorization' => 'ApiKey elasticsearch_api_key') + end + end + + context 'when other headers and options were specified' do + let(:client) do + described_class.new( + api_key: 'elasticsearch_api_key', + transport_options: { + headers: { 'x-test-header' => 'test' }, + ssl: { verify: false } + } + ) + end + + it 'Adds the ApiKey header to the connection and keeps the header' do + header = client.transport.connections.first.connection.headers + expect(header['X-Test-Header']).to eq('test') + expect(header['Authorization']).to eq('ApiKey elasticsearch_api_key') + expect(client.transport.options[:transport_options]).to include({ ssl: { verify: false } }) + expect(client.transport.options[:transport_options][:headers]).to include('Authorization' => 'ApiKey elasticsearch_api_key') + end + end + context 'Metaheader' do let(:adapter_code) { "nh=#{defined?(Net::HTTP::VERSION) ? Net::HTTP::VERSION : Net::HTTP::HTTPVersion}" } let(:meta_header) do