Sha256: 99fff5c7306a92c772ce51d9c9b9b35ebd540a176bdb56cf4d084dfff6b96628

Contents?: true

Size: 1.81 KB

Versions: 27

Compression:

Stored size: 1.81 KB

Contents

module Braintree
  class WebhookNotificationGateway # :nodoc:
    def initialize(gateway)
      @gateway = gateway
      @config = gateway.config
      @config.assert_has_access_token_or_keys
    end

    def parse(signature_string, payload)
      raise InvalidSignature, 'signature cannot be nil' if signature_string.nil?
      raise InvalidSignature, 'payload cannot be nil' if payload.nil?
      if payload =~ /[^A-Za-z0-9+=\/\n]/
        raise InvalidSignature, "payload contains illegal characters"
      end
      _verify_signature(signature_string, payload)
      attributes = Xml.hash_from_xml(Base64.decode64(payload))
      WebhookNotification._new(@gateway, attributes[:notification])
    end

    def verify(challenge)
      raise InvalidChallenge, 'challenge contains non-hex characters' unless challenge =~ /\A[a-f0-9]{20,32}\z/
      digest = Braintree::Digest.hexdigest(@config.private_key, challenge)
      "#{@config.public_key}|#{digest}"
    end

    def _matching_signature_pair(signature_string)
      signature_pairs = signature_string.split("&")
      valid_pairs = signature_pairs.select { |pair| pair.include?("|") }.map { |pair| pair.split("|") }

      valid_pairs.detect do |public_key, signature|
        public_key == @config.public_key
      end
    end

    def _verify_signature(signature_string, payload)
      public_key, signature = _matching_signature_pair(signature_string)
      raise InvalidSignature, 'no matching public key' if public_key.nil?

      signature_matches = [payload, payload + "\n"].any? do |payload|
        payload_signature = Braintree::Digest.hexdigest(@config.private_key, payload)
        Braintree::Digest.secure_compare(signature, payload_signature)
      end
      raise InvalidSignature, 'signature does not match payload - one has been modified' unless signature_matches
    end
  end
end

Version data entries

27 entries across 27 versions & 1 rubygems

Version Path
braintree-3.3.0 lib/braintree/webhook_notification_gateway.rb
braintree-3.2.0 lib/braintree/webhook_notification_gateway.rb
braintree-3.1.0 lib/braintree/webhook_notification_gateway.rb
braintree-3.0.1 lib/braintree/webhook_notification_gateway.rb
braintree-2.104.1 lib/braintree/webhook_notification_gateway.rb
braintree-2.104.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.103.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.102.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.101.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.100.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.99.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.98.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.97.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.96.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.95.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.94.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.93.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.92.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.91.0 lib/braintree/webhook_notification_gateway.rb
braintree-2.90.0 lib/braintree/webhook_notification_gateway.rb