money_mover 0.0.3 → 0.0.4

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
2
  SHA1:
3
- metadata.gz: f9f28c16cd835ccdab226255564ecb0bcaf9e5d4
4
- data.tar.gz: 73a7dfbfa1c0603072668b09d37547a918586b30
3
+ metadata.gz: 539a311851902d5ab85946c0722879850cd5c8b7
4
+ data.tar.gz: c6147bebb234f5b70abc1c5b276c1c22eadbc5d2
5
5
  SHA512:
6
- metadata.gz: 5d69bd6eafd2db81ca96f2b7fc419ecd8d4ab54b48c10e949f5054432d65c42e64db0a6c8db98ea748af6768536dff3589c0c7267834dba4a47bf2646c5bd07c
7
- data.tar.gz: f6e6a950ed63bb3a46fbd3c3f0cfef703fa7d1704eb3879908fbb873f52154c2fd4e08faf701f4454cd06692b564e39e4092bc33f1a7372a07ae6fb0fa9c39ef
6
+ metadata.gz: 204cb3879e4d423c4d65717c0ec4a40de1038b5f76daa6f7c64d88757270386221b35eaa69a6ee99222ad8f7c9f02fb8decc8be45e53fdf14d1c68f666d1e603
7
+ data.tar.gz: cc3a3b581cfe26aa293bbd06de1d30d36c3fd7350b9646c995051d0d921384f73ec0a4f705798f7cd9cdb271352ce54ddfa1511afdf6f9ba1da092320a24d281
data/Gemfile CHANGED
@@ -1,17 +1,3 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
-
5
- group :development do
6
- gem 'rake'
7
- gem 'rspec'
8
- gem 'webmock'
9
- gem 'shoulda-matchers'
10
- gem 'activesupport'
11
-
12
- gem 'activemodel'
13
- gem 'faraday'
14
- gem 'faraday_middleware'
15
-
16
- gem "rack-test"
17
- end
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- money_mover (0.0.1)
5
- activemodel (~> 4.2, >= 4.2.6)
6
- activesupport (~> 4.2, >= 4.2.6)
7
- faraday (~> 0.9, >= 0.9.0)
8
- faraday_middleware (~> 0.9, >= 0.9.0)
4
+ money_mover (0.0.3)
5
+ activemodel (>= 4.0, < 5.1)
6
+ activesupport (>= 4.0, < 5.1)
7
+ faraday (~> 0.9)
8
+ faraday_middleware (~> 0.9)
9
+ rack (>= 1.6, < 2.1)
9
10
 
10
11
  GEM
11
12
  remote: https://rubygems.org/
@@ -65,16 +66,12 @@ PLATFORMS
65
66
  ruby
66
67
 
67
68
  DEPENDENCIES
68
- activemodel
69
- activesupport
70
- faraday
71
- faraday_middleware
72
69
  money_mover!
73
- rack-test
74
- rake
75
- rspec
76
- shoulda-matchers
77
- webmock
70
+ rack-test (~> 0.6)
71
+ rake (~> 11.2)
72
+ rspec (~> 3.5)
73
+ shoulda-matchers (~> 3.1)
74
+ webmock (~> 2.1)
78
75
 
79
76
  BUNDLED WITH
80
77
  1.11.2
data/lib/money_mover.rb CHANGED
@@ -1,14 +1,12 @@
1
- require 'active_support/core_ext/hash'
2
- #require 'active_support/hash_with_indifferent_access'
3
-
1
+ require 'active_support/core_ext/hash' # for hash with indifferent access
2
+ require 'openssl'
3
+ require 'rack/utils'
4
4
  require 'faraday'
5
5
  require 'faraday_middleware'
6
6
  require 'active_model'
7
7
 
8
8
  require 'money_mover/version'
9
9
  require 'money_mover/standalone_errors'
10
-
11
- # dwolla
12
10
  require 'money_mover/dwolla'
13
11
 
14
12
  module MoneyMover; end
@@ -24,13 +24,14 @@ require 'money_mover/dwolla/models/transfer'
24
24
  require 'money_mover/dwolla/models/root_account'
25
25
  # customer models
26
26
  require 'money_mover/dwolla/models/customer'
27
- require 'money_mover/dwolla/models/receive_only_business_customer'
28
27
  require 'money_mover/dwolla/models/receive_only_customer'
28
+ require 'money_mover/dwolla/models/receive_only_business_customer'
29
29
  require 'money_mover/dwolla/models/unverified_customer'
30
30
  require 'money_mover/dwolla/models/unverified_business_customer'
31
31
  require 'money_mover/dwolla/models/verified_business_customer'
32
32
 
33
- # application stuff
33
+ # other stuff
34
+ require 'money_mover/dwolla/request_signature_validator'
34
35
  require 'money_mover/dwolla/models/webhook_subscription'
35
36
 
36
37
  module MoneyMover
@@ -38,7 +38,7 @@ module MoneyMover
38
38
  @resource_location = response.resource_location
39
39
  @id = response.resource_id
40
40
  else
41
- populate_errors_from_response(response)
41
+ add_errors_from response
42
42
  end
43
43
 
44
44
  errors.empty?
@@ -47,15 +47,17 @@ module MoneyMover
47
47
  def destroy
48
48
  response = @client.delete resource_endpoint
49
49
 
50
- populate_errors_from_response(response) unless response.success?
50
+ add_errors_from response unless response.success?
51
51
 
52
52
  errors.empty?
53
53
  end
54
54
 
55
55
  private
56
56
 
57
- def populate_errors_from_response(response)
58
- response.errors.each {|key, message| errors.add key, message }
57
+ def add_errors_from(model)
58
+ model.errors.each do |key, messages|
59
+ errors.add key, messages
60
+ end
59
61
  end
60
62
 
61
63
  def resource_endpoint
@@ -1,14 +1,6 @@
1
1
  module MoneyMover
2
2
  module Dwolla
3
- class ReceiveOnlyBusinessCustomer < Customer
4
- def initialize(attrs = {})
5
- attrs[:type] = 'receive-only'
6
- super attrs
7
- end
8
- private
9
-
10
- validates_presence_of :firstName, :lastName, :email
11
-
3
+ class ReceiveOnlyBusinessCustomer < ReceiveOnlyCustomer
12
4
  def create_params
13
5
  create_attrs = {
14
6
  firstName: firstName,
@@ -1,18 +1,25 @@
1
1
  module MoneyMover
2
2
  module Dwolla
3
3
  class ReceiveOnlyCustomer < Customer
4
- private
5
-
6
4
  validates_presence_of :firstName, :lastName, :email
7
5
 
6
+ def initialize(attrs = {})
7
+ super attrs.merge(type: 'receive-only')
8
+ end
9
+
10
+ private
11
+
8
12
  def create_params
9
- {
13
+ create_attrs = {
10
14
  firstName: firstName,
11
15
  lastName: lastName,
12
16
  email: email,
13
17
  type: 'receive-only',
14
- ipAddress: ipAddress
15
18
  }
19
+
20
+ create_attrs[:ipAddress] = ipAddress if ipAddress.present?
21
+
22
+ create_attrs
16
23
  end
17
24
  end
18
25
  end
@@ -0,0 +1,24 @@
1
+ module MoneyMover
2
+ module Dwolla
3
+ class RequestSignatureValidator
4
+ include ActiveModel::Model
5
+ validate :valid_request_signature
6
+
7
+ def initialize(request_body, request_headers, ach_config = Config.new)
8
+ @request_body = request_body
9
+ @ach_request_signature = request_headers['HTTP_X_REQUEST_SIGNATURE_SHA_256']
10
+ @ach_webhook_secret_key = ach_config.webhook_secret_key
11
+ end
12
+
13
+ def valid_request_signature
14
+ unless @ach_request_signature && Rack::Utils.secure_compare(signed_body, @ach_request_signature)
15
+ errors.add :base, "Request Signature Invalid"
16
+ end
17
+ end
18
+
19
+ def signed_body
20
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), @ach_webhook_secret_key, @request_body.string)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module MoneyMover
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
data/money_mover.gemspec CHANGED
@@ -15,10 +15,17 @@ Gem::Specification.new do |s|
15
15
  s.homepage = 'https://github.com/danoph/money_mover'
16
16
  s.license = 'MIT'
17
17
 
18
- s.add_dependency('faraday', '~> 0.9', '>= 0.9.0')
19
- s.add_dependency('faraday_middleware', '~> 0.9', '>= 0.9.0')
20
- s.add_dependency('activemodel', '~> 4.2', '>= 4.2.6')
21
- s.add_dependency('activesupport', '~> 4.2', '>= 4.2.6')
18
+ s.add_dependency 'faraday', '~> 0.9'
19
+ s.add_dependency 'faraday_middleware', '~> 0.9'
20
+ s.add_dependency 'activemodel', '>= 4.0', '< 5.1'
21
+ s.add_dependency 'activesupport', '>= 4.0', '< 5.1'
22
+ s.add_dependency 'rack', '>= 1.6', '< 2.1'
23
+
24
+ s.add_development_dependency 'rake', '~> 11.2'
25
+ s.add_development_dependency 'rspec', '~> 3.5'
26
+ s.add_development_dependency 'webmock', '~> 2.1'
27
+ s.add_development_dependency 'shoulda-matchers', '~> 3.1'
28
+ s.add_development_dependency 'rack-test', '~> 0.6'
22
29
 
23
30
  s.files = `git ls-files`.split("\n")
24
31
  s.test_files = `git ls-files -- spec/*`.split("\n")
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoneyMover::Dwolla::RequestSignatureValidator do
4
+ let(:event_params) {
5
+ {
6
+ id: "177dd734-3ce1-4701-8f92-9e57386d20f2",
7
+ resourceId: 'some-id',
8
+ topic: "some_topic",
9
+ timestamp: "2016-03-24T20:29:40.346Z",
10
+ _links: {
11
+ self: {href: "https://api-uat.dwolla.com/events/177dd734-3ce1-4701-8f92-9e57386d20f2"},
12
+ account: {href: "https://api-uat.dwolla.com/accounts/0f6589ac-588d-4283-81fc-325cbaa33d54"},
13
+ resource: {href: "https://api-uat.dwolla.com/funding-sources/something"},
14
+ customer: {href:"https://api-uat.dwolla.com/customers/2b4af2fe-4d2c-4a5f-8f06-898449086b7b"}
15
+ }
16
+ }
17
+ }
18
+
19
+ let(:request_body) { double 'request body', string: request_body_string }
20
+ let(:request_body_string) { Rack::Utils.build_nested_query event_params }
21
+
22
+ subject { described_class.new request_body, request_headers }
23
+
24
+ describe '#valid?' do
25
+ context 'request correctly signed' do
26
+ let(:request_headers) { dwolla_helper.webhook_signed_header(event_params) }
27
+
28
+ it 'returns true' do
29
+ expect(subject.valid?).to eq(true)
30
+ end
31
+ end
32
+ end
33
+
34
+ context 'request NOT correctly signed' do
35
+ let(:request_headers) { dwolla_helper.webhook_header }
36
+
37
+ it 'rejects the request with a 401' do
38
+ expect(subject.valid?).to eq(false)
39
+ expect(subject.errors[:base]).to eq(['Request Signature Invalid'])
40
+ end
41
+ end
42
+
43
+ context 'request DOES NOT have signature header' do
44
+ let(:request_headers) {{}}
45
+
46
+ it 'rejects the request with a 401' do
47
+ expect(subject.valid?).to eq(false)
48
+ expect(subject.errors[:base]).to eq(['Request Signature Invalid'])
49
+ end
50
+ end
51
+ end
52
+
@@ -327,4 +327,21 @@ class DwollaHelper
327
327
  def customer_url(customer_token)
328
328
  "#{customers_url}/#{customer_token}"
329
329
  end
330
+
331
+ def body_signature(body)
332
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), webhook_secret_key, body)
333
+ end
334
+
335
+ def header_signature(hash)
336
+ body_signature Rack::Utils.build_nested_query(hash)
337
+ end
338
+
339
+ def webhook_signed_header(hash)
340
+ webhook_header header_signature(hash)
341
+ end
342
+
343
+ def webhook_header(value = 'invalid')
344
+ #{ 'X-Request-Signature-Sha-256' => value } # real value from rack
345
+ { 'HTTP_X_REQUEST_SIGNATURE_SHA_256' => value }
346
+ end
330
347
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money_mover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Errante
@@ -17,9 +17,6 @@ dependencies:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.9'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 0.9.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,9 +24,6 @@ dependencies:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0.9'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 0.9.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: faraday_middleware
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -37,9 +31,6 @@ dependencies:
37
31
  - - "~>"
38
32
  - !ruby/object:Gem::Version
39
33
  version: '0.9'
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- version: 0.9.0
43
34
  type: :runtime
44
35
  prerelease: false
45
36
  version_requirements: !ruby/object:Gem::Requirement
@@ -47,49 +38,136 @@ dependencies:
47
38
  - - "~>"
48
39
  - !ruby/object:Gem::Version
49
40
  version: '0.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activemodel
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
50
45
  - - ">="
51
46
  - !ruby/object:Gem::Version
52
- version: 0.9.0
47
+ version: '4.0'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '5.1'
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '4.0'
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '5.1'
53
61
  - !ruby/object:Gem::Dependency
54
- name: activemodel
62
+ name: activesupport
55
63
  requirement: !ruby/object:Gem::Requirement
56
64
  requirements:
57
- - - "~>"
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '4.0'
68
+ - - "<"
58
69
  - !ruby/object:Gem::Version
59
- version: '4.2'
70
+ version: '5.1'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
60
75
  - - ">="
61
76
  - !ruby/object:Gem::Version
62
- version: 4.2.6
77
+ version: '4.0'
78
+ - - "<"
79
+ - !ruby/object:Gem::Version
80
+ version: '5.1'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rack
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '1.6'
88
+ - - "<"
89
+ - !ruby/object:Gem::Version
90
+ version: '2.1'
63
91
  type: :runtime
64
92
  prerelease: false
65
93
  version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '1.6'
98
+ - - "<"
99
+ - !ruby/object:Gem::Version
100
+ version: '2.1'
101
+ - !ruby/object:Gem::Dependency
102
+ name: rake
103
+ requirement: !ruby/object:Gem::Requirement
66
104
  requirements:
67
105
  - - "~>"
68
106
  - !ruby/object:Gem::Version
69
- version: '4.2'
70
- - - ">="
107
+ version: '11.2'
108
+ type: :development
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
71
113
  - !ruby/object:Gem::Version
72
- version: 4.2.6
114
+ version: '11.2'
73
115
  - !ruby/object:Gem::Dependency
74
- name: activesupport
116
+ name: rspec
75
117
  requirement: !ruby/object:Gem::Requirement
76
118
  requirements:
77
119
  - - "~>"
78
120
  - !ruby/object:Gem::Version
79
- version: '4.2'
80
- - - ">="
121
+ version: '3.5'
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
81
127
  - !ruby/object:Gem::Version
82
- version: 4.2.6
83
- type: :runtime
128
+ version: '3.5'
129
+ - !ruby/object:Gem::Dependency
130
+ name: webmock
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '2.1'
136
+ type: :development
84
137
  prerelease: false
85
138
  version_requirements: !ruby/object:Gem::Requirement
86
139
  requirements:
87
140
  - - "~>"
88
141
  - !ruby/object:Gem::Version
89
- version: '4.2'
90
- - - ">="
142
+ version: '2.1'
143
+ - !ruby/object:Gem::Dependency
144
+ name: shoulda-matchers
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '3.1'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - "~>"
155
+ - !ruby/object:Gem::Version
156
+ version: '3.1'
157
+ - !ruby/object:Gem::Dependency
158
+ name: rack-test
159
+ requirement: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - "~>"
162
+ - !ruby/object:Gem::Version
163
+ version: '0.6'
164
+ type: :development
165
+ prerelease: false
166
+ version_requirements: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - "~>"
91
169
  - !ruby/object:Gem::Version
92
- version: 4.2.6
170
+ version: '0.6'
93
171
  description: Moves Money with ACH integrations (dwolla, stripe)
94
172
  email: danoph@gmail.com
95
173
  executables: []
@@ -127,6 +205,7 @@ files:
127
205
  - lib/money_mover/dwolla/models/unverified_customer.rb
128
206
  - lib/money_mover/dwolla/models/verified_business_customer.rb
129
207
  - lib/money_mover/dwolla/models/webhook_subscription.rb
208
+ - lib/money_mover/dwolla/request_signature_validator.rb
130
209
  - lib/money_mover/dwolla/token.rb
131
210
  - lib/money_mover/standalone_errors.rb
132
211
  - lib/money_mover/version.rb
@@ -137,6 +216,7 @@ files:
137
216
  - spec/integration/money_mover/dwolla/documents/create_spec.rb
138
217
  - spec/integration/money_mover/dwolla/funding-sources/micro-deposits/initiation_spec.rb
139
218
  - spec/integration/money_mover/dwolla/funding-sources/micro-deposits/verification_spec.rb
219
+ - spec/integration/money_mover/dwolla/request_signature_validator_spec.rb
140
220
  - spec/integration/money_mover/dwolla/transfers/create_spec.rb
141
221
  - spec/lib/money_mover/dwolla/client_spec.rb
142
222
  - spec/lib/money_mover/dwolla/config_spec.rb
@@ -170,7 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
170
250
  version: '0'
171
251
  requirements: []
172
252
  rubyforge_project:
173
- rubygems_version: 2.5.1
253
+ rubygems_version: 2.6.6
174
254
  signing_key:
175
255
  specification_version: 4
176
256
  summary: Money Mover
@@ -181,6 +261,7 @@ test_files:
181
261
  - spec/integration/money_mover/dwolla/documents/create_spec.rb
182
262
  - spec/integration/money_mover/dwolla/funding-sources/micro-deposits/initiation_spec.rb
183
263
  - spec/integration/money_mover/dwolla/funding-sources/micro-deposits/verification_spec.rb
264
+ - spec/integration/money_mover/dwolla/request_signature_validator_spec.rb
184
265
  - spec/integration/money_mover/dwolla/transfers/create_spec.rb
185
266
  - spec/lib/money_mover/dwolla/client_spec.rb
186
267
  - spec/lib/money_mover/dwolla/config_spec.rb