money_mover 0.0.3 → 0.0.4

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
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