diff --git a/lib/pact_broker/config/load.rb b/lib/pact_broker/config/load.rb index 6f80008fb..cba0cfb22 100644 --- a/lib/pact_broker/config/load.rb +++ b/lib/pact_broker/config/load.rb @@ -1,6 +1,7 @@ require 'pact_broker/configuration' require 'pact_broker/logging' require 'pact_broker/config/setting' +require 'pact_broker/config/space_delimited_string_list' module PactBroker module Config @@ -49,6 +50,8 @@ def get_value_from_setting setting Integer(setting.value) when 'float' Float(setting.value) + when 'space_delimited_string_list' + SpaceDelimitedStringList.parse(setting.value) when 'boolean' setting.value == "1" end diff --git a/lib/pact_broker/config/save.rb b/lib/pact_broker/config/save.rb index 4d5191e0b..37a3dd861 100644 --- a/lib/pact_broker/config/save.rb +++ b/lib/pact_broker/config/save.rb @@ -49,6 +49,8 @@ def get_db_type setting_name 'boolean' when String, nil 'string' + when SpaceDelimitedStringList + 'space_delimited_string_list' when Array, Hash 'json' when Integer @@ -69,6 +71,8 @@ def get_db_value setting_name "1" when FalseClass "0" + when SpaceDelimitedStringList + val.to_s when Array, Hash val.to_json else diff --git a/lib/pact_broker/config/space_delimited_string_list.rb b/lib/pact_broker/config/space_delimited_string_list.rb new file mode 100644 index 000000000..75b3b70b7 --- /dev/null +++ b/lib/pact_broker/config/space_delimited_string_list.rb @@ -0,0 +1,31 @@ +module PactBroker + module Config + class SpaceDelimitedStringList < Array + + def initialize list + super(list) + end + + def self.parse(string) + array = (string || '').split(' ').collect do | word | + if word[0] == '/' and word[-1] == '/' + Regexp.new(word[1..-2]) + else + word + end + end + SpaceDelimitedStringList.new(array) + end + + def to_s + collect do | word | + if word.is_a?(Regexp) + "/#{word.source}/" + else + word + end + end.join(' ') + end + end + end +end diff --git a/lib/pact_broker/configuration.rb b/lib/pact_broker/configuration.rb index 7ca24d34c..759543a4e 100644 --- a/lib/pact_broker/configuration.rb +++ b/lib/pact_broker/configuration.rb @@ -1,4 +1,5 @@ require 'pact_broker/error' +require 'pact_broker/config/space_delimited_string_list' module PactBroker @@ -23,15 +24,19 @@ class Configuration :check_for_potential_duplicate_pacticipant_names, :webhook_retry_schedule, :semver_formats, - :disable_ssl_verification + :disable_ssl_verification, + :webhook_http_method_whitelist, + :webhook_scheme_whitelist, + :webhook_host_whitelist, + :base_equality_only_on_content_that_affects_verification_results ] attr_accessor :log_dir, :database_connection, :auto_migrate_db, :use_hal_browser, :html_pact_renderer attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser, :sha_generator attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date attr_accessor :check_for_potential_duplicate_pacticipant_names - attr_accessor :webhook_http_method_whitelist, :webhook_scheme_whitelist, :webhook_host_whitelist attr_accessor :webhook_retry_schedule + attr_reader :webhook_http_method_whitelist, :webhook_scheme_whitelist, :webhook_host_whitelist attr_accessor :semver_formats attr_accessor :enable_public_badge_access, :shields_io_base_url attr_accessor :disable_ssl_verification @@ -68,8 +73,7 @@ def self.default_configuration config.version_parser = PactBroker::Versions::ParseSemanticVersion config.sha_generator = PactBroker::Pacts::GenerateSha config.base_equality_only_on_content_that_affects_verification_results = false - # Not recommended to set this to true unless there is no way to - # consistently extract an orderable object from the consumer application version number. + # TODO change this to true config.order_versions_by_date = false 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 @@ -171,8 +175,29 @@ def load_from_database! PactBroker::Config::Load.call(self) end + def webhook_http_method_whitelist= webhook_http_method_whitelist + @webhook_http_method_whitelist = parse_space_delimited_string_list_property('webhook_http_method_whitelist', webhook_http_method_whitelist) + end + + def webhook_scheme_whitelist= webhook_scheme_whitelist + @webhook_scheme_whitelist = parse_space_delimited_string_list_property('webhook_scheme_whitelist', webhook_scheme_whitelist) + end + + def webhook_host_whitelist= webhook_host_whitelist + @webhook_host_whitelist = parse_space_delimited_string_list_property('webhook_host_whitelist', webhook_host_whitelist) + end + private + def parse_space_delimited_string_list_property property_name, property_value + case property_value + when String then Config::SpaceDelimitedStringList.parse(property_value) + when Array then Config::SpaceDelimitedStringList.new(property_value) + else + raise ConfigurationError.new("Pact Broker configuration property `#{property_name}` must be a space delimited String or an Array") + end + end + def create_logger path FileUtils::mkdir_p File.dirname(path) logger = Logger.new(path) diff --git a/spec/lib/pact_broker/config/load_spec.rb b/spec/lib/pact_broker/config/load_spec.rb index 680d1fa4b..c48398b27 100644 --- a/spec/lib/pact_broker/config/load_spec.rb +++ b/spec/lib/pact_broker/config/load_spec.rb @@ -7,7 +7,7 @@ module Config describe ".call" do class MockConfig - attr_accessor :foo, :bar, :nana, :meep, :lalala, :meow, :peebo + attr_accessor :foo, :bar, :nana, :meep, :lalala, :meow, :peebo, :whitelist end before do @@ -19,6 +19,7 @@ class MockConfig Setting.create(name: 'meow', type: 'boolean', value: "0") Setting.create(name: 'peebo', type: 'string', value: nil) Setting.create(name: 'unknown', type: 'string', value: nil) + Setting.create(name: 'whitelist', type: 'space_delimited_string_list', value: 'foo bar') end let(:configuration) { MockConfig.new } @@ -60,6 +61,11 @@ class MockConfig expect(configuration.peebo).to eq nil end + it "loads a space_delimited_string_list" do + subject + expect(configuration.whitelist).to eq ["foo", "bar"] + end + it "does not load a setting where the Configuration object does not have a matching property" do allow(Load.logger).to receive(:warn) expect(Load.logger).to receive(:warn).with("Could not load configuration setting \"unknown\" as there is no matching attribute on the Configuration class") diff --git a/spec/lib/pact_broker/config/save_spec.rb b/spec/lib/pact_broker/config/save_spec.rb index 0b4e9a726..4491693be 100644 --- a/spec/lib/pact_broker/config/save_spec.rb +++ b/spec/lib/pact_broker/config/save_spec.rb @@ -1,12 +1,13 @@ require 'pact_broker/config/save' require 'pact_broker/configuration' +require 'pact_broker/config/space_delimited_string_list' module PactBroker module Config describe Save do describe "#call" do - let(:setting_names) { [:foo, :bar, :wiffle, :meep, :flop, :peebo, :lalala, :meow] } + let(:setting_names) { [:foo, :bar, :wiffle, :meep, :flop, :peebo, :lalala, :meow, :whitelist] } let(:configuration) do double("PactBroker::Configuration", foo: true, @@ -16,7 +17,8 @@ module Config flop: nil, peebo: 1, lalala: 1.2, - meow: Object.new) + meow: Object.new, + whitelist: SpaceDelimitedStringList.parse("foo bar")) end subject { Save.call(configuration, setting_names) } @@ -70,6 +72,13 @@ module Config expect(setting.value).to eq '1.2' end + it "saves a SpaceDelimitedStringList" do + subject + setting = Setting.find(name: 'whitelist') + expect(setting.type).to eq 'space_delimited_string_list' + expect(setting.value).to eq 'foo bar' + end + it "does not save an arbitrary object to the database" do allow(Save.logger).to receive(:warn) expect(Save.logger).to receive(:warn).with("Could not save configuration setting \"meow\" to database as the class Object is not supported.") diff --git a/spec/lib/pact_broker/config/space_delimited_string_list_spec.rb b/spec/lib/pact_broker/config/space_delimited_string_list_spec.rb new file mode 100644 index 000000000..ff82cfc12 --- /dev/null +++ b/spec/lib/pact_broker/config/space_delimited_string_list_spec.rb @@ -0,0 +1,45 @@ +require 'pact_broker/config/space_delimited_string_list' + +module PactBroker + module Config + describe SpaceDelimitedStringList do + describe "parse" do + subject { SpaceDelimitedStringList.parse(input) } + + context "when input is ''" do + let(:input) { "" } + + it { is_expected.to eq [] } + + its(:to_s) { is_expected.to eq input } + end + + context "when input is 'foo bar'" do + let(:input) { "foo bar" } + + it { is_expected.to eq ["foo", "bar"] } + + it { is_expected.to be_a SpaceDelimitedStringList } + + its(:to_s) { is_expected.to eq input } + end + + context "when input is '/foo.*/'" do + let(:input) { "/foo.*/" } + + it { is_expected.to eq [/foo.*/] } + + its(:to_s) { is_expected.to eq input } + end + + context "when input is '/foo\\.*/' (note double backslash)" do + let(:input) { "/foo\\.*/" } + + it { is_expected.to eq [/foo\.*/] } + + its(:to_s) { is_expected.to eq input } + end + end + end + end +end diff --git a/spec/lib/pact_broker/configuration_spec.rb b/spec/lib/pact_broker/configuration_spec.rb index e56952c8e..4473a2842 100644 --- a/spec/lib/pact_broker/configuration_spec.rb +++ b/spec/lib/pact_broker/configuration_spec.rb @@ -16,7 +16,32 @@ module PactBroker expect(PactBroker::Api::Renderers::HtmlPactRenderer).to receive(:call).with(pact, options) PactBroker.configuration.html_pact_renderer.call pact, options end + end + + describe "webhook_http_method_whitelist" do + it "allows setting the whitelist by a string" do + PactBroker.configuration.webhook_http_method_whitelist = "foo" + expect(PactBroker.configuration.webhook_http_method_whitelist).to be_a Config::SpaceDelimitedStringList + end + + it "allows setting the whitelist by an array" do + PactBroker.configuration.webhook_http_method_whitelist = ["foo"] + expect(PactBroker.configuration.webhook_http_method_whitelist).to be_a Config::SpaceDelimitedStringList + end + end + describe "webhook_scheme_whitelist" do + it "allows setting the whitelist by a string" do + PactBroker.configuration.webhook_scheme_whitelist = "foo" + expect(PactBroker.configuration.webhook_scheme_whitelist).to be_a Config::SpaceDelimitedStringList + end + end + + describe "webhook_host_whitelist" do + it "allows setting the whitelist by a string" do + PactBroker.configuration.webhook_host_whitelist = "foo" + expect(PactBroker.configuration.webhook_host_whitelist).to be_a Config::SpaceDelimitedStringList + end end describe "SETTING_NAMES" do