Skip to content

Commit

Permalink
Safer argument parsing (attempt 2)
Browse files Browse the repository at this point in the history
  • Loading branch information
bobjflong committed Mar 7, 2015
1 parent 6976393 commit 257347d
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 7 deletions.
7 changes: 5 additions & 2 deletions lib/stripe/account.rb
Expand Up @@ -13,7 +13,8 @@ def url
end

# @override To make id optional
def self.retrieve(id=nil, opts={})
def self.retrieve(id=ARGUMENT_NOT_PROVIDED, opts={})
id = id.equal?(ARGUMENT_NOT_PROVIDED) ? nil : Util.check_api_key!(id)
# Account used to be a singleton, where this method's signature was `(opts={})`.
# For the sake of not breaking folks who pass in an OAuth key in opts, let's lurkily
# string match for it.
Expand All @@ -22,7 +23,7 @@ def self.retrieve(id=nil, opts={})
opts = id
id = nil
end
super(id, opts)
super(id, Util.normalize_opts(opts))
end

def deauthorize(client_id, opts={})
Expand All @@ -31,5 +32,7 @@ def deauthorize(client_id, opts={})
opts.delete(:api_base) # the api_base here is a one-off, don't persist it
Util.convert_to_stripe_object(response, opts)
end

ARGUMENT_NOT_PROVIDED = Object.new
end
end
2 changes: 1 addition & 1 deletion lib/stripe/api_resource.rb
Expand Up @@ -25,7 +25,7 @@ def refresh
refresh_from(response, opts)
end

def self.retrieve(id, opts=nil)
def self.retrieve(id, opts={})
opts = Util.normalize_opts(opts)
instance = self.new(id, opts)
instance.refresh
Expand Down
2 changes: 1 addition & 1 deletion lib/stripe/singleton_api_resource.rb
Expand Up @@ -12,7 +12,7 @@ def url
end

def self.retrieve(opts={})
instance = self.new(nil, opts)
instance = self.new(nil, Util.normalize_opts(opts))
instance.refresh
instance
end
Expand Down
8 changes: 6 additions & 2 deletions lib/stripe/util.rb
Expand Up @@ -123,15 +123,19 @@ def self.flatten_params_array(value, calculated_key)
# Turn this value into an api_key and a set of headers
def self.normalize_opts(opts)
case opts
when NilClass
{}
when String
{:api_key => opts}
when Hash
check_api_key!(opts.fetch(:api_key)) if opts.has_key?(:api_key)
opts.clone
else
raise TypeError.new('normalize_opts expects a string or a hash')
end
end

def self.check_api_key!(key)
raise TypeError.new("api_key must be a string") unless key.is_a?(String)
key
end
end
end
9 changes: 9 additions & 0 deletions test/stripe/account_test.rb
Expand Up @@ -62,5 +62,14 @@ class AccountTest < Test::Unit::TestCase
end.returns(test_response({ 'stripe_user_id' => a.id }))
a.deauthorize('ca_1234', 'sk_test_1234')
end

should "reject nil api keys" do
assert_raise TypeError do
Stripe::Account.retrieve(nil)
end
assert_raise TypeError do
Stripe::Account.retrieve(:api_key => nil)
end
end
end
end
18 changes: 17 additions & 1 deletion test/stripe/api_resource_test.rb
Expand Up @@ -37,6 +37,15 @@ class ApiResourceTest < Test::Unit::TestCase
end
end

should "using a nil api key should raise an exception" do
assert_raises TypeError do
Stripe::Customer.all({}, nil)
end
assert_raises TypeError do
Stripe::Customer.all({}, { :api_key => nil })
end
end

should "specifying api credentials containing whitespace should raise an exception" do
Stripe.api_key = "key "
assert_raises Stripe::AuthenticationError do
Expand Down Expand Up @@ -454,7 +463,14 @@ class ApiResourceTest < Test::Unit::TestCase
}
})

@mock.expects(:post).once.with("#{Stripe.api_base}/v1/accounts/myid", nil, 'legal_entity[first_name]=Bob&legal_entity[last_name]=').returns(test_response({"id" => "myid"}))
@mock.expects(:post).once.with(
"#{Stripe.api_base}/v1/accounts/myid",
nil,
any_of(
'legal_entity[first_name]=Bob&legal_entity[last_name]=',
'legal_entity[last_name]=&legal_entity[first_name]=Bob'
)
).returns(test_response({"id" => "myid"}))

acct.legal_entity = {:first_name => 'Bob'}
acct.save
Expand Down
5 changes: 5 additions & 0 deletions test/stripe/util_test.rb
Expand Up @@ -25,5 +25,10 @@ class UtilTest < Test::Unit::TestCase
symbolized = Stripe::Util.symbolize_names(start)
assert_equal(finish, symbolized)
end

should "normalize_opts should reject nil keys" do
assert_raise { Stripe::Util.normalize_opts(nil) }
assert_raise { Stripe::Util.normalize_opts(:api_key => nil) }
end
end
end

0 comments on commit 257347d

Please sign in to comment.