23 Commits

Author SHA1 Message Date
Anton Kropp
ab248ec691
Adding metadata header to client requests 2018-11-12 10:24:06 -08:00
Brandur
ebbce668fd Rubocop: Cap method length at 50 lines + disable module length
Remi pointed out in #666 that we basically just have to keep adding more
more onto the `Max` exception for both these rules every time we add a
new API resource.

Here I suggest that we modify the check on method length in two ways:

1. Permanently disable the cop on `Util.object_classes`. This is just
   going to keep growing until we change are approach to it.
2. Choose a more reasonable maximum of 50 lines for elsewhere (IMO, the
   default of 10 is just too short). Most of our methods already come in
   below this, but there's a couple outliers like `#execute_request` in
   `StripeClient`. If we knock over some of those, we could lower this
   number again, but I suspect that we'd probably want somewhere closer
   to 30 (instead of 10) event then.

I also disable the check on module length completely. I'm not convinced
this is a very good heuristic for code quality.
2018-07-27 17:13:07 -07:00
Remi Jannel
4c39c35fd8 Add support for ScheduledQueryRun 2018-07-27 19:14:37 -04:00
Remi Jannel
04ae411754 Add support for Issuing resources 2018-07-26 13:35:50 -04:00
Olivier Bellone
73eb3fec77
Regenerate .rubocop_todo.yml 2018-07-19 14:23:18 +02:00
zach wick
ab3949b8da Adds support for 'partner_id' in 'set_app_info' (#658)
* Adds support for 'partner_id' in 'set_app_info'

Signed-off-by: zach wick <zwick@stripe.com>
2018-06-28 08:55:58 -07:00
Remi Jannel
201f9c29f4 Add support for the PaymentIntent resource
This feature is gated so the tests are stubbed for now
2018-06-27 19:24:23 -04:00
Fay Wu
6ce45193d2 Add support for v1/issuer_fraud_records endpoints (#645) 2018-05-09 14:55:10 -07:00
Brandur
3a2724bfcc Merge query parameters coming from path with params argument
If specifying both query parameters in a path/URL down to Faraday (e.g.,
`/v1/invoices/upcoming?coupon=25OFF`) _and_ query parameters in a hash
(e.g., `{ customer: "cus_123" }`), it will silently overwrite the ones
in the path with the ones in the hash. This can cause problems where
some critical parameters are discarded and causes an error, as seen in
issue #646.

This patch modifies `#execute_request` so that before going out to
Faraday we check whether the incoming path has query parameters. If it
does, we decode them and add them to our `query_params` hash so that
all parameters from either place are preserved.

Fixes #646.
2018-05-07 14:51:25 -07:00
Alexander Thiemann
c066c9c5f8 flexible billing primitives and tests 2018-04-11 13:29:24 -07:00
Brandur
256556efa0 Fix replacement of non-metadata embedded StripeObjects
So we have a bit of a problem right now when it comes to replacing a
`StripeObject` that's embedded in an API resource.

Most of the time when someone does this, they want to _replace_ an
object embedded in another object. Take setting a source on a
subscription for example:

``` ruby
subscription.source = {
  object: 'card',
  number: 123,
}
subscription.save
```

In the case above, the serialized parameters should come out as:

```
source[object]=card&source[number]=123
```

That should apply even if the previous source had something else set on
it which we're not going to set this time -- say an optional parameter
like `source[address_state]`. Those should not be present at all in the
final serialized parameters.

(Another example is setting a `payout_schedule` as seen in #631 which is
PR is intended to address.)

There is an exception to this rule in the form of metadata though.
Metadata is a bit of a strange case in that the API will treat it as
additive, so if we send `metadata[foo]`, that will set the `foo` key,
but it won't overwrite any other keys that were already present.

This is a problem because when a user fully sets `metadata` to a new
object in Ruby, what they're probably trying to do is _replace_ it
rather than add to it. For example:

``` ruby
subscription.metadata
=> { old: 'bar' }

subscription.metadata = {
  new: 'baz'
}
subscription.save
```

To accomplish what the user is probably trying to do, we actually need
to send `metadata[old]=&metadata[new]=baz` so that we empty the value of
`old` while simultaneously setting `new` to `baz`.

In summary, metadata behaves different from other embedded objects in a
fairly fundamental way, and because the code is currently only set up to
handle the metadata case, it's not behaving correctly when other types
of objects are being set. A lot of the time emptying values like we do
for `metadata` is benign, but as we've seen in #631, sometimes it's not.

In this patch, I modify serialization to only empty out object values
when we see that parameter is `metadata`.

I'm really not crazy about the implementation here _at all_, but I'm
having trouble thinking of a better way to do it. One possibility is to
introduce a new class annotation like `empty_embedded_object :metadata`,
but that will have to go everywhere and might be error-prone in case
someone forgets it on a new resource type. If anyone has a suggestion
for an alternative (or can let me know if I'm missing something), I'd
love to hear it.

This PR is an alternate to #631.
2018-04-03 16:52:14 -07:00
Olivier Bellone
3805968741
Add support for code attribute on all Stripe exceptions 2018-02-23 19:02:26 +01:00
Jamu Kakar
0be22683a3 Add support for /v1/topups endpoints. 2018-02-16 15:03:46 -08:00
Brandur
8b73853b6b A block and a class got longer so extend the exceptions for Rubocop 2017-12-07 17:42:39 -08:00
Olivier Bellone
b153b39203
Add support for exchange_rates API requests 2017-10-31 10:25:18 +01:00
Olivier Bellone
c455be74d4
Add support for listing source_transactions 2017-10-26 15:43:34 +02:00
Brandur
b4e64969cc Don't persist idempotency_key option between API requests
Excludes `idempotency_key` from opts to persist between API requests.
Obviously the same idempotency key is not something that we ever want to
use again.

Fixes #598.
2017-10-16 13:00:32 -07:00
Olivier Bellone
a210c5cd76
Ensure that each thread has its own client 2017-10-12 18:20:13 +02:00
Brandur
3f454495bf Merge pull request #586 from stripe/brandur-remove-marshal
Implement deep copy for StripeObject and remove marshal/unmarshal
2017-09-29 07:13:32 -07:00
Brandur
80d85a522c Implement deep copy for StripeObject and remove marshal/unmarshal
We were previously using a bit of a hack to get a free deep copy
implementation through Ruby's marshaling framework. Lint call this out
as a security problem though, and rightfully so: when combined with
unsanitized user input, unmarshaling can result in very serious security
breaches involving arbitrary code execution.

This patch removes all uses of marshal/unmarshal in favor of
implementing a deep copy method for `StripeObject`. I also reworked some
of the constants around what keys are available for `opts`. I'm still
not completely happy with the results, but I think it's going to need a
slightly larger refactor in order to get somewhere truly good.

There is what could be a breaking change for people doing non-standard
stuff with the library: the opts that we copy with an object are now
whitelisted, so if they were being used to pass around extraneous data,
that might not work as expected anymore. But because this is a contract
that we never committed to, I don't think I'd bump the major version for
change.
2017-09-28 11:02:20 -07:00
Brandur
cb198baaa3 Remove Rubocop TODO around guard clauses
Removes Rubocop TODO around guard clauses and fixes the outstanding
offenses.

This is starting to get into territory that feels of more dubious value
to me, but at least it did get me writing a couple more tests, so let's
see how it goes by keeping this on.
2017-09-28 09:32:44 -07:00
Brandur
7f85eea3ee Fix low hanging Rubocop TODOs
I wanted to see what fixing Rubocop TODOs was like, so I tried to
eliminate all the easy ones. Most of these were pretty easy, and the
changes required are relatively minimal.

Some of the stuff left is harder. Pretty much everything under
`Metrics/*` is going to be a pretty big yak shave. A few of the others
are just going to need a little more work (e.g. `Style/ClassVars` and
`Style/GuardClause`). Going to stop here for now.
2017-09-27 15:07:18 -07:00
Olivier Bellone
e02ff7f849
Start using RuboCop for linting 2017-09-27 21:28:25 +02:00