spamtrap 0.3.0 → 0.3.1
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 +4 -4
- data/lib/spamtrap/controller.rb +9 -3
- data/lib/spamtrap/helper.rb +2 -2
- data/lib/spamtrap/version.rb +1 -1
- data/lib/spamtrap.rb +9 -1
- data/test/controller_test.rb +103 -0
- data/test/test_helper.rb +3 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 619741f1ea048808a9235e1bc02a814c2d6606aed599e188c3ea99d464e2fc85
|
|
4
|
+
data.tar.gz: e309645da54a5ac5c898b83f8e90b5132361001724469ceabe18bf7f3195fbac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9e8328c22c89ee565ef34c2cff0e2ecad4aae2b9e71a9627bb6162e57e1013577fa53f65a56a217928e8d0503017b4c2508cec435ecf0c911eb257da53087f59
|
|
7
|
+
data.tar.gz: 49fa2e0f20b2489eb082c9bd4cd3fe1a09f4d4ddd03022676e12a91fc7779a0bab36e1a628205a0a1f29904da8292a984ef11a317bda486eed0c74f1a5d42909
|
data/lib/spamtrap/controller.rb
CHANGED
|
@@ -7,13 +7,19 @@ module Spamtrap::Controller
|
|
|
7
7
|
|
|
8
8
|
module ActsAsMethods
|
|
9
9
|
def spamtrap(honeypot = 'spamtrap', options = {}, &block)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
# Capture explicit per-call values; use sentinel so globals are read
|
|
11
|
+
# at request time rather than at class definition time.
|
|
12
|
+
nonce_opt = options.key?(:nonce) ? options.delete(:nonce) : :global
|
|
13
|
+
timeout_opt = options.key?(:nonce_timeout) ? options.delete(:nonce_timeout) : :global
|
|
14
|
+
mutate_opt = options.key?(:mutate) ? options.delete(:mutate) : :global
|
|
13
15
|
|
|
14
16
|
before_action(options) do |controller|
|
|
15
17
|
controller.instance_eval(&block) if block_given?
|
|
16
18
|
controller.instance_eval do
|
|
19
|
+
nonce_enabled = nonce_opt == :global ? Spamtrap.nonce : nonce_opt
|
|
20
|
+
nonce_timeout = timeout_opt == :global ? Spamtrap.nonce_timeout : timeout_opt
|
|
21
|
+
mutate_enabled = mutate_opt == :global ? Spamtrap.mutate : mutate_opt
|
|
22
|
+
|
|
17
23
|
spamtrap_remap_params if mutate_enabled
|
|
18
24
|
|
|
19
25
|
if params[honeypot].present?
|
data/lib/spamtrap/helper.rb
CHANGED
|
@@ -38,8 +38,8 @@ class ActionView::Helpers::FormBuilder
|
|
|
38
38
|
prepend Spamtrap::FormBuilderMutation
|
|
39
39
|
|
|
40
40
|
def spamtrap(parameter = 'spamtrap', options = {})
|
|
41
|
-
mutate = options.delete(:mutate)
|
|
42
|
-
nonce = options.delete(:nonce)
|
|
41
|
+
mutate = options.key?(:mutate) ? options.delete(:mutate) : Spamtrap.mutate
|
|
42
|
+
nonce = options.key?(:nonce) ? options.delete(:nonce) : Spamtrap.nonce
|
|
43
43
|
options.reverse_merge!(class: 'spamtrap')
|
|
44
44
|
|
|
45
45
|
if mutate
|
data/lib/spamtrap/version.rb
CHANGED
data/lib/spamtrap.rb
CHANGED
|
@@ -2,11 +2,19 @@ require 'openssl'
|
|
|
2
2
|
|
|
3
3
|
module Spamtrap
|
|
4
4
|
class << self
|
|
5
|
-
attr_writer :nonce_timeout
|
|
5
|
+
attr_writer :nonce, :nonce_timeout, :mutate
|
|
6
|
+
|
|
7
|
+
def nonce
|
|
8
|
+
@nonce || false
|
|
9
|
+
end
|
|
6
10
|
|
|
7
11
|
def nonce_timeout
|
|
8
12
|
@nonce_timeout || 1800
|
|
9
13
|
end
|
|
14
|
+
|
|
15
|
+
def mutate
|
|
16
|
+
@mutate || false
|
|
17
|
+
end
|
|
10
18
|
end
|
|
11
19
|
|
|
12
20
|
require 'spamtrap/crypto'
|
data/test/controller_test.rb
CHANGED
|
@@ -242,3 +242,106 @@ class NestedMutationControllerTest < ActionController::TestCase
|
|
|
242
242
|
assert_equal 'body;city,street', response.body
|
|
243
243
|
end
|
|
244
244
|
end
|
|
245
|
+
|
|
246
|
+
# Controller that relies entirely on global defaults (no per-call options).
|
|
247
|
+
class GlobalDefaultsController < ActionController::Base
|
|
248
|
+
spamtrap :trap_field, only: :create
|
|
249
|
+
|
|
250
|
+
def create
|
|
251
|
+
render plain: params[:comment].to_unsafe_h.keys.sort.join(',')
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Controller that explicitly overrides global defaults with false.
|
|
256
|
+
class GlobalOverrideController < ActionController::Base
|
|
257
|
+
spamtrap :trap_field, nonce: false, mutate: false, only: :create
|
|
258
|
+
|
|
259
|
+
def create
|
|
260
|
+
render plain: params[:comment].to_unsafe_h.keys.sort.join(',')
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
class GlobalDefaultsControllerTest < ActionController::TestCase
|
|
265
|
+
include MutationTestHelper
|
|
266
|
+
include NonceTestHelper
|
|
267
|
+
tests GlobalDefaultsController
|
|
268
|
+
|
|
269
|
+
setup do
|
|
270
|
+
Spamtrap.nonce = true
|
|
271
|
+
Spamtrap.mutate = true
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
teardown do
|
|
275
|
+
Spamtrap.nonce = false
|
|
276
|
+
Spamtrap.mutate = false
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def test_global_nonce_default_rejects_missing_nonce
|
|
280
|
+
post :create, params: { trap_field: '', comment: { body: 'Hello' } }
|
|
281
|
+
assert_response :ok
|
|
282
|
+
assert_empty response.body
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def test_global_nonce_default_accepts_valid_nonce
|
|
286
|
+
timestamp = Time.now.to_i
|
|
287
|
+
post :create, params: {
|
|
288
|
+
trap_field: '',
|
|
289
|
+
spamtrap_timestamp: timestamp,
|
|
290
|
+
spamtrap_nonce: generate_nonce(timestamp),
|
|
291
|
+
spamtrap_mutation_salt: MUTATION_SALT_HEX,
|
|
292
|
+
comment: { spamtrap_encrypt_field('body', MUTATION_SALT) => 'Hello' }
|
|
293
|
+
}
|
|
294
|
+
assert_response :ok
|
|
295
|
+
assert_equal 'body', response.body
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def test_global_mutate_default_remaps_encrypted_fields
|
|
299
|
+
body_token = spamtrap_encrypt_field('body', MUTATION_SALT)
|
|
300
|
+
timestamp = Time.now.to_i
|
|
301
|
+
post :create, params: {
|
|
302
|
+
trap_field: '',
|
|
303
|
+
spamtrap_timestamp: timestamp,
|
|
304
|
+
spamtrap_nonce: generate_nonce(timestamp),
|
|
305
|
+
spamtrap_mutation_salt: MUTATION_SALT_HEX,
|
|
306
|
+
comment: { body_token => 'Hello' }
|
|
307
|
+
}
|
|
308
|
+
assert_response :ok
|
|
309
|
+
assert_equal 'body', response.body
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
class GlobalOverrideControllerTest < ActionController::TestCase
|
|
314
|
+
include MutationTestHelper
|
|
315
|
+
tests GlobalOverrideController
|
|
316
|
+
|
|
317
|
+
setup do
|
|
318
|
+
Spamtrap.nonce = true
|
|
319
|
+
Spamtrap.mutate = true
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
teardown do
|
|
323
|
+
Spamtrap.nonce = false
|
|
324
|
+
Spamtrap.mutate = false
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def test_per_call_false_overrides_global_nonce
|
|
328
|
+
# No nonce params — would fail if global nonce: true were in effect
|
|
329
|
+
post :create, params: {
|
|
330
|
+
trap_field: '',
|
|
331
|
+
comment: { body: 'Hello' }
|
|
332
|
+
}
|
|
333
|
+
assert_response :ok
|
|
334
|
+
assert_equal 'body', response.body
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def test_per_call_false_overrides_global_mutate
|
|
338
|
+
# Plain field name — would be remapped if global mutate: true were in effect
|
|
339
|
+
post :create, params: {
|
|
340
|
+
trap_field: '',
|
|
341
|
+
spamtrap_mutation_salt: MUTATION_SALT_HEX,
|
|
342
|
+
comment: { body: 'Hello' }
|
|
343
|
+
}
|
|
344
|
+
assert_response :ok
|
|
345
|
+
assert_equal 'body', response.body
|
|
346
|
+
end
|
|
347
|
+
end
|
data/test/test_helper.rb
CHANGED
|
@@ -18,7 +18,9 @@ Rails.application.routes.draw do
|
|
|
18
18
|
post 'nonce/create', to: 'nonce#create'
|
|
19
19
|
post 'nonce_timeout/create', to: 'nonce_timeout#create'
|
|
20
20
|
post 'mutation/create', to: 'mutation#create'
|
|
21
|
-
post 'nested_mutation/create',
|
|
21
|
+
post 'nested_mutation/create', to: 'nested_mutation#create'
|
|
22
|
+
post 'global_defaults/create', to: 'global_defaults#create'
|
|
23
|
+
post 'global_override/create', to: 'global_override#create'
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
class ActionController::TestCase
|