Skip to content

Commit

Permalink
feat: allow whitelist configurations to be loaded from database
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Jun 11, 2018
1 parent 91b005a commit 19cb83f
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 7 deletions.
3 changes: 3 additions & 0 deletions lib/pact_broker/config/load.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions lib/pact_broker/config/save.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
31 changes: 31 additions & 0 deletions lib/pact_broker/config/space_delimited_string_list.rb
Original file line number Diff line number Diff line change
@@ -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
33 changes: 29 additions & 4 deletions lib/pact_broker/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'pact_broker/error'
require 'pact_broker/config/space_delimited_string_list'

module PactBroker

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 7 additions & 1 deletion spec/lib/pact_broker/config/load_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }
Expand Down Expand Up @@ -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")
Expand Down
13 changes: 11 additions & 2 deletions spec/lib/pact_broker/config/save_spec.rb
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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) }
Expand Down Expand Up @@ -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.")
Expand Down
45 changes: 45 additions & 0 deletions spec/lib/pact_broker/config/space_delimited_string_list_spec.rb
Original file line number Diff line number Diff line change
@@ -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
25 changes: 25 additions & 0 deletions spec/lib/pact_broker/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 19cb83f

Please sign in to comment.