diff options
| -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 | 
