mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Infer options from the primary verifier.
Spares users from passing in non-changing values explicitly. [ Michael Coyne & Kasper Timm Hansen ]
This commit is contained in:
parent
92afe55b17
commit
20ba2e762c
3 changed files with 27 additions and 12 deletions
|
@ -3,9 +3,10 @@
|
|||
module ActiveSupport
|
||||
module Messages
|
||||
module Rotator # :nodoc:
|
||||
def initialize(*args)
|
||||
def initialize(*, **options)
|
||||
super
|
||||
|
||||
@options = options
|
||||
@rotations = []
|
||||
end
|
||||
|
||||
|
@ -24,10 +25,12 @@ module ActiveSupport
|
|||
|
||||
private
|
||||
def create_rotation(raw_key: nil, raw_signed_key: nil, **options)
|
||||
options[:cipher] ||= @cipher
|
||||
|
||||
self.class.new \
|
||||
raw_key || extract_key(options),
|
||||
raw_signed_key || extract_signing_key(options),
|
||||
options.slice(:cipher, :digest, :serializer)
|
||||
@options.merge(options.slice(:cipher, :digest, :serializer))
|
||||
end
|
||||
|
||||
def extract_key(cipher:, salt:, key_generator: nil, secret: nil, **)
|
||||
|
@ -53,8 +56,8 @@ module ActiveSupport
|
|||
end
|
||||
|
||||
private
|
||||
def create_rotation(raw_key: nil, digest: nil, serializer: nil, **options)
|
||||
self.class.new(raw_key || extract_key(options), digest: digest, serializer: serializer)
|
||||
def create_rotation(raw_key: nil, **options)
|
||||
self.class.new(raw_key || extract_key(options), @options.merge(options.slice(:digest, :serializer)))
|
||||
end
|
||||
|
||||
def extract_key(key_generator: nil, secret: nil, salt:)
|
||||
|
|
|
@ -121,11 +121,23 @@ class MessageEncryptorTest < ActiveSupport::TestCase
|
|||
old_message = old_encryptor.encrypt_and_sign("message encrypted with old raw key")
|
||||
|
||||
encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm")
|
||||
encryptor.rotate raw_key: old_raw_key, cipher: "aes-256-gcm"
|
||||
encryptor.rotate raw_key: old_raw_key
|
||||
|
||||
assert_equal "message encrypted with old raw key", encryptor.decrypt_and_verify(old_message)
|
||||
end
|
||||
|
||||
def test_rotating_serializer
|
||||
old_raw_key = SecureRandom.random_bytes(32)
|
||||
|
||||
old_message = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm", serializer: JSON).
|
||||
encrypt_and_sign(ahoy: :hoy)
|
||||
|
||||
encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm", serializer: JSON)
|
||||
encryptor.rotate raw_key: old_raw_key
|
||||
|
||||
assert_equal({ "ahoy" => "hoy" }, encryptor.decrypt_and_verify(old_message))
|
||||
end
|
||||
|
||||
def test_with_rotated_secret_and_salt
|
||||
old_secret, old_salt = SecureRandom.random_bytes(32), "old salt"
|
||||
old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt, 32)
|
||||
|
@ -134,7 +146,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase
|
|||
old_message = old_encryptor.encrypt_and_sign("message encrypted with old secret and salt")
|
||||
|
||||
encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm")
|
||||
encryptor.rotate secret: old_secret, salt: old_salt, cipher: "aes-256-gcm"
|
||||
encryptor.rotate secret: old_secret, salt: old_salt
|
||||
|
||||
assert_equal "message encrypted with old secret and salt", encryptor.decrypt_and_verify(old_message)
|
||||
end
|
||||
|
@ -147,7 +159,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase
|
|||
old_message = old_encryptor.encrypt_and_sign("message encrypted with old key generator and salt")
|
||||
|
||||
encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm")
|
||||
encryptor.rotate key_generator: old_key_gen, salt: old_salt, cipher: "aes-256-gcm"
|
||||
encryptor.rotate key_generator: old_key_gen, salt: old_salt
|
||||
|
||||
assert_equal "message encrypted with old key generator and salt", encryptor.decrypt_and_verify(old_message)
|
||||
end
|
||||
|
@ -227,7 +239,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase
|
|||
"message encrypted with old secret, salt, and metadata", purpose: "rotation")
|
||||
|
||||
encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm")
|
||||
encryptor.rotate secret: old_secret, salt: old_salt, cipher: "aes-256-gcm"
|
||||
encryptor.rotate secret: old_secret, salt: old_salt
|
||||
|
||||
assert_equal "message encrypted with old secret, salt, and metadata",
|
||||
encryptor.decrypt_and_verify(old_message, purpose: "rotation")
|
||||
|
|
|
@ -99,7 +99,7 @@ class MessageVerifierTest < ActiveSupport::TestCase
|
|||
old_message = old_verifier.generate("message verified with old raw key")
|
||||
|
||||
verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1")
|
||||
verifier.rotate raw_key: old_raw_key, digest: "SHA1"
|
||||
verifier.rotate raw_key: old_raw_key
|
||||
|
||||
assert_equal "message verified with old raw key", verifier.verified(old_message)
|
||||
end
|
||||
|
@ -112,7 +112,7 @@ class MessageVerifierTest < ActiveSupport::TestCase
|
|||
old_message = old_verifier.generate("message verified with old secret and salt")
|
||||
|
||||
verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1")
|
||||
verifier.rotate secret: old_secret, salt: old_salt, digest: "SHA1"
|
||||
verifier.rotate secret: old_secret, salt: old_salt
|
||||
|
||||
assert_equal "message verified with old secret and salt", verifier.verified(old_message)
|
||||
end
|
||||
|
@ -125,7 +125,7 @@ class MessageVerifierTest < ActiveSupport::TestCase
|
|||
old_message = old_verifier.generate("message verified with old key generator and salt")
|
||||
|
||||
verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1")
|
||||
verifier.rotate key_generator: old_key_gen, salt: old_salt, digest: "SHA1"
|
||||
verifier.rotate key_generator: old_key_gen, salt: old_salt
|
||||
|
||||
assert_equal "message verified with old key generator and salt", verifier.verified(old_message)
|
||||
end
|
||||
|
@ -175,7 +175,7 @@ class MessageVerifierTest < ActiveSupport::TestCase
|
|||
"message verified with old secret, salt, and metadata", purpose: "rotation")
|
||||
|
||||
verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1")
|
||||
verifier.rotate secret: old_secret, salt: old_salt, digest: "SHA1"
|
||||
verifier.rotate secret: old_secret, salt: old_salt
|
||||
|
||||
assert_equal "message verified with old secret, salt, and metadata",
|
||||
verifier.verified(old_message, purpose: "rotation")
|
||||
|
|
Loading…
Reference in a new issue