Skip to content

Commit 3040e08

Browse files
authored
Support both, encoded and non encoded api-key formats on plugin configuration (#1223)
* Support both, encoded and non encoded api-key formats on plugin configuration * Changed encoded value detection by safer method * Refactored HttpClientBuilder module to have proper private methods
1 parent 7618e9b commit 3040e08

File tree

3 files changed

+67
-14
lines changed

3 files changed

+67
-14
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 12.0.7
2+
- Support both, encoded and non encoded api-key formats on plugin configuration [#1223](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1223)
3+
14
## 12.0.6
25
- Add headers reporting uncompressed size and doc count for bulk requests [#1217](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1217)
36

lib/logstash/outputs/elasticsearch/http_client_builder.rb

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -188,25 +188,37 @@ def self.setup_basic_auth(logger, params)
188188
def self.setup_api_key(logger, params)
189189
api_key = params["api_key"]
190190

191-
return {} unless (api_key && api_key.value)
191+
return {} unless (api_key&.value)
192192

193-
{ "Authorization" => "ApiKey " + Base64.strict_encode64(api_key.value) }
194-
end
193+
value = is_base64?(api_key.value) ? api_key.value : Base64.strict_encode64(api_key.value)
195194

196-
private
197-
def self.dedup_slashes(url)
198-
url.gsub(/\/+/, "/")
195+
{ "Authorization" => "ApiKey #{value}" }
199196
end
200197

201-
# Set a `filter_path` query parameter if it is not already set to be
202-
# `filter_path=errors,items.*.error,items.*.status` to reduce the payload between Logstash and Elasticsearch
203-
def self.resolve_filter_path(url)
204-
return url if url.match?(/(?:[&|?])filter_path=/)
205-
("#{url}#{query_param_separator(url)}filter_path=errors,items.*.error,items.*.status")
206-
end
198+
class << self
199+
private
200+
def dedup_slashes(url)
201+
url.gsub(/\/+/, "/")
202+
end
203+
204+
# Set a `filter_path` query parameter if it is not already set to be
205+
# `filter_path=errors,items.*.error,items.*.status` to reduce the payload between Logstash and Elasticsearch
206+
def resolve_filter_path(url)
207+
return url if url.match?(/(?:[&|?])filter_path=/)
208+
("#{url}#{query_param_separator(url)}filter_path=errors,items.*.error,items.*.status")
209+
end
207210

208-
def self.query_param_separator(url)
209-
url.match?(/\?[^\s#]+/) ? '&' : '?'
211+
def query_param_separator(url)
212+
url.match?(/\?[^\s#]+/) ? '&' : '?'
213+
end
214+
215+
def is_base64?(string)
216+
begin
217+
string == Base64.strict_encode64(Base64.strict_decode64(string))
218+
rescue ArgumentError
219+
false
220+
end
221+
end
210222
end
211223
end
212224
end; end; end

spec/unit/http_client_builder_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,44 @@
2626
end
2727
end
2828

29+
describe "auth setup with api-key" do
30+
let(:klass) { LogStash::Outputs::ElasticSearch::HttpClientBuilder }
31+
32+
context "when api-key is not encoded (id:api-key)" do
33+
let(:api_key) { "id:api-key" }
34+
let(:api_key_secured) do
35+
secured = double("api_key")
36+
allow(secured).to receive(:value).and_return(api_key)
37+
secured
38+
end
39+
let(:options) { { "api_key" => api_key_secured } }
40+
let(:logger) { double("logger") }
41+
let(:api_key_header) { klass.setup_api_key(logger, options) }
42+
43+
it "returns the correct encoded api-key header" do
44+
expected = "ApiKey #{Base64.strict_encode64(api_key)}"
45+
expect(api_key_header["Authorization"]).to eql(expected)
46+
end
47+
end
48+
49+
context "when api-key is already encoded" do
50+
let(:api_key) { Base64.strict_encode64("id:api-key") }
51+
let(:api_key_secured) do
52+
secured = double("api_key")
53+
allow(secured).to receive(:value).and_return(api_key)
54+
secured
55+
end
56+
let(:options) { { "api_key" => api_key_secured } }
57+
let(:logger) { double("logger") }
58+
let(:api_key_header) { klass.setup_api_key(logger, options) }
59+
60+
it "returns the api-key header as is" do
61+
expected = "ApiKey #{api_key}"
62+
expect(api_key_header["Authorization"]).to eql(expected)
63+
end
64+
end
65+
end
66+
2967
describe "customizing action paths" do
3068
let(:hosts) { [ ::LogStash::Util::SafeURI.new("http://localhost:9200") ] }
3169
let(:options) { {"hosts" => hosts } }

0 commit comments

Comments
 (0)