straight-server 0.2.2 → 0.2.3

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +5 -2
  4. data/Gemfile.travis +2 -0
  5. data/README.md +46 -19
  6. data/Rakefile +5 -2
  7. data/VERSION +1 -1
  8. data/db/migrations/003_add_payment_id_to_orders.rb +1 -1
  9. data/db/migrations/004_add_description_to_orders.rb +1 -1
  10. data/db/migrations/005_add_orders_expiration_period_to_gateways.rb +1 -1
  11. data/db/migrations/006_add_check_order_status_in_db_first_to_gateways.rb +1 -1
  12. data/db/migrations/007_add_active_switcher_to_gateways.rb +1 -1
  13. data/db/migrations/008_add_order_counters_to_gateways.rb +1 -1
  14. data/db/migrations/009_add_hashed_id_to_gateways.rb +2 -2
  15. data/db/migrations/010_add_address_reusability_orders.rb +19 -0
  16. data/db/migrations/011_add_callback_data_to_orders.rb +11 -0
  17. data/db/schema.rb +55 -0
  18. data/examples/client/client.html +1 -1
  19. data/examples/client/client.js +1 -1
  20. data/lib/straight-server/config.rb +3 -1
  21. data/lib/straight-server/gateway.rb +133 -34
  22. data/lib/straight-server/initializer.rb +8 -7
  23. data/lib/straight-server/order.rb +12 -5
  24. data/lib/straight-server/orders_controller.rb +45 -13
  25. data/lib/straight-server/throttler.rb +63 -0
  26. data/lib/tasks/db.rake +42 -0
  27. data/spec/.straight/config.yml +3 -2
  28. data/spec/lib/gateway_spec.rb +88 -9
  29. data/spec/lib/order_spec.rb +8 -13
  30. data/spec/lib/orders_controller_spec.rb +36 -4
  31. data/spec/lib/throttle_spec.rb +52 -0
  32. data/straight-server.gemspec +13 -6
  33. data/templates/config.yml +19 -2
  34. metadata +22 -6
  35. data/bin/goliath.log +0 -6
  36. data/bin/goliath.log_stdout.log +0 -51
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+
4
+ RSpec.describe StraightServer::Throttler do
5
+
6
+ it 'throttles requests' do
7
+ new_config = StraightServer::Config.dup
8
+ new_config.throttle = {requests_limit: 1, period: 1}
9
+ stub_const 'StraightServer::Config', new_config
10
+ throttler1 = described_class.new(1)
11
+ throttler2 = described_class.new(2)
12
+ now = Time.now.round
13
+ Timecop.freeze(now) do
14
+ expect(throttler1.deny?('127.0.0.1')).to eq false
15
+ expect(throttler1.deny?('127.0.0.1')).to eq true
16
+ expect(throttler2.deny?('127.0.0.1')).to eq false # does not affect other gateways
17
+ end
18
+ Timecop.freeze(now + 0.5) do
19
+ expect(throttler1.deny?('127.0.0.2')).to eq false
20
+ end
21
+ Timecop.freeze(now + 1.1) do
22
+ expect(throttler1.deny?('127.0.0.2')).to eq false # new timeframe
23
+ expect(throttler1.deny?('127.0.0.2')).to eq true
24
+ expect(throttler2.deny?('127.0.0.2')).to eq false
25
+ expect(throttler1.deny?('127.0.0.1')).to eq false
26
+ expect(throttler1.deny?('127.0.0.1')).to eq true
27
+ expect(throttler2.deny?('127.0.0.1')).to eq false
28
+ end
29
+ end
30
+
31
+ it 'bans by ip' do
32
+ new_config = StraightServer::Config.dup
33
+ new_config.throttle = {requests_limit: 3, period: 1, ip_ban_duration: 30}
34
+ stub_const 'StraightServer::Config', new_config
35
+ throttler1 = described_class.new(1)
36
+ throttler2 = described_class.new(2)
37
+ 3.times { expect(throttler1.deny?('127.0.0.1')).to eq false }
38
+ banned_at = Time.now
39
+ [0, 10, 20, 30].each do |offset|
40
+ Timecop.freeze(banned_at + offset) do
41
+ expect(throttler1.deny?('127.0.0.1')).to eq true
42
+ expect(throttler2.deny?('127.0.0.1')).to eq true # affects any gateways
43
+ expect(throttler1.deny?('127.0.0.2')).to eq false
44
+ expect(throttler2.deny?('127.0.0.2')).to eq false
45
+ end
46
+ end
47
+ Timecop.freeze(banned_at + 31) do
48
+ expect(throttler1.deny?('127.0.0.1')).to eq false
49
+ expect(throttler2.deny?('127.0.0.1')).to eq false
50
+ end
51
+ end
52
+ end
@@ -2,19 +2,19 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: straight-server 0.2.2 ruby lib
5
+ # stub: straight-server 0.2.3 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "straight-server"
9
- s.version = "0.2.2"
9
+ s.version = "0.2.3"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Roman Snitko"]
14
- s.date = "2015-05-10"
14
+ s.date = "2015-05-30"
15
15
  s.description = "Accepts orders via http, returns payment info via http or streams updates via websockets, stores orders in a DB"
16
16
  s.email = "roman.snitko@gmail.com"
17
- s.executables = ["goliath.log", "goliath.log_stdout.log", "straight-console", "straight-server", "straight-server-benchmark"]
17
+ s.executables = ["straight-console", "straight-server", "straight-server-benchmark"]
18
18
  s.extra_rdoc_files = [
19
19
  "LICENSE.txt",
20
20
  "README.md"
@@ -34,8 +34,6 @@ Gem::Specification.new do |s|
34
34
  "benchmark/config.yml",
35
35
  "benchmark/default_last_keychain_id",
36
36
  "benchmark/server_secret",
37
- "bin/goliath.log",
38
- "bin/goliath.log_stdout.log",
39
37
  "bin/straight-console",
40
38
  "bin/straight-server",
41
39
  "bin/straight-server-benchmark",
@@ -48,6 +46,9 @@ Gem::Specification.new do |s|
48
46
  "db/migrations/007_add_active_switcher_to_gateways.rb",
49
47
  "db/migrations/008_add_order_counters_to_gateways.rb",
50
48
  "db/migrations/009_add_hashed_id_to_gateways.rb",
49
+ "db/migrations/010_add_address_reusability_orders.rb",
50
+ "db/migrations/011_add_callback_data_to_orders.rb",
51
+ "db/schema.rb",
51
52
  "examples/client/client.dart",
52
53
  "examples/client/client.html",
53
54
  "examples/client/client.js",
@@ -61,7 +62,9 @@ Gem::Specification.new do |s|
61
62
  "lib/straight-server/random_string.rb",
62
63
  "lib/straight-server/server.rb",
63
64
  "lib/straight-server/thread.rb",
65
+ "lib/straight-server/throttler.rb",
64
66
  "lib/straight-server/utils/hash_string_to_sym_keys.rb",
67
+ "lib/tasks/db.rake",
65
68
  "spec/.straight/config.yml",
66
69
  "spec/.straight/server_secret",
67
70
  "spec/factories.rb",
@@ -71,6 +74,7 @@ Gem::Specification.new do |s|
71
74
  "spec/lib/initializer_spec.rb",
72
75
  "spec/lib/order_spec.rb",
73
76
  "spec/lib/orders_controller_spec.rb",
77
+ "spec/lib/throttle_spec.rb",
74
78
  "spec/lib/utils/hash_string_to_sym_keys.rb",
75
79
  "spec/spec_helper.rb",
76
80
  "spec/support/custom_matchers.rb",
@@ -95,6 +99,7 @@ Gem::Specification.new do |s|
95
99
  s.add_runtime_dependency(%q<logmaster>, ["= 0.1.5"])
96
100
  s.add_runtime_dependency(%q<ruby-hmac>, [">= 0"])
97
101
  s.add_runtime_dependency(%q<httparty>, [">= 0"])
102
+ s.add_runtime_dependency(%q<money-tree>, ["= 0.9.0"])
98
103
  s.add_development_dependency(%q<bundler>, ["~> 1.0"])
99
104
  s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
100
105
  s.add_development_dependency(%q<github_api>, ["= 0.11.3"])
@@ -107,6 +112,7 @@ Gem::Specification.new do |s|
107
112
  s.add_dependency(%q<logmaster>, ["= 0.1.5"])
108
113
  s.add_dependency(%q<ruby-hmac>, [">= 0"])
109
114
  s.add_dependency(%q<httparty>, [">= 0"])
115
+ s.add_dependency(%q<money-tree>, ["= 0.9.0"])
110
116
  s.add_dependency(%q<bundler>, ["~> 1.0"])
111
117
  s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
112
118
  s.add_dependency(%q<github_api>, ["= 0.11.3"])
@@ -120,6 +126,7 @@ Gem::Specification.new do |s|
120
126
  s.add_dependency(%q<logmaster>, ["= 0.1.5"])
121
127
  s.add_dependency(%q<ruby-hmac>, [">= 0"])
122
128
  s.add_dependency(%q<httparty>, [">= 0"])
129
+ s.add_dependency(%q<money-tree>, ["= 0.9.0"])
123
130
  s.add_dependency(%q<bundler>, ["~> 1.0"])
124
131
  s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
125
132
  s.add_dependency(%q<github_api>, ["= 0.11.3"])
data/templates/config.yml CHANGED
@@ -13,9 +13,26 @@ count_orders: false
13
13
  # transaction has been made in the last seconds and Straight didn't have time to detect it?
14
14
  # This just adds a little bit more time to each expiration period.
15
15
  # So technically, you can tell your customer he's got 900 seconds to pay, yet wait additional
16
- # 30 seconds (default value) to be able to detect a late transaction
16
+ # 30 seconds (default value) to be able to detect a late transaction
17
17
  expiration_overtime: 30
18
18
 
19
+ # If you have this number of expired addresses in a row,
20
+ # the latest one of those will be reused to create a new order.
21
+ # This is because wallets that support BIP32 do a limited lookup: they
22
+ # only normally check the next 20 next addresses. Thus, the default value.
23
+ # Without address reuse, merchants may fall into a situation where they
24
+ # technically receive the money, but it's never detected by the wallet.
25
+ reuse_address_orders_threshold: 20
26
+
27
+ # Uncomment this if you want to limit orders creation rate.
28
+ # For example, if user's cat makes more than 21 new orders during 60 seconds (from the same IP and Widget),
29
+ # any user with this IP will be unable to create more orders via this Widget during those 60 seconds
30
+ # Additionally, you can block new orders creation via any Widget from throttled IP for 300 seconds
31
+ #throttle:
32
+ # requests_limit: 21
33
+ # period: 60 # in seconds
34
+ # ip_ban_duration: 300 # in seconds
35
+
19
36
  # Uncomment this if you want to use Gateway's order counters feature
20
37
  # It requires redis.
21
38
  #redis:
@@ -70,7 +87,7 @@ blockchain_adapters:
70
87
  logmaster:
71
88
  log_level: INFO # Wise to change to WARN for production
72
89
  file: straight.log
73
- raise_exception: false
90
+ raise_exception: false
74
91
  name: Straight server logger
75
92
 
76
93
  # These options bellow send you email whenever a FATAL error occurs.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: straight-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Snitko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-10 00:00:00.000000000 Z
11
+ date: 2015-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: straight
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: money-tree
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 0.9.0
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 0.9.0
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: bundler
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -168,8 +182,6 @@ description: Accepts orders via http, returns payment info via http or streams u
168
182
  via websockets, stores orders in a DB
169
183
  email: roman.snitko@gmail.com
170
184
  executables:
171
- - goliath.log
172
- - goliath.log_stdout.log
173
185
  - straight-console
174
186
  - straight-server
175
187
  - straight-server-benchmark
@@ -192,8 +204,6 @@ files:
192
204
  - benchmark/config.yml
193
205
  - benchmark/default_last_keychain_id
194
206
  - benchmark/server_secret
195
- - bin/goliath.log
196
- - bin/goliath.log_stdout.log
197
207
  - bin/straight-console
198
208
  - bin/straight-server
199
209
  - bin/straight-server-benchmark
@@ -206,6 +216,9 @@ files:
206
216
  - db/migrations/007_add_active_switcher_to_gateways.rb
207
217
  - db/migrations/008_add_order_counters_to_gateways.rb
208
218
  - db/migrations/009_add_hashed_id_to_gateways.rb
219
+ - db/migrations/010_add_address_reusability_orders.rb
220
+ - db/migrations/011_add_callback_data_to_orders.rb
221
+ - db/schema.rb
209
222
  - examples/client/client.dart
210
223
  - examples/client/client.html
211
224
  - examples/client/client.js
@@ -219,7 +232,9 @@ files:
219
232
  - lib/straight-server/random_string.rb
220
233
  - lib/straight-server/server.rb
221
234
  - lib/straight-server/thread.rb
235
+ - lib/straight-server/throttler.rb
222
236
  - lib/straight-server/utils/hash_string_to_sym_keys.rb
237
+ - lib/tasks/db.rake
223
238
  - spec/.straight/config.yml
224
239
  - spec/.straight/server_secret
225
240
  - spec/factories.rb
@@ -229,6 +244,7 @@ files:
229
244
  - spec/lib/initializer_spec.rb
230
245
  - spec/lib/order_spec.rb
231
246
  - spec/lib/orders_controller_spec.rb
247
+ - spec/lib/throttle_spec.rb
232
248
  - spec/lib/utils/hash_string_to_sym_keys.rb
233
249
  - spec/spec_helper.rb
234
250
  - spec/support/custom_matchers.rb
data/bin/goliath.log DELETED
@@ -1,6 +0,0 @@
1
- [10084:INFO] 2015-04-16 04:12:10 :: Starting server on 0.0.0.0:9696 in development mode. Watch out for stones.
2
- [10084:INFO] 2015-04-16 04:12:21 :: Status: 200, Content-Length: 963, Response Time: 24.10ms
3
- [10084:INFO] 2015-04-16 04:12:21 :: Status: 200, Content-Length: 366, Response Time: 3.11ms
4
- [10084:INFO] 2015-04-16 04:12:26 :: Status: 200, Content-Length: 963, Response Time: 2.73ms
5
- [10084:INFO] 2015-04-16 04:12:26 :: Status: 200, Content-Length: 366, Response Time: 3.25ms
6
- [10084:INFO] 2015-04-16 04:12:40 :: Status: 500, Content-Length: 99, Response Time: 3.67ms
@@ -1,51 +0,0 @@
1
-
2
- I, [2015-04-16T04:12:40.115826 #10084] INFO -- : POST /gateways/4989d549e95a757efa02023d12023ef0ffec6088dc0e4a36e630a10e67c25d06/orders
3
- {"amount"=>"1"}
4
- F, [2015-04-16T04:12:40.116493 #10084] FATAL -- : Sequel::DatabaseDisconnectError: PG::ConnectionBad: PQconsumeInput() SSL connection has been closed unexpectedly
5
-
6
- Backtrace:
7
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:180:in `async_exec'
8
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:180:in `block in execute_query'
9
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/database/logging.rb:33:in `log_yield'
10
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:180:in `execute_query'
11
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:167:in `block in execute'
12
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:143:in `check_disconnect_errors'
13
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:167:in `execute'
14
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:511:in `_execute'
15
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:335:in `block (2 levels) in execute'
16
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:532:in `check_database_errors'
17
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:335:in `block in execute'
18
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/database/connecting.rb:250:in `block in synchronize'
19
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/connection_pool/threaded.rb:98:in `hold'
20
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/database/connecting.rb:250:in `synchronize'
21
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:335:in `execute'
22
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/dataset/actions.rb:911:in `execute'
23
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/adapters/postgres.rb:655:in `fetch_rows'
24
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/dataset/actions.rb:137:in `each'
25
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/dataset/actions.rb:643:in `single_record'
26
- /home/roman/.rvm/gems/ruby-2.2.0/gems/sequel-4.21.0/lib/sequel/dataset/actions.rb:192:in `first'
27
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/gateway.rb:233:in `find_by_hashed_id'
28
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/orders_controller.rb:85:in `dispatch'
29
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/orders_controller.rb:12:in `initialize'
30
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/initializer.rb:131:in `new'
31
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/initializer.rb:131:in `block in initialize_routes'
32
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/server.rb:72:in `call'
33
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/server.rb:72:in `block in process_request'
34
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/server.rb:71:in `each'
35
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/server.rb:71:in `process_request'
36
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/server.rb:44:in `block in response'
37
- /home/roman/.rvm/gems/ruby-2.2.0/gems/logmaster-0.1.5/lib/logmaster.rb:54:in `watch_exceptions'
38
- /home/roman/Dropbox/Work/straight/server/lib/straight-server/server.rb:37:in `response'
39
- /home/roman/.rvm/gems/ruby-2.2.0/gems/goliath-1.0.4/lib/goliath/api.rb:163:in `call'
40
- /home/roman/.rvm/gems/ruby-2.2.0/gems/faye-websocket-0.9.2/lib/faye/adapters/goliath.rb:28:in `call'
41
- /home/roman/.rvm/gems/ruby-2.2.0/gems/goliath-1.0.4/lib/goliath/rack/params.rb:65:in `block in call'
42
- /home/roman/.rvm/gems/ruby-2.2.0/gems/goliath-1.0.4/lib/goliath/rack/validator.rb:40:in `safely'
43
- /home/roman/.rvm/gems/ruby-2.2.0/gems/goliath-1.0.4/lib/goliath/rack/params.rb:63:in `call'
44
- /home/roman/.rvm/gems/ruby-2.2.0/gems/goliath-1.0.4/lib/goliath/rack/async_middleware.rb:73:in `call'
45
- /home/roman/.rvm/gems/ruby-2.2.0/gems/rack-1.6.0/lib/rack/content_length.rb:15:in `call'
46
- /home/roman/.rvm/gems/ruby-2.2.0/gems/async-rack-0.5.1/lib/async_rack/async_callback.rb:114:in `call'
47
- /home/roman/.rvm/gems/ruby-2.2.0/gems/async-rack-0.5.1/lib/async_rack/async_callback.rb:91:in `block in new'
48
- /home/roman/.rvm/gems/ruby-2.2.0/gems/rack-1.6.0/lib/rack/reloader.rb:44:in `call'
49
- /home/roman/.rvm/gems/ruby-2.2.0/gems/rack-1.6.0/lib/rack/reloader.rb:44:in `call'
50
- /home/roman/.rvm/gems/ruby-2.2.0/gems/goliath-1.0.4/lib/goliath/request.rb:166:in `block in process'
51
-