mirror of https://github.com/rails/rails
add metadata support to message verifier
This commit is contained in:
parent
5c16dd35a2
commit
3bf3653a69
|
@ -3,6 +3,7 @@
|
|||
require "base64"
|
||||
require_relative "core_ext/object/blank"
|
||||
require_relative "security_utils"
|
||||
require_relative "messages/metadata"
|
||||
|
||||
module ActiveSupport
|
||||
# +MessageVerifier+ makes it easy to generate and verify messages which are
|
||||
|
@ -79,11 +80,11 @@ module ActiveSupport
|
|||
#
|
||||
# incompatible_message = "test--dad7b06c94abba8d46a15fafaef56c327665d5ff"
|
||||
# verifier.verified(incompatible_message) # => TypeError: incompatible marshal file format
|
||||
def verified(signed_message)
|
||||
def verified(signed_message, purpose: nil)
|
||||
if valid_message?(signed_message)
|
||||
begin
|
||||
data = signed_message.split("--".freeze)[0]
|
||||
@serializer.load(decode(data))
|
||||
Messages::Metadata.verify(@serializer.load(decode(data)), purpose)
|
||||
rescue ArgumentError => argument_error
|
||||
return if argument_error.message.include?("invalid base64")
|
||||
raise
|
||||
|
@ -103,8 +104,8 @@ module ActiveSupport
|
|||
#
|
||||
# other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
|
||||
# other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
|
||||
def verify(signed_message)
|
||||
verified(signed_message) || raise(InvalidSignature)
|
||||
def verify(signed_message, purpose: nil)
|
||||
verified(signed_message, purpose: purpose) || raise(InvalidSignature)
|
||||
end
|
||||
|
||||
# Generates a signed message for the provided value.
|
||||
|
@ -114,8 +115,8 @@ module ActiveSupport
|
|||
#
|
||||
# verifier = ActiveSupport::MessageVerifier.new 's3Krit'
|
||||
# verifier.generate 'a private message' # => "BAhJIhRwcml2YXRlLW1lc3NhZ2UGOgZFVA==--e2d724331ebdee96a10fb99b089508d1c72bd772"
|
||||
def generate(value)
|
||||
data = encode(@serializer.dump(value))
|
||||
def generate(value, expires_at: nil, expires_in: nil, purpose: nil)
|
||||
data = encode(@serializer.dump(Messages::Metadata.wrap(value, expires_at: expires_at, expires_in: expires_in, purpose: purpose)))
|
||||
"#{data}--#{generate_digest(data)}"
|
||||
end
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ require "abstract_unit"
|
|||
require "openssl"
|
||||
require "active_support/time"
|
||||
require "active_support/json"
|
||||
require_relative "metadata/shared_metadata_tests"
|
||||
|
||||
class MessageVerifierTest < ActiveSupport::TestCase
|
||||
class JSONSerializer
|
||||
|
@ -84,4 +85,44 @@ class MessageVerifierTest < ActiveSupport::TestCase
|
|||
end
|
||||
assert_equal "Secret should not be nil.", exception.message
|
||||
end
|
||||
|
||||
def test_backward_compatibility_messages_signed_without_metadata
|
||||
signed_message = "BAh7BzoJc29tZUkiCWRhdGEGOgZFVDoIbm93SXU6CVRpbWUNIIAbgAAAAAAHOgtvZmZzZXRpADoJem9uZUkiCFVUQwY7BkY=--d03c52c91dfe4ccc5159417c660461bcce005e96"
|
||||
assert_equal @data, @verifier.verify(signed_message)
|
||||
end
|
||||
end
|
||||
|
||||
class MessageVerifierMetadataTest < ActiveSupport::TestCase
|
||||
include SharedMessageMetadataTests
|
||||
|
||||
setup do
|
||||
@verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!", verifier_options)
|
||||
end
|
||||
|
||||
private
|
||||
def generate(message, **options)
|
||||
@verifier.generate(message, options)
|
||||
end
|
||||
|
||||
def parse(message, **options)
|
||||
@verifier.verified(message, options)
|
||||
end
|
||||
|
||||
def verifier_options
|
||||
Hash.new
|
||||
end
|
||||
end
|
||||
|
||||
class MessageVerifierMetadataMarshalTest < MessageVerifierMetadataTest
|
||||
private
|
||||
def verifier_options
|
||||
{ serializer: Marshal }
|
||||
end
|
||||
end
|
||||
|
||||
class MessageVerifierMetadataJSONTest < MessageVerifierMetadataTest
|
||||
private
|
||||
def verifier_options
|
||||
{ serializer: MessageVerifierTest::JSONSerializer.new }
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue