dwolla_v2 2.2.1 → 3.0.0.beta1

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
- SHA256:
3
- metadata.gz: 8bc8a181342130ca7b8cf599646fc216fa919d591bfe3fa4e87cb3323291c212
4
- data.tar.gz: d576897427b0e71e8edb9ff909c4777ec97cae5e3e256a87922f321b8cc0a6d4
2
+ SHA1:
3
+ metadata.gz: 7963f8175eae7eb4b236c230b324b288e41a2686
4
+ data.tar.gz: 597f2b2e59fbec611faedfae85c298e3e31930a3
5
5
  SHA512:
6
- metadata.gz: e4211e5b0637710833cb0ecb26fbb5badc3976086a80242834e176ae55c5b9026fcbe4579cb6d651ce37d5c15ed13d15034660f70ebb7ba86cd350d0428e2dc3
7
- data.tar.gz: bf6121ba16fd8f23a5a1205b296aeaa0d93cb1c12bafabe3c2110823b83fc89e1d8f333ff5cd580e0bfc71401ceff99aab75a28078bfef24f08c14de14a2b7a4
6
+ metadata.gz: aa074f34b265f8bc1445b9319d98f1440977a59562941e2b1d8d6229305640893d3d2d691663738daf0db395e2addee711e9e6dc170b5e8e33db4b8396882c6f
7
+ data.tar.gz: 309c1016afee59fccd4a3052d3493c0d80009d49c7423078fbffef10c4760cd36c0e54d81804197e348e4bd275132e02515d3a232af58d3a66f95744fbb93b70
@@ -8,16 +8,23 @@ rvm:
8
8
  - 2.3.7
9
9
  - 2.4.4
10
10
  - 2.5.1
11
+ - 2.6.3
11
12
  - ruby-head
12
13
  - rbx-2
14
+ - rbx-3
15
+ - rbx-4
13
16
  - jruby
14
17
 
15
- before_install: gem install bundler -v 1.11.2
18
+ before_install: gem install bundler -v 2.0.2
16
19
 
17
20
  matrix:
18
21
  allow_failures:
19
- - rvm: 1.9.3
20
- - rvm: 2.0.0
21
- - rvm: rbx-2
22
- - rvm: jruby
22
+ - rvm: 1.9.3
23
+ - rvm: 2.0.0
24
+ - rvm: 2.1.10
25
+ - rvm: 2.2.10
26
+ - rvm: rbx-2
27
+ - rvm: rbx-3
28
+ - rvm: rbx-4
29
+ - rvm: jruby
23
30
  fast_finish: true
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.0.0.beta1'
15
15
  ```
16
16
 
17
17
  And then execute:
@@ -34,42 +34,13 @@ 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)
41
-
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/
72
-
73
44
  ### Configure Faraday (optional)
74
45
 
75
46
  DwollaV2 uses [Faraday][faraday] to make HTTP requests. You can configure your own
@@ -81,7 +52,11 @@ always include an adapter last, even if you want to use the default adapter.
81
52
 
82
53
  ```ruby
83
54
  # config/initializers/dwolla.rb
84
- $dwolla = DwollaV2::Client.new(key: ENV["DWOLLA_APP_KEY"], secret: ENV["DWOLLA_APP_SECRET"]) do |config|
55
+ $dwolla = DwollaV2::Client.new(
56
+ key: ENV["DWOLLA_APP_KEY"],
57
+ secret: ENV["DWOLLA_APP_SECRET"]
58
+ ) do |config|
59
+
85
60
  config.faraday do |faraday|
86
61
  faraday.response :logger
87
62
  faraday.adapter Faraday.default_adapter
@@ -89,71 +64,22 @@ $dwolla = DwollaV2::Client.new(key: ENV["DWOLLA_APP_KEY"], secret: ENV["DWOLLA_A
89
64
  end
90
65
  ```
91
66
 
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
67
  ## Requests
127
68
 
128
- `DwollaV2::Token`s can make requests using the `#get`, `#post`, `#put`, and `#delete` methods.
69
+ `DwollaV2::Client`s can make requests using the `#get`, `#post`, and `#delete` methods.
129
70
 
130
71
  ```ruby
131
72
  # GET api.dwolla.com/resource?foo=bar
132
- token.get "resource", foo: "bar"
73
+ $dwolla.get "resource", foo: "bar"
133
74
 
134
75
  # POST api.dwolla.com/resource {"foo":"bar"}
135
- token.post "resource", foo: "bar"
76
+ $dwolla.post "resource", foo: "bar"
136
77
 
137
78
  # 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"
79
+ $dwolla.post "resource", foo: Faraday::UploadIO.new("/path/to/bar.png", "image/png")
142
80
 
143
81
  # 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
82
+ $dwolla.delete "resource"
157
83
  ```
158
84
 
159
85
  #### Setting headers
@@ -163,8 +89,8 @@ To set additional headers on a request you can pass a `Hash` of headers as the 3
163
89
  For example:
164
90
 
165
91
  ```ruby
166
- token.post "customers", { firstName: "John", lastName: "Doe", email: "jd@doe.com" },
167
- { 'Idempotency-Key': 'a52fcf63-0730-41c3-96e8-7147b5d1fb01' }
92
+ $dwolla.post "customers", { firstName: "John", lastName: "Doe", email: "jd@doe.com" },
93
+ { 'Idempotency-Key': 'a52fcf63-0730-41c3-96e8-7147b5d1fb01' }
168
94
  ```
169
95
 
170
96
  ## Responses
@@ -172,7 +98,7 @@ token.post "customers", { firstName: "John", lastName: "Doe", email: "jd@doe.com
172
98
  Requests return a `DwollaV2::Response`.
173
99
 
174
100
  ```ruby
175
- res = token.get "/"
101
+ res = $dwolla.get "/"
176
102
  # => #<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
103
 
178
104
  res.response_status
@@ -192,7 +118,7 @@ If the server returns an error, a `DwollaV2::Error` (or one of its subclasses) w
192
118
 
193
119
  ```ruby
194
120
  begin
195
- token.get "/not-found"
121
+ $dwolla.get "/not-found"
196
122
  rescue DwollaV2::NotFoundError => e
197
123
  e
198
124
  # => #<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 +140,32 @@ end
214
140
 
215
141
  _See https://docsv2.dwolla.com/#errors for more info._
216
142
 
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/.
143
+ - `DwollaV2::AccessDeniedError`
144
+ - `DwollaV2::InvalidCredentialsError`
145
+ - `DwollaV2::NotFoundError`
146
+ - `DwollaV2::BadRequestError`
147
+ - `DwollaV2::InvalidGrantError`
148
+ - `DwollaV2::RequestTimeoutError`
149
+ - `DwollaV2::ExpiredAccessTokenError`
150
+ - `DwollaV2::InvalidRequestError`
151
+ - `DwollaV2::ServerError`
152
+ - `DwollaV2::ForbiddenError`
153
+ - `DwollaV2::InvalidResourceStateError`
154
+ - `DwollaV2::TemporarilyUnavailableError`
155
+ - `DwollaV2::InvalidAccessTokenError`
156
+ - `DwollaV2::InvalidScopeError`
157
+ - `DwollaV2::UnauthorizedClientError`
158
+ - `DwollaV2::InvalidAccountStatusError`
159
+ - `DwollaV2::InvalidScopesError`
160
+ - `DwollaV2::UnsupportedGrantTypeError`
161
+ - `DwollaV2::InvalidApplicationStatusError`
162
+ - `DwollaV2::InvalidVersionError`
163
+ - `DwollaV2::UnsupportedResponseTypeError`
164
+ - `DwollaV2::InvalidClientError`
165
+ - `DwollaV2::MethodNotAllowedError`
166
+ - `DwollaV2::ValidationError`
167
+ - `DwollaV2::TooManyRequestsError`
168
+ - `DwollaV2::ConflictError`
252
169
 
253
170
  ## Development
254
171
 
@@ -266,30 +183,31 @@ The gem is available as open source under the terms of the [MIT License](https:/
266
183
 
267
184
  ## Changelog
268
185
 
269
- * **2.2.1** - Update dependencies
270
- * **2.2.0** - Change token url from `www.dwolla.com/oauth/v2/token` to `accounts.dwolla.com/token`
271
- * **2.1.0** - Ensure `Time.iso8601` is defined so timestamps get parsed. [#38](https://github.com/Dwolla/dwolla-v2-ruby/pull/38) (Thanks @javierjulio!)
272
- * **2.0.3** - Add `DuplicateResourceError` [#34](https://github.com/Dwolla/dwolla-v2-ruby/pull/34) (Thanks @javierjulio!)
273
- * **2.0.2** - Fix bug in [#30](https://github.com/Dwolla/dwolla-v2-ruby/pull/30) (Thanks again @sobrinho!)
274
- * **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!)
275
- * **2.0.0**
276
- * Rename `DwollaV2::Response` `#status` => `#response_status`, `#headers` => `#response_headers` to prevent
186
+ - **3.0.0.beta1** - Add token management functionality to `DwollaV2::Client`
187
+ - **2.2.1** - Update dependencies
188
+ - **2.2.0** - Change token url from `www.dwolla.com/oauth/v2/token` to `accounts.dwolla.com/token`
189
+ - **2.1.0** - Ensure `Time.iso8601` is defined so timestamps get parsed. [#38](https://github.com/Dwolla/dwolla-v2-ruby/pull/38) (Thanks @javierjulio!)
190
+ - **2.0.3** - Add `DuplicateResourceError` [#34](https://github.com/Dwolla/dwolla-v2-ruby/pull/34) (Thanks @javierjulio!)
191
+ - **2.0.2** - Fix bug in [#30](https://github.com/Dwolla/dwolla-v2-ruby/pull/30) (Thanks again @sobrinho!)
192
+ - **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!)
193
+ - **2.0.0**
194
+ - Rename `DwollaV2::Response` `#status` => `#response_status`, `#headers` => `#response_headers` to prevent
277
195
  [conflicts with response body properties][response-conflicts].
278
- * Remove support for Ruby versions < 2 ([Bump public_suffix dependency version][public-suffix]).
279
- * **1.2.3** - Implement `#empty?` on `DwollaV2::Token` to allow it to be passed to ActiveRecord constructor.
280
- * **1.2.2** - Strip domain from URLs provided to `token.*` methods.
281
- * **1.2.1** - Update sandbox URLs from uat => sandbox.
282
- * **1.2.0** - Refer to Client :id as :key in docs/public APIs for consistency.
283
- * **1.1.2** - Add support for `verified_account` and `dwolla_landing` auth flags.
284
- * **1.1.1** - Add `TooManyRequestsError` and `ConflictError` classes.
285
- * **1.1.0** - Support setting headers on a per-request basis.
286
- * **1.0.1** - Set user agent header.
287
- * **1.0.0** - Refactor `Error` class to be more like response, add ability to access keys using methods.
288
- * **0.4.0** - Refactor and document how `DwollaV2::Response` works
289
- * **0.3.1** - better `DwollaV2::Error` error messages
290
- * **0.3.0** - ISO8601 values in response body are converted to `Time` objects
291
- * **0.2.0** - Works with `attr_encrypted`
292
- * **0.1.1** - Handle 500 error with HTML response body when requesting a token
196
+ - Remove support for Ruby versions < 2 ([Bump public_suffix dependency version][public-suffix]).
197
+ - **1.2.3** - Implement `#empty?` on `DwollaV2::Token` to allow it to be passed to ActiveRecord constructor.
198
+ - **1.2.2** - Strip domain from URLs provided to `token.*` methods.
199
+ - **1.2.1** - Update sandbox URLs from uat => sandbox.
200
+ - **1.2.0** - Refer to Client :id as :key in docs/public APIs for consistency.
201
+ - **1.1.2** - Add support for `verified_account` and `dwolla_landing` auth flags.
202
+ - **1.1.1** - Add `TooManyRequestsError` and `ConflictError` classes.
203
+ - **1.1.0** - Support setting headers on a per-request basis.
204
+ - **1.0.1** - Set user agent header.
205
+ - **1.0.0** - Refactor `Error` class to be more like response, add ability to access keys using methods.
206
+ - **0.4.0** - Refactor and document how `DwollaV2::Response` works
207
+ - **0.3.1** - better `DwollaV2::Error` error messages
208
+ - **0.3.0** - ISO8601 values in response body are converted to `Time` objects
209
+ - **0.2.0** - Works with `attr_encrypted`
210
+ - **0.1.1** - Handle 500 error with HTML response body when requesting a token
293
211
 
294
212
  [response-conflicts]: https://discuss.dwolla.com/t/document-change-or-more-clarifiation/3964
295
213
  [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", "~> 12.0"
24
- spec.add_development_dependency "rspec", "~> 3.0"
25
- spec.add_development_dependency "webmock", "~> 3.0"
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"
@@ -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 :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
 
@@ -77,7 +83,13 @@ module DwollaV2
77
83
  end
78
84
 
79
85
  def inspect
80
- Util.pretty_inspect self.class.name, key: id, secret: secret, environment: environment
86
+ Util.pretty_inspect self.class.name, key: id, environment: environment
81
87
  end
88
+
89
+ private
90
+
91
+ def token
92
+ @token_manager.get_token
93
+ end
82
94
  end
83
95
  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.1"
2
+ VERSION = "3.0.0.beta1"
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.1
4
+ version: 3.0.0.beta1
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-11-01 00:00:00.000000000 Z
11
+ date: 2019-08-21 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: '12.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: '12.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: '3.0'
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: '3.0'
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
@@ -164,6 +164,7 @@ files:
164
164
  - lib/dwolla_v2/response.rb
165
165
  - lib/dwolla_v2/super_hash.rb
166
166
  - lib/dwolla_v2/token.rb
167
+ - lib/dwolla_v2/token_manager.rb
167
168
  - lib/dwolla_v2/util.rb
168
169
  - lib/dwolla_v2/version.rb
169
170
  homepage: https://github.com/Dwolla/dwolla-v2-ruby
@@ -181,12 +182,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
181
182
  version: '0'
182
183
  required_rubygems_version: !ruby/object:Gem::Requirement
183
184
  requirements:
184
- - - ">="
185
+ - - ">"
185
186
  - !ruby/object:Gem::Version
186
- version: '0'
187
+ version: 1.3.1
187
188
  requirements: []
188
189
  rubyforge_project:
189
- rubygems_version: 2.7.7
190
+ rubygems_version: 2.5.2.3
190
191
  signing_key:
191
192
  specification_version: 4
192
193
  summary: Dwolla V2 Ruby client