Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Added a response_params_valid? method to check that resource response data is valid #18

Merged
merged 1 commit into from

2 participants

@JammyStuff

Also checks that the signature is valid.

James Wheatley Added a response_params_valid? method to check that resource response
data is valid (including signature)
200c948
@hmarr hmarr merged commit 200c948 into gocardless:master
@hmarr
Owner

Thanks a lot for this - merged!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 18, 2012
  1. Added a response_params_valid? method to check that resource response

    James Wheatley authored
    data is valid (including signature)
This page is out of date. Refresh to see the latest.
Showing with 73 additions and 10 deletions.
  1. +31 −10 lib/gocardless/client.rb
  2. +42 −0 spec/client_spec.rb
View
41 lib/gocardless/client.rb
@@ -220,16 +220,7 @@ def new_bill_url(params)
# @param [Hash] params the response parameters returned by the API server
# @return [Resource] the confirmed resource object
def confirm_resource(params)
- # Create a new hash in case is a HashWithIndifferentAccess (keys are
- # always a String)
- params = Utils.symbolize_keys(Hash[params])
- # Only pull out the relevant parameters, other won't be included in the
- # signature so will cause false negatives
- keys = [:resource_id, :resource_type, :resource_uri, :state, :signature]
- params = Hash[params.select { |k,v| keys.include? k }]
- (keys - [:state]).each do |key|
- raise ArgumentError, "Parameters missing #{key}" if !params.key?(key)
- end
+ params = prepare_params(params)
if signature_valid?(params)
data = {
@@ -254,6 +245,17 @@ def confirm_resource(params)
end
+ # Check that resource response data includes a valid signature.
+ #
+ # @param [Hash] params the response parameters returned by the API server
+ # @return [Boolean] true when valid, false otherwise
+ def response_params_valid?(params)
+ params = prepare_params(params)
+
+ signature_valid?(params)
+ end
+
+
# Validates the payload contents of a webhook request.
#
# @param [Hash] params the contents of payload of the webhook
@@ -310,6 +312,25 @@ def sign_params(params)
params
end
+ # Prepare a Hash of parameters for singing. Presence of required
+ # parameters is checked and the others are discarded.
+ #
+ # @param [Hash] params the parameters to be prepared for signing
+ # @return [Hash] the prepared parameters
+ def prepare_params(params)
+ # Create a new hash in case is a HashWithIndifferentAccess (keys are
+ # always a String)
+ params = Utils.symbolize_keys(Hash[params])
+ # Only pull out the relevant parameters, other won't be included in the
+ # signature so will cause false negatives
+ keys = [:resource_id, :resource_type, :resource_uri, :state, :signature]
+ params = Hash[params.select { |k,v| keys.include? k }]
+ (keys - [:state]).each do |key|
+ raise ArgumentError, "Parameters missing #{key}" if !params.key?(key)
+ end
+ params
+ end
+
# Check if a hash's :signature is valid
#
# @param [Hash] params the parameters to check
View
42 spec/client_spec.rb
@@ -333,6 +333,48 @@
end
end
+ describe "#response_params_valid?" do
+ before :each do
+ @params = {
+ :resource_id => '1',
+ :resource_uri => 'a',
+ :resource_type => 'subscription',
+ }
+ end
+
+ [:resource_id, :resource_uri, :resource_type].each do |param|
+ it "fails when :#{param} is missing" do
+ p = @params.tap { |d| d.delete(param) }
+ expect { @client.response_params_valid? p }.to raise_exception ArgumentError
+ end
+ end
+
+ it "does not fail when keys are strings in a HashWithIndiferentAccess" do
+ params = {'resource_id' => 1,
+ 'resource_uri' => 'a',
+ 'resource_type' => 'subscription',
+ 'signature' => 'foo'}
+ params_indifferent_access = HashWithIndifferentAccess.new(params)
+ expect { @client.response_params_valid? params_indifferent_access }.to_not raise_exception ArgumentError
+ end
+
+ it "rejects other params not required for the signature" do
+ @client.expects(:signature_valid?).returns(true).with(hash) do |hash|
+ !hash.keys.include?(:foo) && !hash.keys.include?('foo')
+ end
+
+ @client.response_params_valid?(@client.send(:sign_params, @params).merge('foo' => 'bar'))
+ end
+
+ it "returns false when the signature is invalid" do
+ @client.response_params_valid?({:signature => 'xxx'}.merge(@params)).should be_false
+ end
+
+ it "returns true when the signature is valid" do
+ @client.response_params_valid?(@client.send(:sign_params, @params)).should be_true
+ end
+ end
+
it "#generate_nonce should generate a random string" do
@client.send(:generate_nonce).should_not == @client.send(:generate_nonce)
end
Something went wrong with that request. Please try again.