pact_broker 2.27.0 → 2.27.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 05fcf55e9f52ba3eab88ff971faffb939b8bf3a3
4
- data.tar.gz: 15dd2c9ae6976e5f0ed924947072625fab619dfe
2
+ SHA256:
3
+ metadata.gz: e67bad7e9a3ecb1e2ecd911350a937615bf9b2f90ac811ad48acf16185ffee41
4
+ data.tar.gz: e55c77c181b1d2e37e20a6b0a4f6b500ebdba7b0c861597c8f80b580915d9a3c
5
5
  SHA512:
6
- metadata.gz: 74e9bf66eebb3355c4809b5423469242ccfb31d780eb29c3c0d28d6d6b140726826a4fa8ac204672631a5cd856356708580e6e7d205468b4a3e8f76e4c1c1e2d
7
- data.tar.gz: 7e52f4d4457fa1a9c013a3d58340d5ccbc01b4075c0fd7ca7d787b66593e0a71736992e773bec72e4767e6cdddb5bb893087380e61896b1e75537e516dfd7e26
6
+ metadata.gz: 3fcd28aeb22cee45696bee504bb1c6b49cec7faa83185df24c5854e9a22fd2023bee57f62fbea2fad54f5c4f590e1de91febab56f3baa1a15a7656d692a0d816
7
+ data.tar.gz: 18a6fe1f7dd9c61143ea1fe7bf031576c8d1d615d0a212dc2b8e833ad5fd14de39c606e92ea021f82f8b64015ba3e12a7f8cccc317fd5979c30a965b153cb773
@@ -11,6 +11,7 @@ env:
11
11
  global:
12
12
  - CC_TEST_REPORTER_ID=dc2c30b67c9e2a5309e1aef699c30fdab55ba4f0e4f1beac029ba93e293835db
13
13
  - GIT_COMMITTED_AT=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then git log -1 --pretty=format:%ct; else git log -1 --skip 1 --pretty=format:%ct; fi)
14
+ - INSTALL_MYSQL=true
14
15
  matrix:
15
16
  - DATABASE_ADAPTER=default RUBYOPT="-W0"
16
17
  - DATABASE_ADAPTER=postgres RUBYOPT="-W0"
@@ -1,3 +1,22 @@
1
+ <a name="v2.27.2"></a>
2
+ ### v2.27.2 (2018-09-14)
3
+
4
+
5
+ #### Features
6
+
7
+ * use application/yaml instead of application/x-yaml to match Swaggerhub ([067d6ac7](/../../commit/067d6ac7))
8
+ * treat .yaml requests as having header Accept: application/x-yaml ([1c8e199f](/../../commit/1c8e199f))
9
+
10
+ * **webhook whitelist**
11
+ * allow hosts to be whitelisted using * domains ([150858a1](/../../commit/150858a1))
12
+
13
+
14
+ #### Bug Fixes
15
+
16
+ * **content-type**
17
+ * convert 404 content-type to application/hal+json #235 ([83958db7](/../../commit/83958db7))
18
+
19
+
1
20
  <a name="v2.27.0"></a>
2
21
  ### v2.27.0 (2018-09-07)
3
22
 
data/Gemfile CHANGED
@@ -3,3 +3,7 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem 'simplecov', :require => false, :group => :test
6
+
7
+ if ENV['INSTALL_MYSQL'] == "true"
8
+ gem 'mysql2', '~>0.3.15'
9
+ end
@@ -12,6 +12,7 @@ require 'rack/pact_broker/accepts_html_filter'
12
12
  require 'rack/pact_broker/ui_authentication'
13
13
  require 'rack/pact_broker/configurable_make_it_later'
14
14
  require 'rack/pact_broker/no_auth'
15
+ require 'rack/pact_broker/convert_404_to_hal'
15
16
  require 'sucker_punch'
16
17
 
17
18
  module PactBroker
@@ -145,6 +146,7 @@ module PactBroker
145
146
  require 'pact_broker/api'
146
147
  builder = ::Rack::Builder.new
147
148
  builder.use @make_it_later_api_auth
149
+ builder.use Rack::PactBroker::Convert404ToHal
148
150
  builder.use Rack::PactBroker::DatabaseTransaction, configuration.database_connection
149
151
  builder.run PactBroker::API
150
152
  builder
@@ -123,7 +123,7 @@ Pact Broker Github repository.
123
123
 
124
124
  * **Host**: If the `webhook_host_whitelist` contains any entries, the host must match one or more of the entries. By default, it is empty. For security purposes, if the host whitelist is empty, the response details will not be logged to the UI (though they can be seen in the application logs at debug level).
125
125
 
126
- The host whitelist may contain hostnames (eg `"github.com"`), IPs (eg `"192.0.345.4"`), network ranges (eg `"10.0.0.0/8"`) or regular expressions (eg `/.*\.foo\.com$/`). Note that IPs are not resolved, so if you specify an IP range, you need to use the IP in the webhook URL. If you wish to allow webhooks to any host (not recommended!), you can set `webhook_host_whitelist` to `[/.*/]`. Beware of any sensitive endpoints that may be exposed within the same network.
126
+ The host whitelist may contain hostnames (eg `"github.com"`), domains beginning with `*` (eg. `"*.foo.com"`), IPs (eg `"192.0.345.4"`), network ranges (eg `"10.0.0.0/8"`) or regular expressions (eg `/.*\.foo\.com$/`). Note that IPs are not resolved, so if you specify an IP range, you need to use the IP in the webhook URL. If you wish to allow webhooks to any host (not recommended!), you can set `webhook_host_whitelist` to `[/.*/]`. Beware of any sensitive endpoints that may be exposed within the same network.
127
127
 
128
128
  The recommended set of values to start with are:
129
129
 
@@ -131,7 +131,9 @@ Pact Broker Github repository.
131
131
  * your company chat (eg. Slack, for publishing notifications)
132
132
  * your code repository (eg. Github, for sending commit statuses)
133
133
 
134
- Alternatively, you could use a regular expression to limit requests to your company's domain. eg `/.*\.foo\.com$/` (don't forget the end of string anchor). You can test Ruby regular expressions at [rubular.com](http://rubular.com).
134
+ Alternatively, you could use a domain beginning with a `*` to limit requests to your company's domain.
135
+
136
+ Note that the hostname/domain matching follows that used for SSL certificate hostnames, so `*.foo.com` will match `a.foo.com` but not `a.b.foo.com`. If you need more flexible matching because you have domains with variable "parts" (eg `a.b.foo.com`), you can use a regular expression (eg `/.*\.foo\.com$/` - don't forget the end of string anchor). You can test Ruby regular expressions at [rubular.com](http://rubular.com).
135
137
 
136
138
  ### Testing
137
139
 
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.27.0'
2
+ VERSION = '2.27.2'
3
3
  end
@@ -1,3 +1,5 @@
1
+ require 'openssl'
2
+
1
3
  module PactBroker
2
4
  module Webhooks
3
5
  class CheckHostWhitelist
@@ -7,16 +9,34 @@ module PactBroker
7
9
  end
8
10
 
9
11
  def self.match?(host, whitelist_host)
10
- if whitelist_host.is_a?(Regexp)
11
- host =~ whitelist_host
12
+ if parse_ip_address(host)
13
+ ip_address_matches_range(host, whitelist_host)
14
+ elsif whitelist_host.is_a?(Regexp)
15
+ host_matches_regexp(host, whitelist_host)
16
+ elsif whitelist_host.start_with?("*")
17
+ OpenSSL::SSL.verify_hostname(host, whitelist_host)
12
18
  else
13
- begin
14
- IPAddr.new(whitelist_host) === IPAddr.new(host)
15
- rescue IPAddr::Error
16
- host == whitelist_host
17
- end
19
+ host == whitelist_host
18
20
  end
19
21
  end
22
+
23
+ def self.parse_ip_address(addr)
24
+ IPAddr.new(addr)
25
+ rescue IPAddr::Error
26
+ nil
27
+ end
28
+
29
+ def self.ip_address_matches_range(host, maybe_whitelist_range)
30
+ parse_ip_address(maybe_whitelist_range) === parse_ip_address(host)
31
+ end
32
+
33
+ def self.host_matches_regexp(host, whitelist_regexp)
34
+ host =~ whitelist_regexp
35
+ end
36
+
37
+ def self.host_matches_domain_with_wildcard(host, whitelist_domain)
38
+ OpenSSL::SSL.verify_hostname(host, whitelist_domain)
39
+ end
20
40
  end
21
41
  end
22
42
  end
@@ -0,0 +1,20 @@
1
+ module Rack
2
+ module PactBroker
3
+ class Convert404ToHal
4
+
5
+ def initialize app
6
+ @app = app
7
+ end
8
+
9
+ def call env
10
+ response = @app.call(env)
11
+
12
+ if response.first == 404 && response[1]['Content-Type'] == 'text/html' && !(env['HTTP_ACCEPT'] =~ /html/)
13
+ [404, { 'Content-Type' => 'application/hal+json'},[]]
14
+ else
15
+ response
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,14 +1,18 @@
1
1
  module Rack
2
2
  module PactBroker
3
-
4
3
  # If the HTML and the CSV group resources are both requested by the browser,
5
4
  # Chrome gets confused by the content types, and when you click back, it tries to load the CSV
6
5
  # instead of the HTML page. So we have to give the CSV resource a different URL (.csv)
7
6
 
8
7
  class ConvertFileExtensionToAcceptHeader
9
8
 
10
- EXTENSIONS = {".csv" => "text/csv", ".svg" => "image/svg+xml", ".json" => "application/hal+json"}
11
- EXTENSION_REGEXP = /\.\w+$/
9
+ EXTENSION_REGEXP = /\.\w+$/.freeze
10
+ EXTENSIONS = {
11
+ ".csv" => "text/csv",
12
+ ".svg" => "image/svg+xml",
13
+ ".json" => "application/hal+json",
14
+ ".yaml" => "application/yaml"
15
+ }
12
16
 
13
17
  def initialize app
14
18
  @app = app
@@ -37,8 +41,6 @@ module Rack
37
41
  "HTTP_ACCEPT" => EXTENSIONS[file_extension]
38
42
  )
39
43
  end
40
-
41
44
  end
42
-
43
45
  end
44
46
  end
@@ -47,7 +47,6 @@ Gem::Specification.new do |gem|
47
47
  gem.add_development_dependency 'pry-byebug'
48
48
  gem.add_development_dependency 'rake', '~>10.0'
49
49
  gem.add_development_dependency 'fakefs', '~>0.4'
50
- gem.add_development_dependency 'mysql2', '~>0.3.15'
51
50
  gem.add_development_dependency 'webmock', '~>2.3'
52
51
  gem.add_development_dependency 'rspec', '~>3.0'
53
52
  gem.add_development_dependency 'rspec-its', '~>1.2'
@@ -276,11 +276,27 @@ module PactBroker
276
276
  PactBroker::Database.truncate
277
277
  end
278
278
 
279
- subject { put path, pact_content, {'CONTENT_TYPE' => 'application/json' }; last_response }
279
+ subject { put path, pact_content, { 'CONTENT_TYPE' => 'application/json' }; last_response }
280
280
 
281
281
  it "wraps the API with a database transaction" do
282
282
  expect { subject }.to_not change { PactBroker::Domain::Pacticipant.count }
283
283
  end
284
284
  end
285
+
286
+ describe "when resource is not found" do
287
+ subject { get("/does/not/exist", nil, { 'CONTENT_TYPE' => 'application/hal+json' }) }
288
+
289
+ it "returns a Content-Type of application/hal+json" do
290
+ expect(subject.headers['Content-Type']).to eq 'application/hal+json'
291
+ end
292
+
293
+ it "returns a JSON body" do
294
+ expect(subject.body).to eq ""
295
+ end
296
+
297
+ it "returns a 404" do
298
+ expect(subject.status).to eq 404
299
+ end
300
+ end
285
301
  end
286
302
  end
@@ -23,6 +23,44 @@ module PactBroker
23
23
  end
24
24
  end
25
25
 
26
+ context "when the whitelist includes *.foo.bar" do
27
+ let(:whitelist) { ["*.foo.bar"] }
28
+
29
+ it "matches host a.foo.bar" do
30
+ expect(CheckHostWhitelist.call("a.foo.bar", whitelist)).to eq whitelist
31
+ end
32
+
33
+ it "does not matche host a.b.foo.bar" do
34
+ expect(CheckHostWhitelist.call("a.b.foo.bar", whitelist)).to eq []
35
+ end
36
+
37
+ it "does not match a.foo.bar.b" do
38
+ expect(CheckHostWhitelist.call("a.foo.bar.b", whitelist)).to eq []
39
+ end
40
+
41
+ it "does not match foo.bar" do
42
+ expect(CheckHostWhitelist.call("foo.bar", whitelist)).to eq []
43
+ end
44
+
45
+ it "does not match 10.0.0.2" do
46
+ expect(CheckHostWhitelist.call("10.0.0.2", whitelist)).to eq []
47
+ end
48
+ end
49
+
50
+ context "when the whitelist includes *.2" do
51
+ it "does not match 10.0.0.2 as that's the wrong way to declare an IP range" do
52
+ expect(CheckHostWhitelist.call("10.0.0.2", ["*.0.0.2"])).to eq []
53
+ end
54
+ end
55
+
56
+ context "when the whitelist includes *.foo.*.bar" do
57
+ let(:whitelist) { ["*.foo.*.bar"] }
58
+
59
+ it "does not match host a.foo.b.bar, according to RFC 6125, section 6.4.3, subitem 1" do
60
+ expect(CheckHostWhitelist.call("a.foo.b.bar", whitelist)).to eq []
61
+ end
62
+ end
63
+
26
64
  context "when the host is localhost" do
27
65
  let(:host) { "localhost" }
28
66
 
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.27.0
4
+ version: 2.27.2
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: 2018-09-07 00:00:00.000000000 Z
13
+ date: 2018-09-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: httparty
@@ -380,20 +380,6 @@ dependencies:
380
380
  - - "~>"
381
381
  - !ruby/object:Gem::Version
382
382
  version: '0.4'
383
- - !ruby/object:Gem::Dependency
384
- name: mysql2
385
- requirement: !ruby/object:Gem::Requirement
386
- requirements:
387
- - - "~>"
388
- - !ruby/object:Gem::Version
389
- version: 0.3.15
390
- type: :development
391
- prerelease: false
392
- version_requirements: !ruby/object:Gem::Requirement
393
- requirements:
394
- - - "~>"
395
- - !ruby/object:Gem::Version
396
- version: 0.3.15
397
383
  - !ruby/object:Gem::Dependency
398
384
  name: webmock
399
385
  requirement: !ruby/object:Gem::Requirement
@@ -976,6 +962,7 @@ files:
976
962
  - lib/rack/pact_broker/accepts_html_filter.rb
977
963
  - lib/rack/pact_broker/add_pact_broker_version_header.rb
978
964
  - lib/rack/pact_broker/configurable_make_it_later.rb
965
+ - lib/rack/pact_broker/convert_404_to_hal.rb
979
966
  - lib/rack/pact_broker/convert_file_extension_to_accept_header.rb
980
967
  - lib/rack/pact_broker/database_transaction.rb
981
968
  - lib/rack/pact_broker/invalid_uri_protection.rb
@@ -1351,7 +1338,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1351
1338
  version: '0'
1352
1339
  requirements: []
1353
1340
  rubyforge_project:
1354
- rubygems_version: 2.6.11
1341
+ rubygems_version: 2.7.7
1355
1342
  signing_key:
1356
1343
  specification_version: 4
1357
1344
  summary: See description