mirror of
https://github.com/elastic/logstash.git
synced 2025-04-25 07:07:54 -04:00
144 lines
5.6 KiB
Ruby
144 lines
5.6 KiB
Ruby
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
# license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright
|
|
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
# the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
require 'openssl'
|
|
|
|
require 'logstash/util'
|
|
require 'logstash/webserver'
|
|
require "stud/try"
|
|
require "manticore"
|
|
|
|
describe 'api webserver' do
|
|
let!(:logger) { double("Logger").as_null_object }
|
|
let!(:agent) { double("Agent").as_null_object }
|
|
subject(:webserver) { LogStash::WebServer.new(logger, agent, webserver_options) }
|
|
|
|
let(:webserver_options) { Hash.new }
|
|
|
|
# provide a shared context to take care of ensuring that the webserver
|
|
# is running during the spec runs of examples in the including context
|
|
shared_context 'running webserver' do
|
|
let(:webserver) { defined?(super()) ? super() : fail("included context requires `webserver` to be present") }
|
|
|
|
# since we are running the webserver on another
|
|
# thread, ensure that a crash doesn't go unnoticed.
|
|
around(:each) do |example|
|
|
abort = Thread.abort_on_exception
|
|
example.call
|
|
Thread.abort_on_exception = abort
|
|
end
|
|
|
|
# If webmock is active, allow real network connections
|
|
before(:each) { WebMock.allow_net_connect! if defined?(WebMock) }
|
|
|
|
# ensure our API webserver is running with the provided config
|
|
# before running our specs that validate responses
|
|
let!(:webserver_thread) { Thread.new(webserver, &:run) }
|
|
before(:each) do
|
|
Stud.try(10.times) { fail('API WebServer not running yet...') unless webserver.port }
|
|
end
|
|
after(:each) do
|
|
webserver.stop
|
|
webserver_thread.join
|
|
end
|
|
end
|
|
|
|
context "when configured with api.ssl.supported_protocols" do
|
|
let(:ca_file) { File.join(certs_path, "root.crt") }
|
|
let(:certs_path) { File.expand_path("../../fixtures/webserver_certs/generated", __FILE__) }
|
|
let(:keystore_path) { File.join(certs_path, "server_from_root.p12") }
|
|
let(:keystore_password) { "12345678" }
|
|
let(:supported_protocols) { %w[TLSv1.3] }
|
|
let(:ssl_params) { {:supported_protocols => supported_protocols, :keystore_path => keystore_path, :keystore_password => LogStash::Util::Password.new(keystore_password)} }
|
|
let(:webserver_options) { super().merge(:ssl_params => ssl_params) }
|
|
let(:client_protocols) { nil }
|
|
let(:client) { Manticore::Client.new(ssl: { ca_file: ca_file, protocols: client_protocols }) }
|
|
let(:response) { client.get("https://127.0.0.1:#{webserver.port}") }
|
|
|
|
include_context 'running webserver'
|
|
|
|
context 'an HTTPS request using TLSv1.3' do
|
|
let(:client_protocols) { %w[TLSv1.3] }
|
|
it 'succeeds' do
|
|
expect(response.code).to eq(200)
|
|
end
|
|
end
|
|
|
|
context 'an HTTPS request using TLSv1.2' do
|
|
let(:client_protocols) { %w[TLSv1.2] }
|
|
it 'fails' do
|
|
expect { response.code }.to raise_error(Manticore::ClientProtocolException, a_string_including("handshake"))
|
|
end
|
|
end
|
|
end
|
|
|
|
%w(
|
|
server_from_root.p12
|
|
server_from_intermediate.p12
|
|
server_from_root.jks
|
|
server_from_intermediate.jks
|
|
).each do |keystore_name|
|
|
context "when configured with keystore #{keystore_name}" do
|
|
let(:ca_file) { File.join(certs_path, "root.crt") }
|
|
let(:certs_path) { File.expand_path("../../fixtures/webserver_certs/generated", __FILE__) }
|
|
let(:keystore_path) { File.join(certs_path, "#{keystore_name}") }
|
|
let(:keystore_password) { "12345678" }
|
|
|
|
let(:ssl_params) { {:keystore_path => keystore_path, :keystore_password => LogStash::Util::Password.new(keystore_password)} }
|
|
let(:webserver_options) { super().merge(:ssl_params => ssl_params) }
|
|
|
|
context 'and invalid credentials' do
|
|
let(:keystore_password) { "wrong" }
|
|
it 'raises a helpful error' do
|
|
expect { webserver }.to raise_error(ArgumentError, a_string_including("keystore password was incorrect"))
|
|
end
|
|
end
|
|
|
|
context "when started" do
|
|
include_context 'running webserver'
|
|
|
|
context 'an HTTPS request' do
|
|
it 'succeeds' do
|
|
client = Manticore::Client.new(ssl: { ca_file: ca_file })
|
|
response = client.get("https://127.0.0.1:#{webserver.port}")
|
|
expect(response.code).to eq(200)
|
|
end
|
|
|
|
# this is mostly a sanity check for our testing methodology
|
|
# If this fails, we cannot trust success from the other specs
|
|
context 'without providing CA' do
|
|
it 'fails' do
|
|
client = Manticore::Client.new(ssl: { })
|
|
expect do
|
|
client.get("https://127.0.0.1:#{webserver.port}").code
|
|
end.to raise_error(Manticore::ClientProtocolException, a_string_including("unable to find valid certification path to requested target"))
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'an HTTP request' do
|
|
it 'fails' do
|
|
client = Manticore::Client.new
|
|
expect do
|
|
client.get("http://127.0.0.1:#{webserver.port}").code
|
|
end.to raise_error(Manticore::ClientProtocolException, a_string_including("failed to respond"))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|