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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c25ad9a77e76067aa77db7ac9f97aad1efde11b3f44a1ea6547a26da434bedd
4
- data.tar.gz: 29211ceda85283fb468690b305e942246b9a00afb50e10450ca5e9b4a2839d7f
3
+ metadata.gz: 619741f1ea048808a9235e1bc02a814c2d6606aed599e188c3ea99d464e2fc85
4
+ data.tar.gz: e309645da54a5ac5c898b83f8e90b5132361001724469ceabe18bf7f3195fbac
5
5
  SHA512:
6
- metadata.gz: ed39e2e15276baee291686c81c295bb18b180bc2d58240d48ef019cb1db36bcd90a05b67aa4e68c069d69b934a7e1533a1f16b22e8aec063310a1755cbacea64
7
- data.tar.gz: 127e9108db3e7b72c0ea22f1ca586152f94a6cd6c2ba0645aa5b25dbb4c7ad1cb5249c2b7dd2587339297cbeddb0452fa549b84b143c1549f8ea8b431be248aa
6
+ metadata.gz: 9e8328c22c89ee565ef34c2cff0e2ecad4aae2b9e71a9627bb6162e57e1013577fa53f65a56a217928e8d0503017b4c2508cec435ecf0c911eb257da53087f59
7
+ data.tar.gz: 49fa2e0f20b2489eb082c9bd4cd3fe1a09f4d4ddd03022676e12a91fc7779a0bab36e1a628205a0a1f29904da8292a984ef11a317bda486eed0c74f1a5d42909
@@ -7,13 +7,19 @@ module Spamtrap::Controller
7
7
 
8
8
  module ActsAsMethods
9
9
  def spamtrap(honeypot = 'spamtrap', options = {}, &block)
10
- nonce_enabled = options.delete(:nonce)
11
- nonce_timeout = options.delete(:nonce_timeout) || Spamtrap.nonce_timeout
12
- mutate_enabled = options.delete(:mutate)
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?
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Spamtrap
2
2
 
3
- VERSION = '0.3.0'
3
+ VERSION = '0.3.1'
4
4
 
5
5
  end
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'
@@ -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', to: '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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spamtrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cedric Howe