dwolla_v2 2.2.1 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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