diff options
author | Kasper Timm Hansen <kaspth@gmail.com> | 2017-07-19 21:03:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-19 21:03:59 +0200 |
commit | 526d4b8dc816c17e354e2e0243af16d10147c3f0 (patch) | |
tree | 57b814234e5bd9d4dc9c9520682239cea99e9593 | |
parent | 5c16dd35a23f75038baf1527143ee44accf081ff (diff) | |
parent | 3bf3653a69a18d19083f46cf09b11e79b017af7c (diff) | |
download | rails-526d4b8dc816c17e354e2e0243af16d10147c3f0.tar.gz rails-526d4b8dc816c17e354e2e0243af16d10147c3f0.tar.bz2 rails-526d4b8dc816c17e354e2e0243af16d10147c3f0.zip |
Merge pull request #29854 from assain/add_metadata_to_message_verifier
Add Expiry & Purpose to Message Verifier
-rw-r--r-- | activesupport/lib/active_support/message_verifier.rb | 13 | ||||
-rw-r--r-- | activesupport/test/message_verifier_test.rb | 41 |
2 files changed, 48 insertions, 6 deletions
diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb index b889f31f7a..76b3865bf2 100644 --- a/activesupport/lib/active_support/message_verifier.rb +++ b/activesupport/lib/active_support/message_verifier.rb @@ -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 diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index ba886f9fb4..d4a8ce762a 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -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 |