pact_broker 2.57.0 → 2.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1de4cab3f4fb99ade4806255fb8e1ea1745429fdac8302154d092c99c36c7d76
4
- data.tar.gz: 910569291d130d66d73b3a557a983ba4563a70ae7d3c581ad9ebc770958ea56e
3
+ metadata.gz: e9b3ca0a02cb3eb39138704d804ed6a9997aa044cf0729059175d24acf02794f
4
+ data.tar.gz: 619a828a1ab0f7b1d5677525c5d52b82ec785455a19c0603ce18a3981be81eb7
5
5
  SHA512:
6
- metadata.gz: 2df74e9cbdfa705a1221f4422fb9dc18e33106b25a68b9b2013f649e8d35ad015b344251d2aacd7e9b22d73d50435eb3cdc2e773843de0b49792859e5daa83c6
7
- data.tar.gz: 2f5255f3ba8292bd2df960db95c40b86196872c49f3080afb8cdb398dd96b22022bd6bd28ca73a221881322112fa9f9da6bf9d1b870dba6a59cd286bfb45fbeb
6
+ metadata.gz: 80e5a6272e05b35ff82a5a08fc26cb8acc2729d64b969f3764dbd1bb6be4ed168722d884ca635fe85dc58946c085dc60d65b1d4c95cc0fc8d9437a9f8aaa3356
7
+ data.tar.gz: d094ef10bf315a635afd6c6ef52148ac25c2e03afafcbb5e53b411c4ff2e676fd01d9db45414be4354054396547ae182b4991beadf6e6f0de63045cb38b2ccde
@@ -1,3 +1,19 @@
1
+ <a name="v2.58.0"></a>
2
+ ### v2.58.0 (2020-06-19)
3
+
4
+
5
+ #### Features
6
+
7
+ * log foreign key constraint errors as warn as 99% of the time they are transitory and unreproducible and should not cause alarms to be raised ([71fd0270](/../../commit/71fd0270))
8
+ * use structured logs for logging errors ([1e097b37](/../../commit/1e097b37))
9
+
10
+
11
+ #### Bug Fixes
12
+
13
+ * fix: update sanitize gem for CVE-2020-4054 ([2af4bf9d](/../../commit/2af4bf9d))
14
+ * do not parse the provider version as a semantic version when order_versions_by_date is true ([bf30024f](/../../commit/bf30024f))
15
+
16
+
1
17
  <a name="v2.57.0"></a>
2
18
  ### v2.57.0 (2020-06-16)
3
19
 
@@ -8,7 +8,7 @@ ENV['RACK_ENV'] ||= 'production'
8
8
 
9
9
  # Create a real database, and set the credentials for it here
10
10
  # It is highly recommended to set the encoding to utf8
11
- DATABASE_CREDENTIALS = {adapter: "sqlite", database: "pact_broker_database.sqlite3", :encoding => 'utf8'}
11
+ DATABASE_CREDENTIALS = { adapter: "sqlite", database: "pact_broker_database.sqlite3", :encoding => 'utf8', sql_log_level: :debug }
12
12
 
13
13
  # For postgres:
14
14
  #
@@ -25,6 +25,8 @@ module PactBroker
25
25
  end
26
26
 
27
27
  def valid_version_number?(value)
28
+ return true if PactBroker.configuration.order_versions_by_date
29
+
28
30
  parsed_version_number = PactBroker.configuration.version_parser.call(value)
29
31
  !!parsed_version_number
30
32
  end
@@ -8,13 +8,16 @@ module PactBroker
8
8
 
9
9
  include PactBroker::Logging
10
10
 
11
+ WARNING_ERROR_CLASSES = [Sequel::ForeignKeyConstraintViolation]
12
+
11
13
  def self.call e, request, response
12
14
  error_reference = generate_error_reference
13
- if reportable?(e)
15
+ if log_as_warning?(e)
16
+ logger.warn("Error reference #{error_reference}", e)
17
+ elsif reportable?(e)
14
18
  log_error(e, "Error reference #{error_reference}")
15
19
  report(e, error_reference, request)
16
- else
17
- logger.info "Error reference #{error_reference} - #{e.class} #{e.message}\n#{e.backtrace.join("\n")}"
20
+ logger.info("Error reference #{error_reference}", e)
18
21
  end
19
22
  response.body = response_body_hash(e, error_reference).to_json
20
23
  end
@@ -27,6 +30,10 @@ module PactBroker
27
30
  !e.is_a?(PactBroker::Error) && !e.is_a?(JSON::GeneratorError)
28
31
  end
29
32
 
33
+ def self.log_as_warning?(e)
34
+ WARNING_ERROR_CLASSES.any? { |clazz| e.is_a?(clazz) }
35
+ end
36
+
30
37
  def self.display_message(e, error_reference)
31
38
  if PactBroker.configuration.show_backtrace_in_error_response?
32
39
  e.message || obfuscated_error_message(error_reference)
@@ -9,13 +9,11 @@ require 'delegate'
9
9
  module PactBroker
10
10
  module DB
11
11
  class LogQuietener < SimpleDelegator
12
- def info *args
13
- __getobj__().debug(*args)
14
- end
15
-
16
12
  def error *args
17
13
  if error_is_about_table_not_existing?(args)
18
14
  __getobj__().debug(*reassure_people_that_this_is_expected(args))
15
+ elsif foreign_key_error?(args)
16
+ __getobj__().warn(*args)
19
17
  else
20
18
  __getobj__().error(*args)
21
19
  end
@@ -28,6 +26,11 @@ module PactBroker
28
26
  args.first.include?("no such view"))
29
27
  end
30
28
 
29
+ # Foreign key exceptions are almost always transitory and unreproducible by this stage
30
+ def foreign_key_error?(args)
31
+ args.first.is_a?(String) && args.first.downcase.include?("foreign key")
32
+ end
33
+
31
34
  def reassure_people_that_this_is_expected(args)
32
35
  message = args.shift
33
36
  message = message + " Don't panic. This happens when Sequel doesn't know if a table/view exists or not."
@@ -18,6 +18,10 @@ module PactBroker
18
18
  symbolize_keys_private(self)
19
19
  end
20
20
 
21
+ def stringify_keys
22
+ stringify_keys_private(self)
23
+ end
24
+
21
25
  def snakecase_keys
22
26
  snakecase_keys_private(self)
23
27
  end
@@ -26,6 +30,10 @@ module PactBroker
26
30
  keys.each_with_object(Hash.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
27
31
  end
28
32
 
33
+ def camelcase_keys
34
+ camelcase_keys_private(self)
35
+ end
36
+
29
37
  private
30
38
 
31
39
  def snakecase_keys_private(params)
@@ -45,7 +53,25 @@ module PactBroker
45
53
  else
46
54
  params
47
55
  end
56
+ end
48
57
 
58
+ def camelcase_keys_private(params)
59
+ case params
60
+ when Hash
61
+ params.inject({}) do |result, (key, value)|
62
+ snake_key = case key
63
+ when String then key.camelcase
64
+ when Symbol then key.to_s.camelcase.to_sym
65
+ else
66
+ key
67
+ end
68
+ result.merge(snake_key => camelcase_keys_private(value))
69
+ end
70
+ when Array
71
+ params.collect { |value| camelcase_keys_private(value) }
72
+ else
73
+ params
74
+ end
49
75
  end
50
76
 
51
77
  def symbolize_keys_private(params)
@@ -60,6 +86,19 @@ module PactBroker
60
86
  params
61
87
  end
62
88
  end
89
+
90
+ def stringify_keys_private(params)
91
+ case params
92
+ when Hash
93
+ params.inject({}) do |result, (key, value)|
94
+ result.merge(key.to_s => symbolize_keys_private(value))
95
+ end
96
+ when Array
97
+ params.collect { |value| symbolize_keys_private(value) }
98
+ else
99
+ params
100
+ end
101
+ end
63
102
  end
64
103
  end
65
104
  end
@@ -31,9 +31,17 @@ module PactBroker
31
31
  end
32
32
 
33
33
  def log_error e, description = nil
34
- message = "#{e.class} #{e.message}\n#{e.backtrace.join("\n")}"
35
- message = "#{description} - #{message}" if description
36
- logger.error message
34
+ if logger.instance_of?(SemanticLogger::Logger)
35
+ if description
36
+ logger.error(description, e)
37
+ else
38
+ logger.error(e)
39
+ end
40
+ else
41
+ message = "#{e.class} #{e.message}\n#{e.backtrace.join("\n")}"
42
+ message = "#{description} - #{message}" if description
43
+ logger.error message
44
+ end
37
45
  if ENV['PACT_BROKER_HIDE_PACTFLOW_MESSAGES'] != 'true'
38
46
  logger.info "\n\n#{'*' * 80}\n\nPrefer it was someone else's job to deal with this error? Check out https://pactflow.io/oss for a hardened, fully supported SaaS version of the Pact Broker with an improved UI + more.\n\n#{'*' * 80}\n"
39
47
  end
@@ -9,7 +9,9 @@ module PactBroker
9
9
  end
10
10
 
11
11
  def call(log, output)
12
- @formatter.call(log.level.upcase, log.time, nil, log.message)
12
+ self.log = log
13
+ self.logger = logger
14
+ @formatter.call(log.level.upcase, log.time, nil, [tags, named_tags, duration, message, payload, exception].compact.join(" "))
13
15
  end
14
16
  end
15
17
  end
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.57.0'
2
+ VERSION = '2.58.0'
3
3
  end
@@ -51,7 +51,7 @@ Gem::Specification.new do |gem|
51
51
  gem.add_runtime_dependency 'sequel', '~> 5.28'
52
52
  gem.add_runtime_dependency 'webmachine', '1.5.0'
53
53
  gem.add_runtime_dependency 'semver2', '~> 3.4.2'
54
- gem.add_runtime_dependency 'rack', '~> 2.2', '>= 2.2.3'
54
+ gem.add_runtime_dependency 'rack', '>= 2.2.3', '~> 2.2'
55
55
  gem.add_runtime_dependency 'redcarpet', '>=3.3.2', '~>3.3'
56
56
  gem.add_runtime_dependency 'pact-support', '~> 1.14', '>= 1.14.1'
57
57
  gem.add_runtime_dependency 'padrino-core', '>= 0.14.3', '~> 0.14'
@@ -63,7 +63,7 @@ Gem::Specification.new do |gem|
63
63
  gem.add_runtime_dependency 'dry-logic', '0.4.2' # Later version cases ArgumentError: wrong number of arguments
64
64
  gem.add_runtime_dependency 'table_print', '~> 1.5'
65
65
  gem.add_runtime_dependency 'semantic_logger', '~> 4.3'
66
- gem.add_runtime_dependency 'sanitize', '~> 5.1'
66
+ gem.add_runtime_dependency 'sanitize', '>= 5.2.1', '~> 5.2'
67
67
 
68
68
  gem.add_development_dependency 'pact', '~>1.14'
69
69
  gem.add_development_dependency 'rspec-pact-matchers', '~>0.1'
@@ -15,6 +15,7 @@ module PactBroker
15
15
  let(:success) { true }
16
16
  let(:provider_version) { "4.5.6" }
17
17
  let(:build_url) { 'http://foo' }
18
+ let(:order_versions_by_date) { false }
18
19
 
19
20
  def modify hash, options
20
21
  hash.delete(options.fetch(:without))
@@ -24,6 +25,7 @@ module PactBroker
24
25
  describe "errors" do
25
26
 
26
27
  before do
28
+ allow(PactBroker.configuration).to receive(:order_versions_by_date).and_return(order_versions_by_date)
27
29
  subject.validate(params)
28
30
  end
29
31
 
@@ -85,10 +87,22 @@ module PactBroker
85
87
  end
86
88
  end
87
89
 
88
- context "when the providerApplicationVersion is not a semantic version" do
89
- let(:provider_version) { "#" }
90
- it "has an error" do
91
- expect(subject.errors[:provider_version]).to include(match("#.*cannot be parsed"))
90
+ context "when order_versions_by_date is true" do
91
+ let(:order_versions_by_date) { true }
92
+
93
+ context "when the providerApplicationVersion is not a semantic version" do
94
+ let(:provider_version) { "#" }
95
+ its(:errors) { is_expected.to be_empty }
96
+ end
97
+ end
98
+
99
+ context "when order_versions_by_date is false" do
100
+ context "when the providerApplicationVersion is not a semantic version" do
101
+ let(:provider_version) { "#" }
102
+
103
+ it "has an error" do
104
+ expect(subject.errors[:provider_version]).to include(match("#.*cannot be parsed"))
105
+ end
92
106
  end
93
107
  end
94
108
  end
@@ -23,6 +23,16 @@ module PactBroker
23
23
  end
24
24
  end
25
25
 
26
+ context "when the error is a foreign key constraint violation" do
27
+ before do
28
+ subject.error("SQLite3::ConstraintException: FOREIGN KEY constraint failed: delete from pacticipants where id = 1")
29
+ end
30
+
31
+ it "logs the message at warn level" do
32
+ expect(logs.string).to include "WARN -- :"
33
+ end
34
+ end
35
+
26
36
  context "when the error is NOT for a table or view that does not exist" do
27
37
  before do
28
38
  subject.error("foo bar")
@@ -12,6 +12,30 @@ module PactBroker
12
12
  expect(a.deep_merge(b)).to eq expected
13
13
  end
14
14
 
15
+ describe "camelcase_keys" do
16
+ let(:hash_1) do
17
+ {
18
+ "foo_bar" => {
19
+ :meep_moop => "blahBlah",
20
+ "beepBoop" => ""
21
+ }
22
+ }
23
+ end
24
+
25
+ let(:expected) do
26
+ {
27
+ "fooBar" => {
28
+ :meepMoop => "blahBlah",
29
+ "beepBoop" => ""
30
+ }
31
+ }
32
+ end
33
+
34
+ it "camel cases the keys" do
35
+ expect(hash_1.camelcase_keys).to eq expected
36
+ end
37
+ end
38
+
15
39
  describe "snakecase_keys" do
16
40
  let(:hash_1) do
17
41
  {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact_broker
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.57.0
4
+ version: 2.58.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bethany Skurrie
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-06-15 00:00:00.000000000 Z
13
+ date: 2020-06-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: httparty
@@ -340,14 +340,20 @@ dependencies:
340
340
  requirements:
341
341
  - - "~>"
342
342
  - !ruby/object:Gem::Version
343
- version: '5.1'
343
+ version: '5.2'
344
+ - - ">="
345
+ - !ruby/object:Gem::Version
346
+ version: 5.2.1
344
347
  type: :runtime
345
348
  prerelease: false
346
349
  version_requirements: !ruby/object:Gem::Requirement
347
350
  requirements:
348
351
  - - "~>"
349
352
  - !ruby/object:Gem::Version
350
- version: '5.1'
353
+ version: '5.2'
354
+ - - ">="
355
+ - !ruby/object:Gem::Version
356
+ version: 5.2.1
351
357
  - !ruby/object:Gem::Dependency
352
358
  name: pact
353
359
  requirement: !ruby/object:Gem::Requirement