From ef1bb0eb52d4d867ccc07085909bc3dd61b6b63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 11:06:48 +0100 Subject: [PATCH 01/25] update readme file --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 018ae71..525d29a 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,20 @@ Welcome to your new gem! In this directory, you'll find the files you need to be TODO: Delete this and the text above, and describe your gem +## Require + +Please specify version 1.8 of faraday in your project if you have already installed it beforehand + +``` ruby +gem 'faraday', '~>1.8' +``` + ## Installation Add this line to your application's Gemfile: ``` ruby -gem 'fedapay-ruby' +gem 'fedapay', '~>0.1.20', git: 'https://github.com/fedapay/fedapay-ruby.git' ``` And then execute: From 98a03033a136bc597a2be7fcc8e5f30c24d4ea8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 11:34:40 +0100 Subject: [PATCH 02/25] update bundler version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 838167a..a05a335 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,4 @@ language: ruby cache: bundler rvm: - 2.4.2 -before_install: gem install bundler -v 1.16.6 +before_install: gem install bundler:1.17.3 From 9398458af89d5d7ec26d22c226a768661d60dbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 11:37:52 +0100 Subject: [PATCH 03/25] update bundler version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a05a335..2f0f530 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,4 @@ language: ruby cache: bundler rvm: - 2.4.2 -before_install: gem install bundler:1.17.3 +before_install: gem install bundler:1.16.6 From 541e7ddb9362b75873ba2d58484eeeddce305909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 11:41:52 +0100 Subject: [PATCH 04/25] update bundler version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2f0f530..a05a335 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,4 @@ language: ruby cache: bundler rvm: - 2.4.2 -before_install: gem install bundler:1.16.6 +before_install: gem install bundler:1.17.3 From 46aaf232ee94ed670ef83791164161abd118414c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 11:48:01 +0100 Subject: [PATCH 05/25] update bundler version on gem file --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index c63a6bc..fc8831e 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } gemspec group :development do - gem 'bundler', '~> 1.15' + gem 'bundler', '~> 1.17.3' gem 'faker' gem 'minitest', '~> 5.0' gem 'minitest-reporters' From aa3cbd214992177ac8c08c3ac023716fae306d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 11:51:16 +0100 Subject: [PATCH 06/25] update bundler version on gem file --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index fc8831e..6f2b345 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } gemspec group :development do - gem 'bundler', '~> 1.17.3' + gem 'bundler', '~> 2.3.17' gem 'faker' gem 'minitest', '~> 5.0' gem 'minitest-reporters' From 5b885a90ea3cc99878a4dd117ef1fc13c6b4cc2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 11:54:32 +0100 Subject: [PATCH 07/25] update bundler version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a05a335..536fbe2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,4 @@ language: ruby cache: bundler rvm: - 2.4.2 -before_install: gem install bundler:1.17.3 +before_install: gem install bundler:2.3.17 From 4f0fc7db2564f72018c893608e34df114a0e7770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 12:20:29 +0100 Subject: [PATCH 08/25] update webhook test file --- test/fedapay/webhook_test.rb | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/test/fedapay/webhook_test.rb b/test/fedapay/webhook_test.rb index a39ed15..7683de3 100644 --- a/test/fedapay/webhook_test.rb +++ b/test/fedapay/webhook_test.rb @@ -1,10 +1,9 @@ # frozen_string_literal: true -require ::File.expand_path('../../test_helper', __FILE__) +require 'test_helper' module FedaPay class WebhookTest < Minitest::Test - EVENT_PAYLOAD = "{ \"id\": \"evt_test_webhook\", \"object\": \"event\" @@ -17,14 +16,10 @@ def generateHeader(opts = {}) opts[:secret] ||= SECRET opts[:scheme] ||= FedaPay::WebhookSignature.EXPECTED_SCHEME opts[:signature] ||= FedaPay::WebhookSignature.computeSignature( - opts[:timestamp], - opts[:payload], - opts[:secret] + opts[:timestamp], opts[:payload], opts[:secret] ) FedaPay::WebhookSignature.generateHeader( - opts[:timestamp], - opts[:signature], - scheme: opts[:scheme] + opts[:timestamp], opts[:signature], scheme: opts[:scheme] ) end @@ -32,8 +27,7 @@ def generateHeader(opts = {}) it "compute a signature which can then be verified" do timestamp = Time.now signature = FedaPay::WebhookSignature.computeSignature( - EVENT_PAYLOAD, - SECRET + EVENT_PAYLOAD, SECRET ) header = generateHeader(timestamp: timestamp, signature: signature) assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET)) @@ -125,4 +119,4 @@ def generateHeader(opts = {}) end end end -end \ No newline at end of file +end From bed5de79d5ee9941ee78eeebbab6660c53a4f422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 12:40:44 +0100 Subject: [PATCH 09/25] wip --- Gemfile | 2 +- test/fedapay/webhook_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 6f2b345..e9ca61f 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gemspec group :development do gem 'bundler', '~> 2.3.17' gem 'faker' - gem 'minitest', '~> 5.0' + gem 'minitest', '~> 5.8.4' gem 'minitest-reporters' gem 'mocha', '~> 0.13.2' gem 'rake', '>= 12.3.3' diff --git a/test/fedapay/webhook_test.rb b/test/fedapay/webhook_test.rb index 7683de3..a51a45e 100644 --- a/test/fedapay/webhook_test.rb +++ b/test/fedapay/webhook_test.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'test_helper' +require ::File.expand_path('../../test_helper', __FILE__) module FedaPay class WebhookTest < Minitest::Test From e283a933d5b2465cb43dcdaec159ec3ec2dfa6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 12:46:38 +0100 Subject: [PATCH 10/25] wip --- test/test_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_helper.rb b/test/test_helper.rb index c4e0cd0..a032f19 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -2,6 +2,7 @@ require 'fedapay' gem 'mocha' +require 'minitest' require 'minitest/autorun' require 'minitest/reporters' require 'mocha/setup' From 3702b7c15785328f5d7ee094aec091b4aaff0cca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 13:28:32 +0100 Subject: [PATCH 11/25] wip --- Gemfile | 3 ++- test/fedapay/webhook_test.rb | 11 ++++++++--- test/test_helper.rb | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index e9ca61f..9476467 100644 --- a/Gemfile +++ b/Gemfile @@ -8,8 +8,9 @@ gemspec group :development do gem 'bundler', '~> 2.3.17' gem 'faker' - gem 'minitest', '~> 5.8.4' + gem 'minitest', '~> 5.0' gem 'minitest-reporters' + gem 'minitest-spec-context' gem 'mocha', '~> 0.13.2' gem 'rake', '>= 12.3.3' gem 'rubocop', '0.52.1' diff --git a/test/fedapay/webhook_test.rb b/test/fedapay/webhook_test.rb index a51a45e..7311302 100644 --- a/test/fedapay/webhook_test.rb +++ b/test/fedapay/webhook_test.rb @@ -16,10 +16,14 @@ def generateHeader(opts = {}) opts[:secret] ||= SECRET opts[:scheme] ||= FedaPay::WebhookSignature.EXPECTED_SCHEME opts[:signature] ||= FedaPay::WebhookSignature.computeSignature( - opts[:timestamp], opts[:payload], opts[:secret] + opts[:timestamp], + opts[:payload], + opts[:secret] ) FedaPay::WebhookSignature.generateHeader( - opts[:timestamp], opts[:signature], scheme: opts[:scheme] + opts[:timestamp], + opts[:signature], + scheme: opts[:scheme] ) end @@ -27,7 +31,8 @@ def generateHeader(opts = {}) it "compute a signature which can then be verified" do timestamp = Time.now signature = FedaPay::WebhookSignature.computeSignature( - EVENT_PAYLOAD, SECRET + EVENT_PAYLOAD, + SECRET ) header = generateHeader(timestamp: timestamp, signature: signature) assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET)) diff --git a/test/test_helper.rb b/test/test_helper.rb index a032f19..40f0111 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -2,9 +2,9 @@ require 'fedapay' gem 'mocha' -require 'minitest' require 'minitest/autorun' require 'minitest/reporters' +require 'minitest-spec-context' require 'mocha/setup' require 'timecop' require 'webmock/minitest' From e54e8a5cca7ee61fbaa0980f05f0bd31a18e21e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 13:33:32 +0100 Subject: [PATCH 12/25] wip --- .travis.yml | 2 +- Gemfile | 3 +-- test/test_helper.rb | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 536fbe2..838167a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,4 @@ language: ruby cache: bundler rvm: - 2.4.2 -before_install: gem install bundler:2.3.17 +before_install: gem install bundler -v 1.16.6 diff --git a/Gemfile b/Gemfile index 9476467..c63a6bc 100644 --- a/Gemfile +++ b/Gemfile @@ -6,11 +6,10 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } gemspec group :development do - gem 'bundler', '~> 2.3.17' + gem 'bundler', '~> 1.15' gem 'faker' gem 'minitest', '~> 5.0' gem 'minitest-reporters' - gem 'minitest-spec-context' gem 'mocha', '~> 0.13.2' gem 'rake', '>= 12.3.3' gem 'rubocop', '0.52.1' diff --git a/test/test_helper.rb b/test/test_helper.rb index 40f0111..c4e0cd0 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -4,7 +4,6 @@ gem 'mocha' require 'minitest/autorun' require 'minitest/reporters' -require 'minitest-spec-context' require 'mocha/setup' require 'timecop' require 'webmock/minitest' From a44b306b117f22e82179da7e92940987b854f91e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 13:40:14 +0100 Subject: [PATCH 13/25] wip --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index c63a6bc..7207e56 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } gemspec group :development do - gem 'bundler', '~> 1.15' + gem 'bundler', '~> 1.16.6' gem 'faker' gem 'minitest', '~> 5.0' gem 'minitest-reporters' From 8fd61272add89cbb08278307d7ecea3e9b4e0a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 13:46:21 +0100 Subject: [PATCH 14/25] wip --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 838167a..2f0f530 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,4 @@ language: ruby cache: bundler rvm: - 2.4.2 -before_install: gem install bundler -v 1.16.6 +before_install: gem install bundler:1.16.6 From 0ceb901d41779ec802341dc0fdcf0c57ce54ebe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 14:10:24 +0100 Subject: [PATCH 15/25] wip --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 7207e56..b808740 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } gemspec group :development do - gem 'bundler', '~> 1.16.6' + gem 'bundler' gem 'faker' gem 'minitest', '~> 5.0' gem 'minitest-reporters' From 55fb38b204e93cb647c597ec2c0aefcc6f5f5140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 14:20:38 +0100 Subject: [PATCH 16/25] wip --- test/fedapay/webhook_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/fedapay/webhook_test.rb b/test/fedapay/webhook_test.rb index 7311302..b452fa0 100644 --- a/test/fedapay/webhook_test.rb +++ b/test/fedapay/webhook_test.rb @@ -39,6 +39,10 @@ def generateHeader(opts = {}) end end + test 'make test' do + assert true + end + context "generate header" do should "generate a header in valid format" do timestamp = Time.now From 50ed1892f3260058041f88a6624f5ac9af534166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 14:24:34 +0100 Subject: [PATCH 17/25] wip --- test/fedapay/webhook_test.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/fedapay/webhook_test.rb b/test/fedapay/webhook_test.rb index b452fa0..89939f8 100644 --- a/test/fedapay/webhook_test.rb +++ b/test/fedapay/webhook_test.rb @@ -39,11 +39,7 @@ def generateHeader(opts = {}) end end - test 'make test' do - assert true - end - - context "generate header" do + it "generate header" do should "generate a header in valid format" do timestamp = Time.now signature = FedaPay::WebhookSignature.computeSignature( From aec71f230b3e2abbb0836afbb0d15bec7ee426ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 14:56:09 +0100 Subject: [PATCH 18/25] wip --- test/fedapay/webhook_test.rb | 54 +++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/test/fedapay/webhook_test.rb b/test/fedapay/webhook_test.rb index 89939f8..953d7c2 100644 --- a/test/fedapay/webhook_test.rb +++ b/test/fedapay/webhook_test.rb @@ -39,31 +39,33 @@ def generateHeader(opts = {}) end end - it "generate header" do - should "generate a header in valid format" do - timestamp = Time.now - signature = FedaPay::WebhookSignature.computeSignature( - EVENT_PAYLOAD, - SECRET - ) - scheme = "v1" - header = FedaPay::WebhookSignature.generateHeader( - timestamp, - signature, - scheme: scheme - ) - assert_equal("t=#{timestamp.to_i},#{scheme}=#{signature}", header) + describe "hedear generation" do + it "generate header" do + it "generate a header in valid format" do + timestamp = Time.now + signature = FedaPay::WebhookSignature.computeSignature( + EVENT_PAYLOAD, + SECRET + ) + scheme = "v1" + header = FedaPay::WebhookSignature.generateHeader( + timestamp, + signature, + scheme: scheme + ) + assert_equal("t=#{timestamp.to_i},#{scheme}=#{signature}", header) + end end end - context "construct event" do - should "return an Event instance from a valid JSON payload and valid signature header" do + describe "construct event" do + it "return an Event instance from a valid JSON payload and valid signature header" do header = generate_header event = FedaPay::Webhook.constructEvent(EVENT_PAYLOAD, header, SECRET) assert event.is_a?(FedaPay::Event) end - should "raise a JSON::ParserError from an invalid JSON payload" do + it "raise a JSON::ParserError from an invalid JSON payload" do assert_raises JSON::ParserError do payload = "this is not valid JSON" header = generateHeader(payload: payload) @@ -71,7 +73,7 @@ def generateHeader(opts = {}) end end - should "raise a Signature Verification Error from a valid JSON payload and an invalid signature header" do + it "raise a Signature Verification Error from a valid JSON payload and an invalid signature header" do header = "bad_header" assert_raises FedaPay::SignatureVerificationError do FedaPay::Webhook.constructEvent(EVENT_PAYLOAD, header, SECRET) @@ -79,46 +81,46 @@ def generateHeader(opts = {}) end end - context "verify signature header" do - should "raise a SignatureVerificationError when the header does not have the expected format" do + describe "verify signature header" do + it "raise a SignatureVerificationError when the header does not have the expected format" do header = "i'm not even a real signature header" assert_raises(FedaPay::SignatureVerificationError) do FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, "secret") end end - should "raise a Signature verification error when there are no signatures with the expected scheme" do + it "raise a Signature verification error when there are no signatures with the expected scheme" do header = generate_header(scheme: "v0") assert_raises(FedaPay::SignatureVerificationError) do FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, "secret") end end - should "raise a Signature verification error when there are no valid signatures for the payload" do + it "raise a Signature verification error when there are no valid signatures for the payload" do header = generate_header(signature: "bad_signature") assert_raises(FedaPay::SignatureVerificationError) do FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, "secret") end end - should "raise a Signature verification error when the timestamp is not within the tolerance" do + it "raise a Signature verification error when the timestamp is not within the tolerance" do header = generate_header(timestamp: Time.now - 15) assert_raises(FedaPay::SignatureVerificationError) do FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET, tolerance: 10) end end - should "return true when the header contains a valid signature and the timestamp is within the tolerance" do + it "return true when the header contains a valid signature and the timestamp is within the tolerance" do header = generate_header assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET, tolerance: 10)) end - should "return true when the header contains at least one valid signature" do + it "return true when the header contains at least one valid signature" do header = generate_header + ",v1=bad_signature" assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET, tolerance: 10)) end - should "return true when the header contains a valid signature and the timestamp is off but no tolerance is provided" do + it "return true when the header contains a valid signature and the timestamp is off but no tolerance is provided" do header = generate_header(timestamp: Time.at(12345)) assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET)) end From e64a31ea6c07ecc9a6eab7ca214e34974262bdde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 15:28:23 +0100 Subject: [PATCH 19/25] wip --- Gemfile | 2 ++ test/fedapay/webhook_test.rb | 54 +++++++++++++++++------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Gemfile b/Gemfile index b808740..31d694d 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,8 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } # Specify your gem's dependencies in fedapay.gemspec gemspec +gem 'faraday', '~>1.8' + group :development do gem 'bundler' gem 'faker' diff --git a/test/fedapay/webhook_test.rb b/test/fedapay/webhook_test.rb index 953d7c2..7311302 100644 --- a/test/fedapay/webhook_test.rb +++ b/test/fedapay/webhook_test.rb @@ -39,33 +39,31 @@ def generateHeader(opts = {}) end end - describe "hedear generation" do - it "generate header" do - it "generate a header in valid format" do - timestamp = Time.now - signature = FedaPay::WebhookSignature.computeSignature( - EVENT_PAYLOAD, - SECRET - ) - scheme = "v1" - header = FedaPay::WebhookSignature.generateHeader( - timestamp, - signature, - scheme: scheme - ) - assert_equal("t=#{timestamp.to_i},#{scheme}=#{signature}", header) - end + context "generate header" do + should "generate a header in valid format" do + timestamp = Time.now + signature = FedaPay::WebhookSignature.computeSignature( + EVENT_PAYLOAD, + SECRET + ) + scheme = "v1" + header = FedaPay::WebhookSignature.generateHeader( + timestamp, + signature, + scheme: scheme + ) + assert_equal("t=#{timestamp.to_i},#{scheme}=#{signature}", header) end end - describe "construct event" do - it "return an Event instance from a valid JSON payload and valid signature header" do + context "construct event" do + should "return an Event instance from a valid JSON payload and valid signature header" do header = generate_header event = FedaPay::Webhook.constructEvent(EVENT_PAYLOAD, header, SECRET) assert event.is_a?(FedaPay::Event) end - it "raise a JSON::ParserError from an invalid JSON payload" do + should "raise a JSON::ParserError from an invalid JSON payload" do assert_raises JSON::ParserError do payload = "this is not valid JSON" header = generateHeader(payload: payload) @@ -73,7 +71,7 @@ def generateHeader(opts = {}) end end - it "raise a Signature Verification Error from a valid JSON payload and an invalid signature header" do + should "raise a Signature Verification Error from a valid JSON payload and an invalid signature header" do header = "bad_header" assert_raises FedaPay::SignatureVerificationError do FedaPay::Webhook.constructEvent(EVENT_PAYLOAD, header, SECRET) @@ -81,46 +79,46 @@ def generateHeader(opts = {}) end end - describe "verify signature header" do - it "raise a SignatureVerificationError when the header does not have the expected format" do + context "verify signature header" do + should "raise a SignatureVerificationError when the header does not have the expected format" do header = "i'm not even a real signature header" assert_raises(FedaPay::SignatureVerificationError) do FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, "secret") end end - it "raise a Signature verification error when there are no signatures with the expected scheme" do + should "raise a Signature verification error when there are no signatures with the expected scheme" do header = generate_header(scheme: "v0") assert_raises(FedaPay::SignatureVerificationError) do FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, "secret") end end - it "raise a Signature verification error when there are no valid signatures for the payload" do + should "raise a Signature verification error when there are no valid signatures for the payload" do header = generate_header(signature: "bad_signature") assert_raises(FedaPay::SignatureVerificationError) do FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, "secret") end end - it "raise a Signature verification error when the timestamp is not within the tolerance" do + should "raise a Signature verification error when the timestamp is not within the tolerance" do header = generate_header(timestamp: Time.now - 15) assert_raises(FedaPay::SignatureVerificationError) do FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET, tolerance: 10) end end - it "return true when the header contains a valid signature and the timestamp is within the tolerance" do + should "return true when the header contains a valid signature and the timestamp is within the tolerance" do header = generate_header assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET, tolerance: 10)) end - it "return true when the header contains at least one valid signature" do + should "return true when the header contains at least one valid signature" do header = generate_header + ",v1=bad_signature" assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET, tolerance: 10)) end - it "return true when the header contains a valid signature and the timestamp is off but no tolerance is provided" do + should "return true when the header contains a valid signature and the timestamp is off but no tolerance is provided" do header = generate_header(timestamp: Time.at(12345)) assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET)) end From d190beacb498831be8cded1d51652c9e6a5e8c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 15:40:43 +0100 Subject: [PATCH 20/25] wip --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 31d694d..7db387a 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gemspec gem 'faraday', '~>1.8' group :development do - gem 'bundler' + gem 'bundler', '~>1.6' gem 'faker' gem 'minitest', '~> 5.0' gem 'minitest-reporters' From 07d62d43faa529a472ec1bbed942ae1081c6748f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 15:46:45 +0100 Subject: [PATCH 21/25] wip --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2f0f530..8092606 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,5 @@ language: ruby cache: bundler rvm: - 2.4.2 -before_install: gem install bundler:1.16.6 +before_install: gem install bundler -v 1.16.6 +before_install: gem uninstall bundler -v 2.3.18 From 819551161a649e395c433bb0ba20504c16b1a102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 15:50:17 +0100 Subject: [PATCH 22/25] wip --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8092606..f1bf9f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,4 +5,4 @@ cache: bundler rvm: - 2.4.2 before_install: gem install bundler -v 1.16.6 -before_install: gem uninstall bundler -v 2.3.18 +before_install: gem uninstall -i /home/travis/.rvm/gems/ruby-2.4.2@global bundler From a56c051361ca874e4895ff9e8b092cc8fc03a8f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Thu, 14 Jul 2022 16:03:17 +0100 Subject: [PATCH 23/25] wip --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f1bf9f8..6c525b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,5 +4,7 @@ language: ruby cache: bundler rvm: - 2.4.2 -before_install: gem install bundler -v 1.16.6 -before_install: gem uninstall -i /home/travis/.rvm/gems/ruby-2.4.2@global bundler +before_install: + - yes | gem uninstall -i /home/travis/.rvm/gems/ruby-2.4.2@global bundler + - gem install bundler -v 1.16.6 + \ No newline at end of file From 2b6b11877aead249851037b0feec429d92f5ace2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Tue, 19 Jul 2022 17:25:15 +0100 Subject: [PATCH 24/25] test update --- .travis.yml | 1 + test/fedapay/webhook_test.rb | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6c525b3..3ce77ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,5 +6,6 @@ rvm: - 2.4.2 before_install: - yes | gem uninstall -i /home/travis/.rvm/gems/ruby-2.4.2@global bundler + - gem install bundler -v 1.16.6 \ No newline at end of file diff --git a/test/fedapay/webhook_test.rb b/test/fedapay/webhook_test.rb index 7311302..70c6501 100644 --- a/test/fedapay/webhook_test.rb +++ b/test/fedapay/webhook_test.rb @@ -39,8 +39,8 @@ def generateHeader(opts = {}) end end - context "generate header" do - should "generate a header in valid format" do + describe "generate header" do + before "generate a header in valid format" do timestamp = Time.now signature = FedaPay::WebhookSignature.computeSignature( EVENT_PAYLOAD, From f3f54c4f516139b4e065a17835322697a5f6dfdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?DAKIN=20Judica=C3=ABl?= Date: Tue, 19 Jul 2022 18:58:37 +0100 Subject: [PATCH 25/25] update --- lib/fedapay/webhook_signature.rb | 113 ++++++++++++++----------------- test/fedapay/webhook_test.rb | 56 +++++++-------- 2 files changed, 80 insertions(+), 89 deletions(-) diff --git a/lib/fedapay/webhook_signature.rb b/lib/fedapay/webhook_signature.rb index d1c358a..4e38764 100644 --- a/lib/fedapay/webhook_signature.rb +++ b/lib/fedapay/webhook_signature.rb @@ -1,74 +1,65 @@ module FedaPay - class WebhookSignature + class WebhookSignature + EXPECTED_SCHEME = 's'.freeze - EXPECTED_SCHEME = 's'; + def self.verify_header(payload, header, secret, tolerance = nil) + timestamp = get_timestamp(header) + signatures = get_signatures(header, EXPECTED_SCHEME) - def self.verify_header(payload, header, secret, tolerance = nil) - timestamp = get_timestamp(header) - signatures = get_signatures(header, EXPECTED_SCHEME) - - if timestamp == -1 - raise "Unable to extract timestamp and signatures from header" - end - - if signatures.empty? - raise SignatureVerificationError.new( - "No signatures found with expected scheme #{EXPECTED_SCHEME}", - header, http_body: payload - ) - end + if timestamp == -1 + raise 'Unable to extract timestamp and signatures from header' + end - signed_payload = "#{timestamp.to_i}.#{payload}" - expected_signature = compute_signature(signed_payload, secret) - unless signatures.any? { |s| Util.secure_compare(expected_signature, s) } - raise SignatureVerificationError.new( - "No signatures found matching the expected signature for payload", - header, http_body: payload - ) - end + if signatures.empty? + raise SignatureVerificationError.new( + "No signatures found with expected scheme #{EXPECTED_SCHEME}", + header, http_body: payload + ) + end - if tolerance && timestamp < Time.now - tolerance - raise SignatureVerificationError.new( - "Timestamp outside the tolerance zone (#{Time.at(timestamp)})", - header, http_body: payload - ) - end + signed_payload = "#{timestamp.to_i}.#{payload}" + expected_signature = compute_signature(signed_payload, secret) + unless signatures.any? { |s| Util.secure_compare(expected_signature, s) } + raise SignatureVerificationError.new( + 'No signatures found matching the expected signature for payload', + header, http_body: payload + ) + end - true - end + if tolerance && timestamp < Time.now - tolerance + raise SignatureVerificationError.new( + "Timestamp outside the tolerance zone (#{Time.at(timestamp)})", + header, http_body: payload + ) + end - def self.generate_header(timestamp, signature, scheme: EXPECTED_SCHEME) - unless timestamp.is_a?(Time) - raise "timestamp should be an instance of Time" - end - unless signature.is_a?(String) - raise "signature should be a string" - end - unless scheme.is_a?(String) - raise "scheme should be a string" - end - - "t=#{timestamp.to_i},#{scheme}=#{signature}" - end - - def self.compute_signature(payload, secret) - digest = OpenSSL::Digest.new('sha256') - OpenSSL::HMAC.hexdigest(digest, secret, payload) - end + true + end - def self.get_signatures(header, scheme) - items = header.split(',').map { |i| i.split("=", 2) } - signatures = items.select { |i| i[0] == scheme }.map { |i| i[1] } - end + def self.generate_header(timestamp, signature, scheme: EXPECTED_SCHEME) + unless timestamp.is_a?(Time) + raise 'timestamp should be an instance of Time' + end + raise 'signature should be a string' unless signature.is_a?(String) + raise 'scheme should be a string' unless scheme.is_a?(String) - def self.get_timestamp(header) - items = header.split(',').map { |i| i.split("=", 2) } - timestamp = Integer(items.select { |i| i[0] == "t" }[0][1]) - Time.at(timestamp) - end + "t=#{timestamp.to_i},#{scheme}=#{signature}" end -end - + def self.compute_signature(payload, secret) + digest = OpenSSL::Digest.new('sha256') + OpenSSL::HMAC.hexdigest(digest, secret, payload) + end + def self.get_signatures(header, scheme) + items = header.split(',').map { |i| i.split('=', 2) } + signatures = items.select { |i| i[0] == scheme }.map { |i| i[1] } + end + def self.get_timestamp(header) + items = header.split(',').map { |i| i.split('=', 2) } + timestamp = Integer(items.select { |i| i[0] == 't' }[0][1]) + Time.at(timestamp) + end + end +end diff --git a/test/fedapay/webhook_test.rb b/test/fedapay/webhook_test.rb index 70c6501..f23aac0 100644 --- a/test/fedapay/webhook_test.rb +++ b/test/fedapay/webhook_test.rb @@ -15,12 +15,12 @@ def generateHeader(opts = {}) opts[:payload] ||= EVENT_PAYLOAD opts[:secret] ||= SECRET opts[:scheme] ||= FedaPay::WebhookSignature.EXPECTED_SCHEME - opts[:signature] ||= FedaPay::WebhookSignature.computeSignature( + opts[:signature] ||= FedaPay::WebhookSignature.compute_signature( opts[:timestamp], opts[:payload], opts[:secret] ) - FedaPay::WebhookSignature.generateHeader( + FedaPay::WebhookSignature.generate_header( opts[:timestamp], opts[:signature], scheme: opts[:scheme] @@ -30,7 +30,7 @@ def generateHeader(opts = {}) describe "compute signature" do it "compute a signature which can then be verified" do timestamp = Time.now - signature = FedaPay::WebhookSignature.computeSignature( + signature = FedaPay::WebhookSignature.compute_signature( EVENT_PAYLOAD, SECRET ) @@ -42,12 +42,12 @@ def generateHeader(opts = {}) describe "generate header" do before "generate a header in valid format" do timestamp = Time.now - signature = FedaPay::WebhookSignature.computeSignature( + signature = FedaPay::WebhookSignature.compute_signature( EVENT_PAYLOAD, SECRET ) scheme = "v1" - header = FedaPay::WebhookSignature.generateHeader( + header = FedaPay::WebhookSignature.generate_header( timestamp, signature, scheme: scheme @@ -56,71 +56,71 @@ def generateHeader(opts = {}) end end - context "construct event" do - should "return an Event instance from a valid JSON payload and valid signature header" do + describe "construct event" do + it "return an Event instance from a valid JSON payload and valid signature header" do header = generate_header - event = FedaPay::Webhook.constructEvent(EVENT_PAYLOAD, header, SECRET) + event = FedaPay::Webhook.construct_event(EVENT_PAYLOAD, header, SECRET) assert event.is_a?(FedaPay::Event) end - should "raise a JSON::ParserError from an invalid JSON payload" do + it "raise a JSON::ParserError from an invalid JSON payload" do assert_raises JSON::ParserError do payload = "this is not valid JSON" header = generateHeader(payload: payload) - FedaPay::Webhook.constructEvent(payload, header, SECRET) + FedaPay::Webhook.construct_event(payload, header, SECRET) end end - should "raise a Signature Verification Error from a valid JSON payload and an invalid signature header" do + it "raise a Signature Verification Error from a valid JSON payload and an invalid signature header" do header = "bad_header" assert_raises FedaPay::SignatureVerificationError do - FedaPay::Webhook.constructEvent(EVENT_PAYLOAD, header, SECRET) + FedaPay::Webhook.construct_event(EVENT_PAYLOAD, header, SECRET) end end end - context "verify signature header" do - should "raise a SignatureVerificationError when the header does not have the expected format" do + describe "verify signature header" do + it "raise a SignatureVerificationError when the header does not have the expected format" do header = "i'm not even a real signature header" assert_raises(FedaPay::SignatureVerificationError) do - FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, "secret") + FedaPay::WebhookSignature.verify_header(EVENT_PAYLOAD, header, "secret") end end - should "raise a Signature verification error when there are no signatures with the expected scheme" do + it "raise a Signature verification error when there are no signatures with the expected scheme" do header = generate_header(scheme: "v0") assert_raises(FedaPay::SignatureVerificationError) do - FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, "secret") + FedaPay::WebhookSignature.verify_header(EVENT_PAYLOAD, header, "secret") end end - should "raise a Signature verification error when there are no valid signatures for the payload" do - header = generate_header(signature: "bad_signature") + it "raise a Signature verification error when there are no valid signatures for the payload" do + header = generateHeader(signature: "bad_signature") assert_raises(FedaPay::SignatureVerificationError) do - FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, "secret") + FedaPay::WebhookSignature.verify_header(EVENT_PAYLOAD, header, "secret") end end - should "raise a Signature verification error when the timestamp is not within the tolerance" do + it "raise a Signature verification error when the timestamp is not within the tolerance" do header = generate_header(timestamp: Time.now - 15) assert_raises(FedaPay::SignatureVerificationError) do - FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET, tolerance: 10) + FedaPay::WebhookSignature.verify_header(EVENT_PAYLOAD, header, SECRET, tolerance: 10) end end - should "return true when the header contains a valid signature and the timestamp is within the tolerance" do + it "return true when the header contains a valid signature and the timestamp is within the tolerance" do header = generate_header - assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET, tolerance: 10)) + assert(FedaPay::WebhookSignature.verify_header(EVENT_PAYLOAD, header, SECRET, tolerance: 10)) end - should "return true when the header contains at least one valid signature" do + it "return true when the header contains at least one valid signature" do header = generate_header + ",v1=bad_signature" - assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET, tolerance: 10)) + assert(FedaPay::WebhookSignature.verify_header(EVENT_PAYLOAD, header, SECRET, tolerance: 10)) end - should "return true when the header contains a valid signature and the timestamp is off but no tolerance is provided" do + it "return true when the header contains a valid signature and the timestamp is off but no tolerance is provided" do header = generate_header(timestamp: Time.at(12345)) - assert(FedaPay::WebhookSignature.verifyHeader(EVENT_PAYLOAD, header, SECRET)) + assert(FedaPay::WebhookSignature.verify_header(EVENT_PAYLOAD, header, SECRET)) end end end