diff --git a/.ruby-version b/.ruby-version index 3f684d2d9..197c4d5c2 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.3.4 +2.4.0 diff --git a/lib/pact_broker/badges/service.rb b/lib/pact_broker/badges/service.rb index 95625ea48..a20b89e9f 100644 --- a/lib/pact_broker/badges/service.rb +++ b/lib/pact_broker/badges/service.rb @@ -3,6 +3,7 @@ require 'pact_broker/project_root' require 'pact_broker/logging' require 'pact_broker/configuration' +require 'pact_broker/build_http_options' module PactBroker module Badges @@ -102,12 +103,10 @@ def escape_text text def do_request(uri) with_cache uri do request = Net::HTTP::Get.new(uri) - Net::HTTP.start(uri.hostname, uri.port, - use_ssl: uri.scheme == 'https', - read_timeout: 3, - open_timeout: 1, - ssl_timeout: 1, - continue_timeout: 1) do |http| + options = {read_timeout: 3, open_timeout: 1, ssl_timeout: 1, continue_timeout: 1} + options.merge! PactBroker::BuildHttpOptions.call(uri) + + Net::HTTP.start(uri.hostname, uri.port, :ENV, options) do |http| http.request request end end diff --git a/lib/pact_broker/build_http_options.rb b/lib/pact_broker/build_http_options.rb new file mode 100644 index 000000000..e5beb636d --- /dev/null +++ b/lib/pact_broker/build_http_options.rb @@ -0,0 +1,32 @@ +require 'pact_broker/services' + +module PactBroker + class BuildHttpOptions + extend PactBroker::Services + + def self.call uri + uri = URI(uri) + options = {} + + if uri.scheme == 'https' + options[:use_ssl] = true + options[:cert_store] = cert_store + if disable_ssl_verification? + options[:verify_mode] = OpenSSL::SSL::VERIFY_NONE + else + options[:verify_mode] = OpenSSL::SSL::VERIFY_PEER + end + end + options + end + + def self.disable_ssl_verification? + PactBroker.configuration.disable_ssl_verification + end + + def self.cert_store + certificate_service.cert_store + end + end +end + diff --git a/lib/pact_broker/configuration.rb b/lib/pact_broker/configuration.rb index e1ead0f38..d11cc17f9 100644 --- a/lib/pact_broker/configuration.rb +++ b/lib/pact_broker/configuration.rb @@ -18,7 +18,8 @@ class Configuration :shields_io_base_url, :check_for_potential_duplicate_pacticipant_names, :webhook_retry_schedule, - :semver_formats + :semver_formats, + :disable_ssl_verification ] attr_accessor :log_dir, :database_connection, :auto_migrate_db, :use_hal_browser, :html_pact_renderer @@ -28,6 +29,7 @@ class Configuration attr_accessor :semver_formats attr_accessor :enable_public_badge_access, :shields_io_base_url attr_accessor :webhook_retry_schedule + attr_accessor :disable_ssl_verification attr_writer :logger def initialize @@ -60,6 +62,7 @@ def self.default_configuration config.semver_formats = ["%M.%m.%p%s%d", "%M.%m", "%M"] config.webhook_retry_schedule = [10, 60, 120, 300, 600, 1200] #10 sec, 1 min, 2 min, 5 min, 10 min, 20 min => 38 minutes config.check_for_potential_duplicate_pacticipant_names = true + config.disable_ssl_verification = false config end diff --git a/lib/pact_broker/domain/webhook_request.rb b/lib/pact_broker/domain/webhook_request.rb index c51d1ca47..2572b7db5 100644 --- a/lib/pact_broker/domain/webhook_request.rb +++ b/lib/pact_broker/domain/webhook_request.rb @@ -1,3 +1,4 @@ +require 'pact_broker/build_http_options' require 'pact_broker/domain/webhook_request_header' require 'pact_broker/domain/webhook_execution_result' require 'pact_broker/logging' @@ -5,7 +6,7 @@ require 'net/http' require 'pact_broker/webhooks/redact_logs' require 'pact_broker/api/pact_broker_urls' -require 'pact_broker/services' +require 'pact_broker/build_http_options' module PactBroker @@ -24,7 +25,6 @@ class WebhookRequest include PactBroker::Logging include PactBroker::Messages - include PactBroker::Services attr_accessor :method, :url, :headers, :body, :username, :password, :uuid @@ -104,13 +104,8 @@ def build_request uri, pact, execution_logger def do_request uri, req logger.info "Making webhook #{uuid} request #{to_s}" - options = {} - if uri.scheme == 'https' - options[:use_ssl] = true - options[:verify_mode] = OpenSSL::SSL::VERIFY_PEER - options[:cert_store] = cert_store - end - Net::HTTP.start(uri.hostname, uri.port, options) do |http| + options = PactBroker::BuildHttpOptions.call(uri) + Net::HTTP.start(uri.hostname, uri.port, :ENV, options) do |http| http.request req end end @@ -174,10 +169,6 @@ def gsub_url pact, url escaped_pact_url = CGI::escape(pact_url) url.gsub('${pactbroker.pactUrl}', escaped_pact_url) end - - def cert_store - certificate_service.cert_store - end end end end diff --git a/spec/lib/pact_broker/build_http_options_spec.rb b/spec/lib/pact_broker/build_http_options_spec.rb new file mode 100644 index 000000000..81c9d38cc --- /dev/null +++ b/spec/lib/pact_broker/build_http_options_spec.rb @@ -0,0 +1,47 @@ +require 'spec_helper' +require 'pact_broker/build_http_options' + +module PactBroker + describe BuildHttpOptions do + + subject { PactBroker::BuildHttpOptions.call(url) } + + context "default http options" do + before do + PactBroker.configuration.disable_ssl_verification = false + end + + describe "when given an insecure URL" do + let(:url) { 'http://example.org/insecure' } + + it "should provide an empty configuration object" do + expect(subject).to eq({}) + end + + end + + describe "when given a secure URL" do + let(:url) { 'https://example.org/secure' } + + it "should validate the full certificate chain" do + expect(subject).to include({:use_ssl => true, :verify_mode => 1}) + end + + end + end + + context "disable_ssl_verification is set to true" do + before do + PactBroker.configuration.disable_ssl_verification = true + end + + let(:url) { 'https://example.org/secure' } + + describe "when given a secure URL" do + it "should not validate certificates" do + expect(subject).to include({:use_ssl => true, :verify_mode => 0}) + end + end + end + end +end