dwolla_v2 2.2.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +35 -0
- data/README.md +75 -149
- data/dwolla_v2.gemspec +7 -7
- data/lib/dwolla_v2.rb +2 -0
- data/lib/dwolla_v2/client.rb +32 -5
- data/lib/dwolla_v2/errors/max_number_of_resources_error.rb +4 -0
- data/lib/dwolla_v2/token_manager.rb +39 -0
- data/lib/dwolla_v2/version.rb +1 -1
- metadata +26 -25
- data/.travis.yml +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3c41f5ce15e5ab3cf8cfdde49d2e72895ba0d00347e59b8ae7656c9653a03133
|
4
|
+
data.tar.gz: 9dd8a478e589e99716b00380ce4dbdb077ba1b4cd11def52f9766af54e0a3248
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa42116bb5ac4a4405c66cb12dc48186db190e3c4d7aaebdf4074c46e1feea2689b9a0242fe4200097b77df7aa1928b9eb94315a2cc57f752ca9b5fc64d783e6
|
7
|
+
data.tar.gz: 93db64cb3b5b93894fb376b2e86f17016308d1c8def962049f0e77f8fd02d93abe22577b301fefcf06dc31a2e28ad6d97695a3337f2207e715d256bd798a3c40
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [main]
|
13
|
+
pull_request:
|
14
|
+
branches: [main]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
strategy:
|
19
|
+
matrix:
|
20
|
+
os: ["ubuntu-latest"]
|
21
|
+
ruby: ["2.4", "2.5", "2.6", "2.7"]
|
22
|
+
|
23
|
+
runs-on: ${{ matrix.os }}
|
24
|
+
|
25
|
+
steps:
|
26
|
+
- uses: actions/checkout@v2
|
27
|
+
- name: Set up Ruby
|
28
|
+
# https://github.com/ruby/setup-ruby
|
29
|
+
uses: ruby/setup-ruby@v1
|
30
|
+
with:
|
31
|
+
ruby-version: ${{ matrix.ruby }}
|
32
|
+
- name: Install dependencies
|
33
|
+
run: bundle install
|
34
|
+
- name: Run tests
|
35
|
+
run: bundle exec rspec
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ Dwolla V2 Ruby client.
|
|
11
11
|
Add this line to your application's Gemfile:
|
12
12
|
|
13
13
|
```ruby
|
14
|
-
gem 'dwolla_v2', '~>
|
14
|
+
gem 'dwolla_v2', '~> 3.1'
|
15
15
|
```
|
16
16
|
|
17
17
|
And then execute:
|
@@ -34,41 +34,16 @@ Create a client using your application's consumer key and secret found on the ap
|
|
34
34
|
|
35
35
|
```ruby
|
36
36
|
# config/initializers/dwolla.rb
|
37
|
-
$dwolla = DwollaV2::Client.new(
|
37
|
+
$dwolla = DwollaV2::Client.new(
|
38
|
+
key: ENV["DWOLLA_APP_KEY"],
|
39
|
+
secret: ENV["DWOLLA_APP_SECRET"],
|
40
|
+
environment: :sandbox # defaults to :production
|
41
|
+
)
|
38
42
|
```
|
39
43
|
|
40
|
-
###
|
44
|
+
### Integrations Authorization
|
41
45
|
|
42
|
-
|
43
|
-
# config/initializers/dwolla.rb
|
44
|
-
$dwolla = DwollaV2::Client.new(key: ENV["DWOLLA_APP_KEY"], secret: ENV["DWOLLA_APP_SECRET"]) do |config|
|
45
|
-
config.environment = :sandbox
|
46
|
-
end
|
47
|
-
```
|
48
|
-
|
49
|
-
`environment=` defaults to `:production` and accepts either a String or a Symbol.
|
50
|
-
|
51
|
-
### Configure an `on_grant` callback (optional)
|
52
|
-
|
53
|
-
An `on_grant` callback is useful for storing new tokens when they are granted. For example, you
|
54
|
-
may have a `YourTokenData` ActiveRecord model that you use to store your tokens. The `on_grant`
|
55
|
-
callback is called with the `DwollaV2::Token` that was just granted by the server. You can pass
|
56
|
-
this to the `create!` method of an ActiveRecord model to create a record using the token's data.
|
57
|
-
|
58
|
-
```ruby
|
59
|
-
# config/initializers/dwolla.rb
|
60
|
-
$dwolla = DwollaV2::Client.new(key: ENV["DWOLLA_APP_KEY"], secret: ENV["DWOLLA_APP_SECRET"]) do |config|
|
61
|
-
config.on_grant {|t| YourTokenData.create!(t) }
|
62
|
-
end
|
63
|
-
```
|
64
|
-
|
65
|
-
It is highly recommended that you encrypt any token data you store using
|
66
|
-
[attr_encrypted][attr_encrypted] or [vault-rails][vault-rails] (if you use [Vault][vault]). These
|
67
|
-
are both configured in your ActiveRecord models.
|
68
|
-
|
69
|
-
[attr_encrypted]: https://github.com/attr-encrypted/attr_encrypted
|
70
|
-
[vault-rails]: https://github.com/hashicorp/vault-rails
|
71
|
-
[vault]: https://www.vaultproject.io/
|
46
|
+
Check out our [Integrations Authorization Guide](https://developers.dwolla.com/integrations/authorization).
|
72
47
|
|
73
48
|
### Configure Faraday (optional)
|
74
49
|
|
@@ -81,7 +56,11 @@ always include an adapter last, even if you want to use the default adapter.
|
|
81
56
|
|
82
57
|
```ruby
|
83
58
|
# config/initializers/dwolla.rb
|
84
|
-
$dwolla = DwollaV2::Client.new(
|
59
|
+
$dwolla = DwollaV2::Client.new(
|
60
|
+
key: ENV["DWOLLA_APP_KEY"],
|
61
|
+
secret: ENV["DWOLLA_APP_SECRET"]
|
62
|
+
) do |config|
|
63
|
+
|
85
64
|
config.faraday do |faraday|
|
86
65
|
faraday.response :logger
|
87
66
|
faraday.adapter Faraday.default_adapter
|
@@ -89,71 +68,22 @@ $dwolla = DwollaV2::Client.new(key: ENV["DWOLLA_APP_KEY"], secret: ENV["DWOLLA_A
|
|
89
68
|
end
|
90
69
|
```
|
91
70
|
|
92
|
-
## `DwollaV2::Token`
|
93
|
-
|
94
|
-
Tokens can be used to make requests to the Dwolla V2 API.
|
95
|
-
|
96
|
-
### Application tokens
|
97
|
-
|
98
|
-
Application access tokens are used to authenticate against the API on behalf of a consumer application. Application tokens can be used to access resources in the API that either belong to the application itself (`webhooks`, `events`, `webhook-subscriptions`) or the partner Account that owns the consumer application (`accounts`, `customers`, `funding-sources`, etc.). Application
|
99
|
-
tokens are obtained by using the [`client_credentials`][client_credentials] OAuth grant type:
|
100
|
-
|
101
|
-
[client_credentials]: https://tools.ietf.org/html/rfc6749#section-4.4
|
102
|
-
|
103
|
-
```ruby
|
104
|
-
application_token = $dwolla.auths.client
|
105
|
-
# => #<DwollaV2::Token client=#<DwollaV2::Client key="..." secret="..." environment=:sandbox> access_token="..." expires_in=3600 scope="...">
|
106
|
-
```
|
107
|
-
|
108
|
-
_Application tokens do not include a `refresh_token`. When an application token expires, generate
|
109
|
-
a new one using `$dwolla.auths.client`._
|
110
|
-
|
111
|
-
### Initializing a pre-existing access token:
|
112
|
-
|
113
|
-
`DwollaV2::Token`s can be initialized with the following attributes:
|
114
|
-
|
115
|
-
```ruby
|
116
|
-
$dwolla.tokens.new access_token: "...",
|
117
|
-
expires_in: 123
|
118
|
-
#<DwollaV2::Token client=#<DwollaV2::Client key="..." secret="..." environment=:sandbox> access_token="..." expires_in=123>
|
119
|
-
```
|
120
|
-
|
121
|
-
```ruby
|
122
|
-
token_data = YourTokenData.first
|
123
|
-
$dwolla.tokens.new(token_data)
|
124
|
-
```
|
125
|
-
|
126
71
|
## Requests
|
127
72
|
|
128
|
-
`DwollaV2::
|
73
|
+
`DwollaV2::Client`s can make requests using the `#get`, `#post`, and `#delete` methods.
|
129
74
|
|
130
75
|
```ruby
|
131
76
|
# GET api.dwolla.com/resource?foo=bar
|
132
|
-
|
77
|
+
$dwolla.get "resource", foo: "bar"
|
133
78
|
|
134
79
|
# POST api.dwolla.com/resource {"foo":"bar"}
|
135
|
-
|
80
|
+
$dwolla.post "resource", foo: "bar"
|
136
81
|
|
137
82
|
# POST api.dwolla.com/resource multipart/form-data foo=...
|
138
|
-
|
139
|
-
|
140
|
-
# PUT api.dwolla.com/resource {"foo":"bar"}
|
141
|
-
token.put "resource", foo: "bar"
|
83
|
+
$dwolla.post "resource", foo: Faraday::UploadIO.new("/path/to/bar.png", "image/png")
|
142
84
|
|
143
85
|
# DELETE api.dwolla.com/resource
|
144
|
-
|
145
|
-
```
|
146
|
-
|
147
|
-
Requests can also be made in parallel:
|
148
|
-
|
149
|
-
```ruby
|
150
|
-
foo, bar = nil
|
151
|
-
token.in_parallel do
|
152
|
-
foo = token.get "/foo"
|
153
|
-
bar = token.get "/bar"
|
154
|
-
end
|
155
|
-
puts foo # only ready after `in_parallel` block has executed
|
156
|
-
puts bar # only ready after `in_parallel` block has executed
|
86
|
+
$dwolla.delete "resource"
|
157
87
|
```
|
158
88
|
|
159
89
|
#### Setting headers
|
@@ -163,8 +93,8 @@ To set additional headers on a request you can pass a `Hash` of headers as the 3
|
|
163
93
|
For example:
|
164
94
|
|
165
95
|
```ruby
|
166
|
-
|
167
|
-
|
96
|
+
$dwolla.post "customers", { firstName: "John", lastName: "Doe", email: "jd@doe.com" },
|
97
|
+
{ 'Idempotency-Key': 'a52fcf63-0730-41c3-96e8-7147b5d1fb01' }
|
168
98
|
```
|
169
99
|
|
170
100
|
## Responses
|
@@ -172,7 +102,7 @@ token.post "customers", { firstName: "John", lastName: "Doe", email: "jd@doe.com
|
|
172
102
|
Requests return a `DwollaV2::Response`.
|
173
103
|
|
174
104
|
```ruby
|
175
|
-
res =
|
105
|
+
res = $dwolla.get "/"
|
176
106
|
# => #<DwollaV2::Response response_status=200 response_headers={"server"=>"cloudflare-nginx", "date"=>"Mon, 28 Mar 2016 15:30:23 GMT", "content-type"=>"application/vnd.dwolla.v1.hal+json; charset=UTF-8", "content-length"=>"150", "connection"=>"close", "set-cookie"=>"__cfduid=d9dcd0f586c166d36cbd45b992bdaa11b1459179023; expires=Tue, 28-Mar-17 15:30:23 GMT; path=/; domain=.dwolla.com; HttpOnly", "x-request-id"=>"69a4e612-5dae-4c52-a6a0-2f921e34a88a", "cf-ray"=>"28ac1f81875941e3-MSP"} {"_links"=>{"events"=>{"href"=>"https://api-sandbox.dwolla.com/events"}, "webhook-subscriptions"=>{"href"=>"https://api-sandbox.dwolla.com/webhook-subscriptions"}}}>
|
177
107
|
|
178
108
|
res.response_status
|
@@ -192,7 +122,7 @@ If the server returns an error, a `DwollaV2::Error` (or one of its subclasses) w
|
|
192
122
|
|
193
123
|
```ruby
|
194
124
|
begin
|
195
|
-
|
125
|
+
$dwolla.get "/not-found"
|
196
126
|
rescue DwollaV2::NotFoundError => e
|
197
127
|
e
|
198
128
|
# => #<DwollaV2::NotFoundError response_status=404 response_headers={"server"=>"cloudflare-nginx", "date"=>"Mon, 28 Mar 2016 15:35:32 GMT", "content-type"=>"application/vnd.dwolla.v1.hal+json; profile=\"http://nocarrier.co.uk/profiles/vnd.error/\"; charset=UTF-8", "content-length"=>"69", "connection"=>"close", "set-cookie"=>"__cfduid=da1478bfdf3e56275cd8a6a741866ccce1459179332; expires=Tue, 28-Mar-17 15:35:32 GMT; path=/; domain=.dwolla.com; HttpOnly", "access-control-allow-origin"=>"*", "x-request-id"=>"667fca74-b53d-43db-bddd-50426a011881", "cf-ray"=>"28ac270abca64207-MSP"} {"code"=>"NotFound", "message"=>"The requested resource was not found."}>
|
@@ -214,41 +144,32 @@ end
|
|
214
144
|
|
215
145
|
_See https://docsv2.dwolla.com/#errors for more info._
|
216
146
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
## Sample code
|
245
|
-
|
246
|
-
The following gist contains some sample bootstrapping code:
|
247
|
-
|
248
|
-
https://gist.github.com/sausman/df58a196b3bc0381b0e8
|
249
|
-
|
250
|
-
If you have any questions regarding your specific implementation we'll do our best to help
|
251
|
-
at https://discuss.dwolla.com/.
|
147
|
+
- `DwollaV2::AccessDeniedError`
|
148
|
+
- `DwollaV2::InvalidCredentialsError`
|
149
|
+
- `DwollaV2::NotFoundError`
|
150
|
+
- `DwollaV2::BadRequestError`
|
151
|
+
- `DwollaV2::InvalidGrantError`
|
152
|
+
- `DwollaV2::RequestTimeoutError`
|
153
|
+
- `DwollaV2::ExpiredAccessTokenError`
|
154
|
+
- `DwollaV2::InvalidRequestError`
|
155
|
+
- `DwollaV2::ServerError`
|
156
|
+
- `DwollaV2::ForbiddenError`
|
157
|
+
- `DwollaV2::InvalidResourceStateError`
|
158
|
+
- `DwollaV2::TemporarilyUnavailableError`
|
159
|
+
- `DwollaV2::InvalidAccessTokenError`
|
160
|
+
- `DwollaV2::InvalidScopeError`
|
161
|
+
- `DwollaV2::UnauthorizedClientError`
|
162
|
+
- `DwollaV2::InvalidAccountStatusError`
|
163
|
+
- `DwollaV2::InvalidScopesError`
|
164
|
+
- `DwollaV2::UnsupportedGrantTypeError`
|
165
|
+
- `DwollaV2::InvalidApplicationStatusError`
|
166
|
+
- `DwollaV2::InvalidVersionError`
|
167
|
+
- `DwollaV2::UnsupportedResponseTypeError`
|
168
|
+
- `DwollaV2::InvalidClientError`
|
169
|
+
- `DwollaV2::MethodNotAllowedError`
|
170
|
+
- `DwollaV2::ValidationError`
|
171
|
+
- `DwollaV2::TooManyRequestsError`
|
172
|
+
- `DwollaV2::ConflictError`
|
252
173
|
|
253
174
|
## Development
|
254
175
|
|
@@ -266,29 +187,34 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
266
187
|
|
267
188
|
## Changelog
|
268
189
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
190
|
+
- **3.1.0** - Added `DwollaV2::MaxNumberOfResourcesError` (Thanks @paulyeo21!). [#54](https://github.com/Dwolla/dwolla-v2-ruby/pull/54)
|
191
|
+
- **3.0.1** - Update dependencies (Thanks @sealabcore!). [#48](https://github.com/Dwolla/dwolla-v2-ruby/pull/48)
|
192
|
+
- **3.0.0** - Add integrations auth functions
|
193
|
+
- **3.0.0.beta1** - Add token management functionality to `DwollaV2::Client`
|
194
|
+
- **2.2.1** - Update dependencies
|
195
|
+
- **2.2.0** - Change token url from `www.dwolla.com/oauth/v2/token` to `accounts.dwolla.com/token`
|
196
|
+
- **2.1.0** - Ensure `Time.iso8601` is defined so timestamps get parsed. [#38](https://github.com/Dwolla/dwolla-v2-ruby/pull/38) (Thanks @javierjulio!)
|
197
|
+
- **2.0.3** - Add `DuplicateResourceError` [#34](https://github.com/Dwolla/dwolla-v2-ruby/pull/34) (Thanks @javierjulio!)
|
198
|
+
- **2.0.2** - Fix bug in [#30](https://github.com/Dwolla/dwolla-v2-ruby/pull/30) (Thanks again @sobrinho!)
|
199
|
+
- **2.0.1** - Fix bugs in [#27](https://github.com/Dwolla/dwolla-v2-ruby/pull/27) + [#28](https://github.com/Dwolla/dwolla-v2-ruby/pull/28) (Thanks @sobrinho!)
|
200
|
+
- **2.0.0**
|
201
|
+
- Rename `DwollaV2::Response` `#status` => `#response_status`, `#headers` => `#response_headers` to prevent
|
276
202
|
[conflicts with response body properties][response-conflicts].
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
203
|
+
- Remove support for Ruby versions < 2 ([Bump public_suffix dependency version][public-suffix]).
|
204
|
+
- **1.2.3** - Implement `#empty?` on `DwollaV2::Token` to allow it to be passed to ActiveRecord constructor.
|
205
|
+
- **1.2.2** - Strip domain from URLs provided to `token.*` methods.
|
206
|
+
- **1.2.1** - Update sandbox URLs from uat => sandbox.
|
207
|
+
- **1.2.0** - Refer to Client :id as :key in docs/public APIs for consistency.
|
208
|
+
- **1.1.2** - Add support for `verified_account` and `dwolla_landing` auth flags.
|
209
|
+
- **1.1.1** - Add `TooManyRequestsError` and `ConflictError` classes.
|
210
|
+
- **1.1.0** - Support setting headers on a per-request basis.
|
211
|
+
- **1.0.1** - Set user agent header.
|
212
|
+
- **1.0.0** - Refactor `Error` class to be more like response, add ability to access keys using methods.
|
213
|
+
- **0.4.0** - Refactor and document how `DwollaV2::Response` works
|
214
|
+
- **0.3.1** - better `DwollaV2::Error` error messages
|
215
|
+
- **0.3.0** - ISO8601 values in response body are converted to `Time` objects
|
216
|
+
- **0.2.0** - Works with `attr_encrypted`
|
217
|
+
- **0.1.1** - Handle 500 error with HTML response body when requesting a token
|
292
218
|
|
293
219
|
[response-conflicts]: https://discuss.dwolla.com/t/document-change-or-more-clarifiation/3964
|
294
220
|
[public-suffix]: https://github.com/Dwolla/dwolla-v2-ruby/pull/18#discussion_r108028135
|
data/dwolla_v2.gemspec
CHANGED
@@ -19,12 +19,12 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.add_development_dependency "bundler", "~>
|
23
|
-
spec.add_development_dependency "rake", "~>
|
24
|
-
spec.add_development_dependency "rspec", "~> 3.
|
25
|
-
spec.add_development_dependency "webmock", "~>
|
22
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
23
|
+
spec.add_development_dependency "rake", "~> 12.3"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.8"
|
25
|
+
spec.add_development_dependency "webmock", "~> 3.6"
|
26
26
|
|
27
|
-
spec.add_dependency "hashie", "
|
28
|
-
spec.add_dependency "faraday", "
|
29
|
-
spec.add_dependency "faraday_middleware", "
|
27
|
+
spec.add_dependency "hashie", ">= 3.6"
|
28
|
+
spec.add_dependency "faraday", ">= 0.15"
|
29
|
+
spec.add_dependency "faraday_middleware", ">= 0.13"
|
30
30
|
end
|
data/lib/dwolla_v2.rb
CHANGED
@@ -15,6 +15,7 @@ require "dwolla_v2/client"
|
|
15
15
|
require "dwolla_v2/portal"
|
16
16
|
require "dwolla_v2/auth"
|
17
17
|
require "dwolla_v2/token"
|
18
|
+
require "dwolla_v2/token_manager"
|
18
19
|
require "dwolla_v2/response"
|
19
20
|
require "dwolla_v2/error"
|
20
21
|
require "dwolla_v2/util"
|
@@ -55,6 +56,7 @@ require "dwolla_v2/errors/request_timeout_error"
|
|
55
56
|
require "dwolla_v2/errors/too_many_requests_error"
|
56
57
|
require "dwolla_v2/errors/conflict_error"
|
57
58
|
require "dwolla_v2/errors/duplicate_resource_error"
|
59
|
+
require "dwolla_v2/errors/max_number_of_resources_error"
|
58
60
|
|
59
61
|
module DwollaV2
|
60
62
|
end
|
data/lib/dwolla_v2/client.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
module DwollaV2
|
2
2
|
class Client
|
3
|
+
extend Forwardable
|
4
|
+
|
3
5
|
ENVIRONMENTS = {
|
4
6
|
:production => {
|
5
|
-
:auth_url => "https://
|
6
|
-
:token_url => "https://
|
7
|
+
:auth_url => "https://accounts.dwolla.com/auth",
|
8
|
+
:token_url => "https://api.dwolla.com/token",
|
7
9
|
:api_url => "https://api.dwolla.com"
|
8
10
|
},
|
9
11
|
:sandbox => {
|
10
|
-
:auth_url => "https://sandbox.dwolla.com/
|
11
|
-
:token_url => "https://
|
12
|
+
:auth_url => "https://accounts-sandbox.dwolla.com/auth",
|
13
|
+
:token_url => "https://api-sandbox.dwolla.com/token",
|
12
14
|
:api_url => "https://api-sandbox.dwolla.com"
|
13
15
|
}
|
14
16
|
}
|
@@ -16,16 +18,20 @@ module DwollaV2
|
|
16
18
|
attr_reader :id, :secret, :auths, :tokens
|
17
19
|
alias_method :key, :id
|
18
20
|
|
21
|
+
def_delegators :current_token, :get, :post, :delete
|
22
|
+
|
19
23
|
def initialize opts
|
20
24
|
opts[:id] ||= opts[:key]
|
21
25
|
raise ArgumentError.new ":key is required" unless opts[:id].is_a? String
|
22
26
|
raise ArgumentError.new ":secret is required" unless opts[:secret].is_a? String
|
23
27
|
@id = opts[:id]
|
24
28
|
@secret = opts[:secret]
|
29
|
+
self.environment = opts[:environment] if opts.has_key?(:environment)
|
25
30
|
yield self if block_given?
|
26
31
|
conn
|
27
32
|
@auths = Portal.new self, Auth
|
28
33
|
@tokens = Portal.new self, Token
|
34
|
+
@token_manager = TokenManager.new(self)
|
29
35
|
freeze
|
30
36
|
end
|
31
37
|
|
@@ -64,6 +70,21 @@ module DwollaV2
|
|
64
70
|
end
|
65
71
|
end
|
66
72
|
|
73
|
+
def auth(params = {})
|
74
|
+
DwollaV2::Auth.new(self, params)
|
75
|
+
end
|
76
|
+
|
77
|
+
def refresh_token(params = {})
|
78
|
+
unless params.is_a?(Hash) && params.has_key?(:refresh_token)
|
79
|
+
raise ArgumentError.new(":refresh_token is required")
|
80
|
+
end
|
81
|
+
auths.refresh(params, params)
|
82
|
+
end
|
83
|
+
|
84
|
+
def token(params = {})
|
85
|
+
tokens.new(params)
|
86
|
+
end
|
87
|
+
|
67
88
|
def auth_url
|
68
89
|
ENVIRONMENTS[environment][:auth_url]
|
69
90
|
end
|
@@ -77,7 +98,13 @@ module DwollaV2
|
|
77
98
|
end
|
78
99
|
|
79
100
|
def inspect
|
80
|
-
Util.pretty_inspect self.class.name, key: id,
|
101
|
+
Util.pretty_inspect self.class.name, key: id, environment: environment
|
81
102
|
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def current_token
|
107
|
+
@token_manager.get_token
|
108
|
+
end
|
82
109
|
end
|
83
110
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module DwollaV2
|
2
|
+
class TokenManager
|
3
|
+
def initialize(client)
|
4
|
+
@client = client
|
5
|
+
@wrapped_token = nil
|
6
|
+
@mutex = Mutex.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_token
|
10
|
+
@mutex.synchronize do
|
11
|
+
current_token = @wrapped_token || fetch_new_token()
|
12
|
+
fresh_token = current_token.is_expired? ? fetch_new_token() : current_token
|
13
|
+
@wrapped_token = fresh_token unless @wrapped_token == fresh_token
|
14
|
+
fresh_token.token
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def fetch_new_token
|
21
|
+
TokenWrapper.new(@client.auths.client)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class TokenWrapper
|
26
|
+
EXPIRES_IN_LEEWAY = 60
|
27
|
+
|
28
|
+
attr_reader :token
|
29
|
+
|
30
|
+
def initialize(token)
|
31
|
+
@token = token
|
32
|
+
@expires_at = Time.now.utc + @token.expires_in - EXPIRES_IN_LEEWAY
|
33
|
+
end
|
34
|
+
|
35
|
+
def is_expired?
|
36
|
+
@expires_at < Time.now.utc
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/dwolla_v2/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dwolla_v2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Ausman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,98 +16,98 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '12.3'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '12.3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.8'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
54
|
+
version: '3.8'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: webmock
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '3.6'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '3.6'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: hashie
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '3.
|
75
|
+
version: '3.6'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '3.
|
82
|
+
version: '3.6'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: faraday
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0.
|
89
|
+
version: '0.15'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0.
|
96
|
+
version: '0.15'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: faraday_middleware
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0.
|
103
|
+
version: '0.13'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0.
|
110
|
+
version: '0.13'
|
111
111
|
description: Dwolla V2 Ruby client
|
112
112
|
email:
|
113
113
|
- stephen@dwolla.com
|
@@ -115,9 +115,9 @@ executables: []
|
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
|
+
- ".github/workflows/ruby.yml"
|
118
119
|
- ".gitignore"
|
119
120
|
- ".rspec"
|
120
|
-
- ".travis.yml"
|
121
121
|
- Gemfile
|
122
122
|
- LICENSE.txt
|
123
123
|
- README.md
|
@@ -146,6 +146,7 @@ files:
|
|
146
146
|
- lib/dwolla_v2/errors/invalid_scope_error.rb
|
147
147
|
- lib/dwolla_v2/errors/invalid_scopes_error.rb
|
148
148
|
- lib/dwolla_v2/errors/invalid_version_error.rb
|
149
|
+
- lib/dwolla_v2/errors/max_number_of_resources_error.rb
|
149
150
|
- lib/dwolla_v2/errors/method_not_allowed_error.rb
|
150
151
|
- lib/dwolla_v2/errors/not_found_error.rb
|
151
152
|
- lib/dwolla_v2/errors/request_timeout_error.rb
|
@@ -164,6 +165,7 @@ files:
|
|
164
165
|
- lib/dwolla_v2/response.rb
|
165
166
|
- lib/dwolla_v2/super_hash.rb
|
166
167
|
- lib/dwolla_v2/token.rb
|
168
|
+
- lib/dwolla_v2/token_manager.rb
|
167
169
|
- lib/dwolla_v2/util.rb
|
168
170
|
- lib/dwolla_v2/version.rb
|
169
171
|
homepage: https://github.com/Dwolla/dwolla-v2-ruby
|
@@ -185,8 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
185
187
|
- !ruby/object:Gem::Version
|
186
188
|
version: '0'
|
187
189
|
requirements: []
|
188
|
-
|
189
|
-
rubygems_version: 2.6.13
|
190
|
+
rubygems_version: 3.0.3
|
190
191
|
signing_key:
|
191
192
|
specification_version: 4
|
192
193
|
summary: Dwolla V2 Ruby client
|
data/.travis.yml
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
rvm:
|
4
|
-
- 1.9.3
|
5
|
-
- 2.0.0
|
6
|
-
- 2.1.9
|
7
|
-
- 2.2.9
|
8
|
-
- 2.3.6
|
9
|
-
- 2.4.3
|
10
|
-
- ruby-head
|
11
|
-
- rbx-2
|
12
|
-
- jruby
|
13
|
-
|
14
|
-
before_install: gem install bundler -v 1.11.2
|
15
|
-
|
16
|
-
matrix:
|
17
|
-
allow_failures:
|
18
|
-
- rvm: 1.9.3
|
19
|
-
- rvm: 2.0.0
|
20
|
-
- rvm: rbx-2
|
21
|
-
- rvm: jruby
|
22
|
-
fast_finish: true
|