Skip to content

Commit

Permalink
Merge branch 'dparpyani-dparpyani/proxy' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
philnash committed Mar 27, 2021
2 parents f77c999 + cbc02a7 commit 27aa234
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 4 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,16 @@ end
#### Custom Request Options

You can configure network requests made from the validator using `:request_options` (see [Net::HTTP.start](http://ruby-doc.org/stdlib-2.6.3/libdoc/net/http/rdoc/Net/HTTP.html#method-c-start) for the list of available options).
In addition to these options, HTTP headers can be specified with the `:headers` key, e.g. `"User-Agent"`):
In addition to these options, HTTP headers can be specified with the `:headers` key (e.g. `"User-Agent"`) and proxy can be specified with the `:proxy` key:

```ruby
validates :password, not_pwned: {
request_options: { read_timeout: 5, open_timeout: 1, headers: { "User-Agent" => "Super fun user agent" } }
request_options: {
read_timeout: 5,
open_timeout: 1,
headers: { "User-Agent" => "Super fun user agent" },
proxy: "https://username:[email protected]:12345"
}
}
```

Expand Down
1 change: 1 addition & 0 deletions lib/pwned/hashed_password.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def initialize(hashed_password, request_options={})
@request_options = Hash(request_options).dup
@request_headers = Hash(request_options.delete(:headers))
@request_headers = DEFAULT_REQUEST_HEADERS.merge(@request_headers)
@request_proxy = URI(request_options.delete(:proxy)) if request_options.key?(:proxy)
end
end
end
1 change: 1 addition & 0 deletions lib/pwned/password.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def initialize(password, request_options={})
@request_options = Hash(request_options).dup
@request_headers = Hash(request_options.delete(:headers))
@request_headers = DEFAULT_REQUEST_HEADERS.merge(@request_headers)
@request_proxy = URI(request_options.delete(:proxy)) if request_options.key?(:proxy)
end
end
end
12 changes: 10 additions & 2 deletions lib/pwned/password_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def pwned_count

private

attr_reader :request_options, :request_headers
attr_reader :request_options, :request_headers, :request_proxy

def fetch_pwned_count
for_each_response_line do |line|
Expand Down Expand Up @@ -108,7 +108,15 @@ def with_http_response(url, &block)
request.initialize_http_header(request_headers)
request_options[:use_ssl] = true

Net::HTTP.start(uri.host, uri.port, request_options) do |http|
Net::HTTP.start(
uri.host,
uri.port,
request_proxy&.host,
request_proxy&.port,
request_proxy&.user,
request_proxy&.password,
request_options
) do |http|
http.request(request, &block)
end
end
Expand Down
18 changes: 18 additions & 0 deletions spec/pwned/not_pwned_validator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ def create_model(password)
with(headers: { "User-Agent" => "Super fun user agent" })).
to have_been_made.once
end

it "allows the proxy to be set" do
Model.validates :password, not_pwned: {
request_options: { proxy: "https://username:[email protected]:12345" }
}
model = create_model("password")

# Webmock doesn't support proxy assertions (https://github.com/bblimke/webmock/issues/753)
# so we check that Net::HTTP receives the correct arguments.
expect(Net::HTTP).to receive(:start).
with("api.pwnedpasswords.com", 443, "example.com", 12345, "username", "password", anything).
and_call_original

expect(model).to_not be_valid
expect(a_request(:get, "https://api.pwnedpasswords.com/range/5BAA6").
with(headers: { "User-Agent" => "Ruby Pwned::Password #{Pwned::VERSION}" })).
to have_been_made.once
end
end

describe "when not pwned", pwned_range: "37D5B" do
Expand Down
17 changes: 17 additions & 0 deletions spec/pwned/password_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,23 @@ def verify_not_found_error(error)
with(headers: { "User-Agent" => "Super fun user agent" })).
to have_been_made.once
end

it "allows the proxy to be set" do
proxy = "https://username:[email protected]:12345"

# Webmock doesn't support proxy assertions (https://github.com/bblimke/webmock/issues/753)
# so we check that Net::HTTP receives the correct arguments.
expect(Net::HTTP).to receive(:start).
with("api.pwnedpasswords.com", 443, "example.com", 12345, "username", "password", anything).
and_call_original

password = Pwned::Password.new("password", proxy: proxy)
password.pwned?

expect(a_request(:get, "https://api.pwnedpasswords.com/range/5BAA6").
with(headers: { "User-Agent" => "Ruby Pwned::Password #{Pwned::VERSION}" })).
to have_been_made.once
end
end

describe "streaming", pwned_range: "A0F41" do
Expand Down

0 comments on commit 27aa234

Please sign in to comment.