codeclimate-services 1.9.0 → 1.9.1

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
  SHA1:
3
- metadata.gz: 4df2ee48a6422a56813233250049c38979fc3cb8
4
- data.tar.gz: 7e58584424589e2c0b2ca337a853a4ea37e7b0fa
3
+ metadata.gz: 0b0ad91d5350b519927b48a92e1f8fc799627813
4
+ data.tar.gz: 622aa41d40c4cbfe5b2ce9c9197fec5759f1226b
5
5
  SHA512:
6
- metadata.gz: ebb9f1f93b763a3858d6c66283ad1b27ff6507e57612301b71eeaf2077a1a034e808f98e787bbd9d9a9b2091f7f2e0bb397f38b3710c726bcd6907d5e37d51ad
7
- data.tar.gz: db694bb54c853bf76dab733883350b38e1c3123706104e3b2a7730ebb41618b65badd9b6c7afc4ccade4ecc26db5997935cd8c5392a052987a06c156f75ab541
6
+ metadata.gz: 3649833ef47b09d719ee72375b83cbfca664522e1f7c8aec90a9678b4a24e00c607efb71a54f78397c6635ce9e21842802420de46dda0cbf1c255644cc0be5b6
7
+ data.tar.gz: 8965dc6e356e0e29f964724ca4e53cb38a26ab585e484c36c8a82b8e485cfa4b48c56cb26f34a0ba93540a2b03e178eac187db05f3bb4581103adbb8d8fe1496
data/lib/cc/resolv.rb ADDED
@@ -0,0 +1,39 @@
1
+ require "resolv-replace"
2
+
3
+ module CC
4
+ class Resolv
5
+ def self.with_fixed_dns(dns = ::Resolv::DNS.new)
6
+ ::Resolv::DefaultResolver.replace_resolvers([Fixed.new(dns)])
7
+
8
+ yield if block_given?
9
+ ensure
10
+ # There's no way to ask what the current values are before we override
11
+ # them; hopefully going by the source is good enough.
12
+ # https://docs.ruby-lang.org/en/2.0.0/Resolv.html#method-c-new
13
+ default_resolvers = [::Resolv::Hosts.new, ::Resolv::DNS.new]
14
+ ::Resolv::DefaultResolver.replace_resolvers(default_resolvers)
15
+ end
16
+
17
+ class Fixed
18
+ def initialize(fallback)
19
+ @addresses = {}
20
+ @fallback = fallback
21
+ end
22
+
23
+ def each_address(name)
24
+ if addresses.key?(name)
25
+ yield addresses.fetch(name)
26
+ else
27
+ fallback.each_address(name) do |address|
28
+ addresses[name] ||= address
29
+ yield address
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :addresses, :fallback
37
+ end
38
+ end
39
+ end
@@ -1,4 +1,5 @@
1
1
  require "active_support/concern"
2
+ require "cc/resolv"
2
3
  require "cc/service/response_check"
3
4
  require "cc/service/safe_webhook"
4
5
 
@@ -53,13 +54,15 @@ module CC::Service::HTTP
53
54
  def http_method(method, url = nil, body = nil, headers = nil)
54
55
  block = Proc.new if block_given?
55
56
 
56
- CC::Service::SafeWebhook.ensure_safe!(url)
57
+ CC::Resolv.with_fixed_dns do
58
+ CC::Service::SafeWebhook.ensure_safe!(url)
57
59
 
58
- http.send(method) do |req|
59
- req.url(url) if url
60
- req.headers.update(headers) if headers
61
- req.body = body if body
62
- block.call req if block
60
+ http.send(method) do |req|
61
+ req.url(url) if url
62
+ req.headers.update(headers) if headers
63
+ req.body = body if body
64
+ block.call req if block
65
+ end
63
66
  end
64
67
  end
65
68
 
@@ -1,8 +1,6 @@
1
1
  require "ipaddr"
2
2
  require "uri"
3
3
 
4
- require "cc/fixed_resolv"
5
-
6
4
  module CC
7
5
  class Service
8
6
  class SafeWebhook
@@ -22,16 +20,6 @@ module CC
22
20
  instance.ensure_safe!
23
21
  end
24
22
 
25
- def self.getaddress(host)
26
- @dns ||= Resolv::DNS.new
27
- @dns.getaddress(host)
28
- end
29
-
30
- def self.setaddress(host, address)
31
- @fixed_resolv ||= CC::FixedResolv.enable!
32
- @fixed_resolv.setaddress(host, address)
33
- end
34
-
35
23
  def initialize(url)
36
24
  @url = url
37
25
  end
@@ -49,14 +37,12 @@ module CC
49
37
  attr_reader :url
50
38
 
51
39
  def internal?(host)
52
- address = self.class.getaddress(host)
53
-
54
- self.class.setaddress(host, address)
40
+ address = ::Resolv.getaddress(host)
55
41
 
56
42
  PRIVATE_ADDRESS_SUBNETS.any? do |subnet|
57
43
  subnet === IPAddr.new(address.to_s)
58
44
  end
59
- rescue Resolv::ResolvError
45
+ rescue ::Resolv::ResolvError
60
46
  true # localhost
61
47
  end
62
48
 
@@ -1,5 +1,5 @@
1
1
  module CC
2
2
  module Services
3
- VERSION = "1.9.0".freeze
3
+ VERSION = "1.9.1".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ module CC
4
+ describe Resolv do
5
+ describe ".with_fixed_dns" do
6
+ it "replaces the default resolver for the duration of the block" do
7
+ fallback = double
8
+
9
+ expect(fallback).to receive(:each_address).
10
+ with("google.com").and_yield("overridden")
11
+
12
+ Resolv.with_fixed_dns(fallback) do
13
+ expect(::Resolv.getaddress("google.com")).to eq "overridden"
14
+ expect(::Resolv.getaddress("google.com")).to eq "overridden"
15
+ end
16
+
17
+ expect(::Resolv.getaddress("google.com")).not_to eq "overridden"
18
+ end
19
+ end
20
+
21
+ describe Resolv::Fixed do
22
+ describe "#each_address" do
23
+ it "delegates to the fallback resolver and caches the first address" do
24
+ fallback = double
25
+ fixed = Resolv::Fixed.new(fallback)
26
+
27
+ allow(fallback).to receive(:each_address).
28
+ with("host").once.
29
+ and_yield("address-1").
30
+ and_yield("address-2")
31
+
32
+ yielded_1 = []
33
+ yielded_2 = []
34
+ fixed.each_address("host") { |a| yielded_1 << a }
35
+ fixed.each_address("host") { |a| yielded_2 << a }
36
+
37
+ expect(yielded_1).to eq ["address-1", "address-2"]
38
+ expect(yielded_2).to eq ["address-1"]
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -5,7 +5,7 @@ class CC::Service
5
5
  describe ".ensure_safe!" do
6
6
  it "does not allow internal URLs" do
7
7
  %w[ 127.0.0.1 192.168.0.1 10.0.1.18 ].each do |address|
8
- stub_resolv("github.com", address)
8
+ stub_resolv_getaddress("github.com", address)
9
9
 
10
10
  expect do
11
11
  SafeWebhook.ensure_safe!("https://github.com/api/v1/user")
@@ -13,29 +13,35 @@ class CC::Service
13
13
  end
14
14
  end
15
15
 
16
+ it "does not allow URLs that don't resolve via DNS" do
17
+ allow(::Resolv).to receive(:getaddress).
18
+ with("localhost").and_raise(::Resolv::ResolvError)
19
+
20
+ expect do
21
+ SafeWebhook.ensure_safe!("https://localhost/api/v1/user")
22
+ end.to raise_error(SafeWebhook::InternalWebhookError)
23
+ end
24
+
16
25
  it "allows internal URLs when configured to do so" do
17
26
  allow(ENV).to receive(:[]).
18
27
  with("CODECLIMATE_ALLOW_INTERNAL_WEBHOOKS").
19
28
  and_return("1")
20
29
 
21
- stub_resolv("github.com", "10.0.1.18")
30
+ stub_resolv_getaddress("github.com", "10.0.1.18")
22
31
 
23
32
  SafeWebhook.ensure_safe!("https://github.com/api/v1/user")
24
33
  end
25
34
 
26
35
  it "allows non-internal URLs" do
27
- stub_resolv("github.com", "1.1.1.2")
36
+ stub_resolv_getaddress("github.com", "1.1.1.2")
28
37
 
29
38
  SafeWebhook.ensure_safe!("https://github.com/api/v1/user")
30
39
  end
40
+ end
31
41
 
32
- it "ensures future dns queries get the same answer" do
33
- stub_resolv("github.com", "1.1.1.3")
34
-
35
- SafeWebhook.ensure_safe!("https://github.com/api/v1/user")
36
-
37
- expect(Resolv.getaddress("github.com").to_s).to eq "1.1.1.3"
38
- end
42
+ def stub_resolv_getaddress(host, ip)
43
+ allow(::Resolv).to receive(:getaddress).
44
+ with(host).and_return(::Resolv::IPv4.create(ip))
39
45
  end
40
46
  end
41
47
  end
@@ -1,7 +1,9 @@
1
1
  module ResolvHelpers
2
2
  def stub_resolv(name, address)
3
- allow(CC::Service::SafeWebhook).to receive(:getaddress).
4
- with(name).and_return(Resolv::IPv4.create(address))
3
+ dns = double
4
+ allow(::Resolv::DNS).to receive(:new).and_return(dns)
5
+ allow(dns).to receive(:each_address).
6
+ with(name).and_yield(Resolv::IPv4.create(address))
5
7
  end
6
8
  end
7
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codeclimate-services
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Helmkamp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-04 00:00:00.000000000 Z
11
+ date: 2016-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -149,7 +149,6 @@ files:
149
149
  - config/cacert.pem
150
150
  - config/load.rb
151
151
  - lib/axiom/types/password.rb
152
- - lib/cc/fixed_resolv.rb
153
152
  - lib/cc/formatters/linked_formatter.rb
154
153
  - lib/cc/formatters/plain_formatter.rb
155
154
  - lib/cc/formatters/snapshot_formatter.rb
@@ -160,6 +159,7 @@ files:
160
159
  - lib/cc/helpers/vulnerability_helper.rb
161
160
  - lib/cc/presenters/pull_requests_presenter.rb
162
161
  - lib/cc/pull_requests.rb
162
+ - lib/cc/resolv.rb
163
163
  - lib/cc/service.rb
164
164
  - lib/cc/service/config.rb
165
165
  - lib/cc/service/formatter.rb
@@ -192,6 +192,7 @@ files:
192
192
  - spec/axiom/types/password_spec.rb
193
193
  - spec/cc/formatters/snapshot_formatter_spec.rb
194
194
  - spec/cc/presenters/pull_requests_presenter_spec.rb
195
+ - spec/cc/resolve_spec.rb
195
196
  - spec/cc/service/asana_spec.rb
196
197
  - spec/cc/service/campfire_spec.rb
197
198
  - spec/cc/service/flowdock_spec.rb
@@ -243,6 +244,7 @@ test_files:
243
244
  - spec/axiom/types/password_spec.rb
244
245
  - spec/cc/formatters/snapshot_formatter_spec.rb
245
246
  - spec/cc/presenters/pull_requests_presenter_spec.rb
247
+ - spec/cc/resolve_spec.rb
246
248
  - spec/cc/service/asana_spec.rb
247
249
  - spec/cc/service/campfire_spec.rb
248
250
  - spec/cc/service/flowdock_spec.rb
@@ -1,29 +0,0 @@
1
- require "resolv-replace"
2
-
3
- module CC
4
- class FixedResolv < Resolv::DNS
5
- def self.enable!
6
- new.tap do |instance|
7
- Resolv::DefaultResolver.replace_resolvers([instance])
8
- end
9
- end
10
-
11
- def initialize
12
- @addresses = {}
13
- end
14
-
15
- def setaddress(name, address)
16
- addresses[name] = address
17
- end
18
-
19
- def each_address(name)
20
- if addresses.key?(name)
21
- yield addresses.fetch(name)
22
- end
23
- end
24
-
25
- private
26
-
27
- attr_reader :addresses
28
- end
29
- end