-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Expand file tree
/
Copy pathwebserver_spec.rb
More file actions
145 lines (126 loc) · 5.64 KB
/
webserver_spec.rb
File metadata and controls
145 lines (126 loc) · 5.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# 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"
# SPLIT_ESTIMATE: 5
describe 'api webserver', :skip_fips 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