dwolla_v2 2.2.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 39bf667ecf4bf2f299a94476716f1261b092b60b
4
- data.tar.gz: 3ab3c531466c89a286b1ddf66185b2b1681b6330
2
+ SHA256:
3
+ metadata.gz: 3c41f5ce15e5ab3cf8cfdde49d2e72895ba0d00347e59b8ae7656c9653a03133
4
+ data.tar.gz: 9dd8a478e589e99716b00380ce4dbdb077ba1b4cd11def52f9766af54e0a3248
5
5
  SHA512:
6
- metadata.gz: d774e87d98bd99dbc7cc85d24557aec64c90afd92fb26f593c0c096a699e3d2359eb8d6256555fdb2b312f190e1f8701cea7b0a36d002e50b22730b5e2fff173
7
- data.tar.gz: d9f9058100884c97e1be778689af8b7b4f1a39a49abe9567c36e1ce311a0f7526054bd9832874c9b76ee84a818883e0ba0ee68d94290f1bbf3a24c4b3292f55e
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', '~> 2.0'
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(key: ENV["DWOLLA_APP_KEY"], secret: ENV["DWOLLA_APP_SECRET"])
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
- ### Using the sandbox environment (optional)
44
+ ### Integrations Authorization
41
45
 
42
- ```ruby
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(key: ENV["DWOLLA_APP_KEY"], secret: ENV["DWOLLA_APP_SECRET"]) do |config|
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::Token`s can make requests using the `#get`, `#post`, `#put`, and `#delete` methods.
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
- token.get "resource", foo: "bar"
77
+ $dwolla.get "resource", foo: "bar"
133
78
 
134
79
  # POST api.dwolla.com/resource {"foo":"bar"}
135
- token.post "resource", foo: "bar"
80
+ $dwolla.post "resource", foo: "bar"
136
81
 
137
82
  # POST api.dwolla.com/resource multipart/form-data foo=...
138
- token.post "resource", foo: Faraday::UploadIO.new("/path/to/bar.png", "image/png")
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
- token.delete "resource"
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
- token.post "customers", { firstName: "John", lastName: "Doe", email: "jd@doe.com" },
167
- { 'Idempotency-Key': 'a52fcf63-0730-41c3-96e8-7147b5d1fb01' }
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 = token.get "/"
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
- token.get "/not-found"
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
- * `DwollaV2::AccessDeniedError`
218
- * `DwollaV2::InvalidCredentialsError`
219
- * `DwollaV2::NotFoundError`
220
- * `DwollaV2::BadRequestError`
221
- * `DwollaV2::InvalidGrantError`
222
- * `DwollaV2::RequestTimeoutError`
223
- * `DwollaV2::ExpiredAccessTokenError`
224
- * `DwollaV2::InvalidRequestError`
225
- * `DwollaV2::ServerError`
226
- * `DwollaV2::ForbiddenError`
227
- * `DwollaV2::InvalidResourceStateError`
228
- * `DwollaV2::TemporarilyUnavailableError`
229
- * `DwollaV2::InvalidAccessTokenError`
230
- * `DwollaV2::InvalidScopeError`
231
- * `DwollaV2::UnauthorizedClientError`
232
- * `DwollaV2::InvalidAccountStatusError`
233
- * `DwollaV2::InvalidScopesError`
234
- * `DwollaV2::UnsupportedGrantTypeError`
235
- * `DwollaV2::InvalidApplicationStatusError`
236
- * `DwollaV2::InvalidVersionError`
237
- * `DwollaV2::UnsupportedResponseTypeError`
238
- * `DwollaV2::InvalidClientError`
239
- * `DwollaV2::MethodNotAllowedError`
240
- * `DwollaV2::ValidationError`
241
- * `DwollaV2::TooManyRequestsError`
242
- * `DwollaV2::ConflictError`
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
- * **2.2.0** - Change token url from `www.dwolla.com/oauth/v2/token` to `accounts.dwolla.com/token`
270
- * **2.1.0** - Ensure `Time.iso8601` is defined so timestamps get parsed. [#38](https://github.com/Dwolla/dwolla-v2-ruby/pull/38) (Thanks @javierjulio!)
271
- * **2.0.3** - Add `DuplicateResourceError` [#34](https://github.com/Dwolla/dwolla-v2-ruby/pull/34) (Thanks @javierjulio!)
272
- * **2.0.2** - Fix bug in [#30](https://github.com/Dwolla/dwolla-v2-ruby/pull/30) (Thanks again @sobrinho!)
273
- * **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!)
274
- * **2.0.0**
275
- * Rename `DwollaV2::Response` `#status` => `#response_status`, `#headers` => `#response_headers` to prevent
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
- * Remove support for Ruby versions < 2 ([Bump public_suffix dependency version][public-suffix]).
278
- * **1.2.3** - Implement `#empty?` on `DwollaV2::Token` to allow it to be passed to ActiveRecord constructor.
279
- * **1.2.2** - Strip domain from URLs provided to `token.*` methods.
280
- * **1.2.1** - Update sandbox URLs from uat => sandbox.
281
- * **1.2.0** - Refer to Client :id as :key in docs/public APIs for consistency.
282
- * **1.1.2** - Add support for `verified_account` and `dwolla_landing` auth flags.
283
- * **1.1.1** - Add `TooManyRequestsError` and `ConflictError` classes.
284
- * **1.1.0** - Support setting headers on a per-request basis.
285
- * **1.0.1** - Set user agent header.
286
- * **1.0.0** - Refactor `Error` class to be more like response, add ability to access keys using methods.
287
- * **0.4.0** - Refactor and document how `DwollaV2::Response` works
288
- * **0.3.1** - better `DwollaV2::Error` error messages
289
- * **0.3.0** - ISO8601 values in response body are converted to `Time` objects
290
- * **0.2.0** - Works with `attr_encrypted`
291
- * **0.1.1** - Handle 500 error with HTML response body when requesting a token
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
@@ -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", "~> 1.11"
23
- spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "rspec", "~> 3.0"
25
- spec.add_development_dependency "webmock", "~> 1.22"
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", "~> 3.4"
28
- spec.add_dependency "faraday", "~> 0.9"
29
- spec.add_dependency "faraday_middleware", "~> 0.10"
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
@@ -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
@@ -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://www.dwolla.com/oauth/v2/authenticate",
6
- :token_url => "https://accounts.dwolla.com/token",
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/oauth/v2/authenticate",
11
- :token_url => "https://accounts-sandbox.dwolla.com/token",
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, secret: secret, environment: environment
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,4 @@
1
+ module DwollaV2
2
+ class MaxNumberOfResourcesError < Error
3
+ end
4
+ 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
@@ -1,3 +1,3 @@
1
1
  module DwollaV2
2
- VERSION = "2.2.0"
2
+ VERSION = "3.1.0"
3
3
  end
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: 2.2.0
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: 2018-08-16 00:00:00.000000000 Z
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: '1.11'
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: '1.11'
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: '10.0'
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: '10.0'
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.0'
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.0'
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: '1.22'
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: '1.22'
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.4'
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.4'
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.9'
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.9'
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.10'
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.10'
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
- rubyforge_project:
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
@@ -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