61f711a1ff
This commit adds a block form of `ActiveSupport::MessageEncryptors#rotate` and `ActiveSupport::MessageVerifiers#rotate`, which supports fine-grained per-salt rotation options. The block will receive a salt, and should return an appropriate options Hash. The block may also return `nil` to indicate that the rotation does not apply to the given salt. For example: ```ruby verifiers = ActiveSupport::MessageVerifiers.new { ... } verifiers.rotate(serializer: JSON, url_safe: true) verifiers.rotate do |salt| case salt when :foo { serializer: Marshal, url_safe: true } when :bar { serializer: Marshal, url_safe: false } end end # Uses `serializer: JSON, url_safe: true`. # Falls back to `serializer: Marshal, url_safe: true`. verifiers[:foo] # Uses `serializer: JSON, url_safe: true`. # Falls back to `serializer: Marshal, url_safe: false`. verifiers[:bar] # Uses `serializer: JSON, url_safe: true`. verifiers[:baz] ``` This can be particularly useful when migrating older configurations to a unified configuration.
42 lines
1.4 KiB
Ruby
42 lines
1.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "abstract_unit"
|
|
require_relative "rotation_coordinator_tests"
|
|
|
|
class MessageVerifiersTest < ActiveSupport::TestCase
|
|
include RotationCoordinatorTests
|
|
|
|
test "can override secret generator" do
|
|
secret_generator = ->(salt) { salt + "!" }
|
|
coordinator = make_coordinator.rotate(secret_generator: secret_generator)
|
|
|
|
assert_equal "message", roundtrip("message", coordinator["salt"])
|
|
assert_nil roundtrip("message", @coordinator["salt"], coordinator["salt"])
|
|
end
|
|
|
|
test "supports arbitrary secret generator kwargs" do
|
|
secret_generator = ->(salt, foo:, bar: nil) { foo + bar }
|
|
coordinator = ActiveSupport::MessageVerifiers.new(&secret_generator)
|
|
coordinator.rotate(foo: "foo", bar: "bar")
|
|
|
|
assert_equal "message", roundtrip("message", coordinator["salt"])
|
|
end
|
|
|
|
test "supports arbitrary secret generator kwargs when using #rotate block" do
|
|
secret_generator = ->(salt, foo:, bar: nil) { foo + bar }
|
|
coordinator = ActiveSupport::MessageVerifiers.new(&secret_generator)
|
|
coordinator.rotate { { foo: "foo", bar: "bar" } }
|
|
|
|
assert_equal "message", roundtrip("message", coordinator["salt"])
|
|
end
|
|
|
|
private
|
|
def make_coordinator
|
|
ActiveSupport::MessageVerifiers.new { |salt| salt * 10 }
|
|
end
|
|
|
|
def roundtrip(message, signer, verifier = signer)
|
|
verifier.verified(signer.generate(message))
|
|
end
|
|
end
|