sendgrid-ruby 6.2.0 → 6.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -1
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +6 -0
  5. data/.travis.yml +12 -21
  6. data/CHANGELOG.md +57 -8
  7. data/CONTRIBUTING.md +10 -17
  8. data/Dockerfile +14 -0
  9. data/FIRST_TIMERS.md +79 -0
  10. data/Gemfile +0 -1
  11. data/ISSUE_TEMPLATE.md +5 -1
  12. data/Makefile +9 -2
  13. data/PULL_REQUEST_TEMPLATE.md +1 -1
  14. data/README.md +22 -21
  15. data/TROUBLESHOOTING.md +5 -5
  16. data/USAGE.md +35 -36
  17. data/examples/helpers/eventwebhook/example.rb +16 -0
  18. data/examples/helpers/mail/example.rb +11 -4
  19. data/examples/mail/mail.rb +1 -1
  20. data/lib/rack/sendgrid_webhook_verification.rb +52 -0
  21. data/lib/sendgrid-ruby.rb +2 -0
  22. data/lib/sendgrid/helpers/eventwebhook/eventwebhook.rb +52 -0
  23. data/lib/sendgrid/helpers/inbound/README.md +5 -5
  24. data/lib/sendgrid/helpers/inbound/public/index.html +1 -1
  25. data/lib/sendgrid/helpers/mail/README.md +3 -3
  26. data/lib/sendgrid/helpers/settings/README.md +2 -2
  27. data/lib/sendgrid/version.rb +1 -1
  28. data/mail_helper_v3.md +9 -9
  29. data/sendgrid-ruby.gemspec +2 -0
  30. data/spec/fixtures/event_webhook.rb +16 -0
  31. data/spec/rack/sendgrid_webhook_verification_spec.rb +116 -0
  32. data/spec/sendgrid/helpers/eventwebhook/eventwebhook_spec.rb +103 -0
  33. data/spec/spec_helper.rb +2 -0
  34. data/static/img/github-fork.png +0 -0
  35. data/static/img/github-sign-up.png +0 -0
  36. data/test/sendgrid/helpers/mail/test_mail.rb +1 -1
  37. data/test/sendgrid/test_sendgrid-ruby.rb +24 -59
  38. data/twilio_sendgrid_logo.png +0 -0
  39. data/use-cases/README.md +16 -0
  40. data/use-cases/domain-authentication.md +5 -0
  41. data/use-cases/email-statistics.md +52 -0
  42. data/use-cases/legacy-templates.md +98 -0
  43. data/use-cases/sms.md +39 -0
  44. data/use-cases/transactional-templates.md +111 -0
  45. data/use-cases/twilio-email.md +13 -0
  46. data/use-cases/twilio-setup.md +54 -0
  47. metadata +54 -8
  48. data/USE_CASES.md +0 -405
  49. data/docker/Dockerfile +0 -12
  50. data/docker/README.md +0 -30
  51. data/test/prism.sh +0 -42
@@ -0,0 +1,52 @@
1
+ require 'base64'
2
+ require 'digest'
3
+ require 'openssl'
4
+
5
+ module SendGrid
6
+ # This class allows you to use the Event Webhook feature. Read the docs for
7
+ # more details: https://sendgrid.com/docs/for-developers/tracking-events/event
8
+ class EventWebhook
9
+ # * *Args* :
10
+ # - +public_key+ -> verification key under Mail Settings
11
+ #
12
+ def convert_public_key_to_ecdsa(public_key)
13
+ verify_engine
14
+ OpenSSL::PKey::EC.new(Base64.decode64(public_key))
15
+ end
16
+
17
+ # * *Args* :
18
+ # - +public_key+ -> elliptic curve public key
19
+ # - +payload+ -> event payload in the request body
20
+ # - +signature+ -> signature value obtained from the 'X-Twilio-Email-Event-Webhook-Signature' header
21
+ # - +timestamp+ -> timestamp value obtained from the 'X-Twilio-Email-Event-Webhook-Timestamp' header
22
+ def verify_signature(public_key, payload, signature, timestamp)
23
+ verify_engine
24
+ timestamped_playload = "#{timestamp}#{payload}"
25
+ payload_digest = Digest::SHA256.digest(timestamped_playload)
26
+ decoded_signature = Base64.decode64(signature)
27
+ public_key.dsa_verify_asn1(payload_digest, decoded_signature)
28
+ rescue
29
+ false
30
+ end
31
+
32
+ def verify_engine
33
+ # JRuby does not fully support ECDSA: https://github.com/jruby/jruby-openssl/issues/193
34
+ if RUBY_PLATFORM == "java"
35
+ raise NotSupportedError, "Event Webhook verification is not supported by JRuby"
36
+ end
37
+ end
38
+
39
+ class Error < ::RuntimeError
40
+ end
41
+
42
+ class NotSupportedError < Error
43
+ end
44
+ end
45
+
46
+ # This class lists headers that get posted to the webhook. Read the docs for
47
+ # more details: https://sendgrid.com/docs/for-developers/tracking-events/event
48
+ class EventWebhookHeader
49
+ SIGNATURE = "HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE"
50
+ TIMESTAMP = "HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP"
51
+ end
52
+ end
@@ -17,7 +17,7 @@
17
17
  # Installation
18
18
 
19
19
  In addition to the installation instructions in
20
- [the main readme](https://github.com/sendgrid/sendgrid-ruby/tree/master/#installation),
20
+ [the main readme](../../../../README.md#installation),
21
21
  you must also add sinatra to your Gemfile:
22
22
 
23
23
  ```
@@ -47,7 +47,7 @@ bundle install
47
47
  ruby ./lib/sendgrid/helpers/inbound/send.rb ./lib/sendgrid/helpers/inbound/sample_data/default_data.txt
48
48
  ```
49
49
 
50
- More sample data can be found [here](https://github.com/sendgrid/sendgrid-ruby/tree/master/lib/sendgrid/helpers/inbound/sample_data).
50
+ More sample data can be found [here](sample_data).
51
51
 
52
52
  View the results in the first terminal.
53
53
 
@@ -82,11 +82,11 @@ Next, send an email to [anything]@inbound.yourdomain.com, then look at the termi
82
82
 
83
83
  ## app.rb
84
84
 
85
- This module runs a [Sinatra](http://www.sinatrarb.com/) server, that by default (you can change those settings [here](https://github.com/sendgrid/sendgrid-ruby/blob/master/sendgrid/helpers/inbound/config.yml)), listens for POSTs on http://localhost:9292. When the server receives the POST, it parses and prints the key/value data.
85
+ This module runs a [Sinatra](http://www.sinatrarb.com/) server, that by default (you can change those settings [here](config.yml)), listens for POSTs on http://localhost:9292. When the server receives the POST, it parses and prints the key/value data.
86
86
 
87
87
  ## config.yml
88
88
 
89
- This module loads application environment variables (located in [config.yml](https://github.com/sendgrid/sendgrid-ruby/blob/master/sendgrid/helpers/inbound/config.yml)).
89
+ This module loads application environment variables (located in [config.yml](config.yml)).
90
90
 
91
91
  ## send.rb & /sample_data
92
92
 
@@ -95,4 +95,4 @@ This module is used to send sample test data. It is useful for testing and devel
95
95
  <a name="contributing"></a>
96
96
  # Contributing
97
97
 
98
- If you would like to contribute to this project, please see our [contributing guide](https://github.com/sendgrid/sendgrid-ruby/blob/master/CONTRIBUTING.md). Thanks!
98
+ If you would like to contribute to this project, please see our [contributing guide](../../../../CONTRIBUTING.md). Thanks!
@@ -5,6 +5,6 @@
5
5
  <body>
6
6
  <h1>You have successfuly launched the server!</h1>
7
7
 
8
- Check out <a href="https://github.com/sendgrid/sendgrid-ruby/tree/master/sendgrid/helpers/inbound">the documentation</a> on how to use this software to utilize the SendGrid Inbound Parse webhook.
8
+ Check out <a href="https://github.com/sendgrid/sendgrid-ruby/tree/HEAD/sendgrid/helpers/inbound">the documentation</a> on how to use this software to utilize the SendGrid Inbound Parse webhook.
9
9
  </body>
10
10
  </html>
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Quick Start
4
4
 
5
- Run the [example](https://github.com/sendgrid/sendgrid-ruby/tree/master/examples/helpers/mail) (make sure you have set your environment variable to include your SENDGRID_API_KEY).
5
+ Run the [example](../../../../examples/helpers/mail) (make sure you have set your environment variable to include your SENDGRID_API_KEY).
6
6
 
7
7
  ```bash
8
8
  ruby examples/helpers/mail/example.rb
@@ -10,5 +10,5 @@ ruby examples/helpers/mail/example.rb
10
10
 
11
11
  ## Usage
12
12
 
13
- - See the [example](https://github.com/sendgrid/sendgrid-ruby/tree/master/examples/helpers/mail) for a complete working example.
14
- - [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/overview.html)
13
+ - See the [example](../../../../examples/helpers/mail) for a complete working example.
14
+ - [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/index.html)
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Quick Start
4
4
 
5
- Run the [example](https://github.com/sendgrid/sendgrid-ruby/tree/master/examples/helpers/settings) (make sure you have set your environment variable to include your SENDGRID_API_KEY).
5
+ Run the [example](../../../../examples/helpers/settings) (make sure you have set your environment variable to include your SENDGRID_API_KEY).
6
6
 
7
7
  ```bash
8
8
  ruby examples/helpers/settings/example.rb
@@ -10,5 +10,5 @@ ruby examples/helpers/settings/example.rb
10
10
 
11
11
  ## Usage
12
12
 
13
- - See the [example](https://github.com/sendgrid/sendgrid-ruby/tree/master/examples/helpers/settings) for a complete working example.
13
+ - See the [example](../../../../examples/helpers/settings) for a complete working example.
14
14
  - [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Settings/index.html)
@@ -1,3 +1,3 @@
1
1
  module SendGrid
2
- VERSION = '6.2.0'
2
+ VERSION = '6.3.4'
3
3
  end
@@ -2,11 +2,11 @@ Hello!
2
2
 
3
3
  It is now time to implement the final piece of our v2 to v3 migration. Before we dig into writing the code, we would love to get feedback on the following proposed interfaces.
4
4
 
5
- We are starting with the use cases below for the first iteration. (we have completed this work on [our C# library](https://github.com/sendgrid/sendgrid-csharp/blob/master/USE_CASES.md), you can check that out for a sneak peek of where we are heading).
5
+ We are starting with the use cases below for the first iteration. (we have completed this work on [our C# library](https://github.com/sendgrid/sendgrid-csharp/blob/HEAD/USE_CASES.md), you can check that out for a sneak peek of where we are heading).
6
6
 
7
7
  # Send a Single Email to a Single Recipient
8
8
 
9
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
9
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
10
10
 
11
11
  ```ruby
12
12
  require 'sendgrid-ruby'
@@ -37,7 +37,7 @@ puts response.headers
37
37
 
38
38
  # Send a Single Email to Multiple Recipients
39
39
 
40
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
40
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
41
41
 
42
42
  ```ruby
43
43
  require 'sendgrid-ruby'
@@ -72,7 +72,7 @@ puts response.headers
72
72
 
73
73
  # Send Multiple Emails to Multiple Recipients
74
74
 
75
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
75
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
76
76
 
77
77
  ```ruby
78
78
  require 'sendgrid-ruby'
@@ -119,7 +119,7 @@ puts response.headers
119
119
 
120
120
  # Kitchen Sink - an example with all settings used
121
121
 
122
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
122
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
123
123
 
124
124
  ```ruby
125
125
  client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
@@ -233,7 +233,7 @@ msg.set_send_at(1461775052, 1)
233
233
 
234
234
  msg.set_subject('this subject overrides the Global Subject on the second Personalization', 1)
235
235
 
236
- # The values below this comment are global to entire message
236
+ # The values below this comment are global to the entire message
237
237
 
238
238
  msg.set_from(SendGrid::Email.new('test0@example.com', 'Example User0'))
239
239
 
@@ -295,7 +295,7 @@ puts response.headers
295
295
 
296
296
  # Attachments
297
297
 
298
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
298
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
299
299
 
300
300
  ```ruby
301
301
  client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
@@ -326,7 +326,7 @@ puts response.headers
326
326
 
327
327
  # Transactional Templates
328
328
 
329
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
329
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
330
330
 
331
331
  For this example, we assume you have created a [transactional template](https://sendgrid.com/docs/User_Guide/Transactional_Templates/index.html). Following is the template content we used for testing.
332
332
 
@@ -347,7 +347,7 @@ Template Body:
347
347
  ```html
348
348
  <html>
349
349
  <head>
350
- <title></title>
350
+ <title></title>
351
351
  </head>
352
352
  <body>
353
353
  Hello -name-,
@@ -27,4 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'faker'
28
28
  spec.add_development_dependency 'rubocop'
29
29
  spec.add_development_dependency 'minitest', '~> 5.9'
30
+ spec.add_development_dependency 'rack'
31
+ spec.add_development_dependency 'simplecov', '~> 0.18.5'
30
32
  end
@@ -0,0 +1,16 @@
1
+ require "json"
2
+
3
+ module Fixtures
4
+ module EventWebhook
5
+ PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEDr2LjtURuePQzplybdC+u4CwrqDqBaWjcMMsTbhdbcwHBcepxo7yAQGhHPTnlvFYPAZFceEu/1FwCM/QmGUhA=='
6
+ FAILING_PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqTxd43gyp8IOEto2LdIfjRQrIbsd4SXZkLW6jDutdhXSJCWHw8REntlo7aNDthvj+y7GjUuFDb/R1NGe1OPzpA=='
7
+ SIGNATURE = 'MEUCIQCtIHJeH93Y+qpYeWrySphQgpNGNr/U+UyUlBkU6n7RAwIgJTz2C+8a8xonZGi6BpSzoQsbVRamr2nlxFDWYNH2j/0='
8
+ FAILING_SIGNATURE = 'MEUCIQCtIHJeH93Y+qpYeWrySphQgpNGNr/U+UyUlBkU6n7RAwIgJTz2C+8a8xonZGi6BpSzoQsbVRamr2nlxFDWYNH3j/0='
9
+ TIMESTAMP = '1588788367'
10
+ PAYLOAD = {
11
+ 'category'=>'example_payload',
12
+ 'event'=>'test_event',
13
+ 'message_id'=>'message_id',
14
+ }.to_json
15
+ end
16
+ end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+ require 'rack/mock'
3
+ require './spec/fixtures/event_webhook'
4
+
5
+ unless RUBY_PLATFORM == 'java'
6
+ describe Rack::SendGridWebhookVerification do
7
+ let(:public_key) { Fixtures::EventWebhook::PUBLIC_KEY }
8
+ before do
9
+ @app = ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['Hello']] }
10
+ end
11
+
12
+ describe 'new' do
13
+ it 'should initialize with an app, public key and a path' do
14
+ expect do
15
+ Rack::SendGridWebhookVerification.new(@app, 'ABC', /\/email/)
16
+ end.not_to raise_error
17
+ end
18
+
19
+ it 'should initialize with an app, public key and paths' do
20
+ expect do
21
+ Rack::SendGridWebhookVerification.new(@app, 'ABC', /\/email/, /\/event/)
22
+ end.not_to raise_error
23
+ end
24
+ end
25
+
26
+ describe 'calling against one path' do
27
+ let(:middleware) { Rack::SendGridWebhookVerification.new(@app, public_key, /\/email/) }
28
+
29
+ it "should not intercept when the path doesn't match" do
30
+ expect(SendGrid::EventWebhook).to_not receive(:new)
31
+ request = Rack::MockRequest.env_for('/login')
32
+ status, headers, body = middleware.call(request)
33
+ expect(status).to eq(200)
34
+ end
35
+
36
+ it 'should allow a request through if it is verified' do
37
+ options = {
38
+ :input => Fixtures::EventWebhook::PAYLOAD,
39
+ 'Content-Type' => "application/json"
40
+ }
41
+ options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
42
+ options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
43
+ request = Rack::MockRequest.env_for('/email', options)
44
+ status, headers, body = middleware.call(request)
45
+ expect(status).to eq(200)
46
+ end
47
+
48
+ it 'should short circuit a request to 403 if there is no signature or timestamp' do
49
+ options = {
50
+ :input => Fixtures::EventWebhook::PAYLOAD,
51
+ 'Content-Type' => "application/json"
52
+ }
53
+ request = Rack::MockRequest.env_for('/email', options)
54
+ status, headers, body = middleware.call(request)
55
+ expect(status).to eq(403)
56
+ end
57
+
58
+ it 'should short circuit a request to 403 if the signature is incorrect' do
59
+ options = {
60
+ :input => Fixtures::EventWebhook::PAYLOAD,
61
+ 'Content-Type' => "application/json"
62
+ }
63
+ options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::FAILING_SIGNATURE
64
+ options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
65
+ request = Rack::MockRequest.env_for('/email', options)
66
+ status, headers, body = middleware.call(request)
67
+ expect(status).to eq(403)
68
+ end
69
+
70
+ it 'should short circuit a request to 403 if the payload is incorrect' do
71
+ options = {
72
+ :input => 'payload',
73
+ 'Content-Type' => "application/json"
74
+ }
75
+ options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
76
+ options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
77
+ request = Rack::MockRequest.env_for('/email', options)
78
+ status, headers, body = middleware.call(request)
79
+ expect(status).to eq(403)
80
+ end
81
+ end
82
+
83
+ describe 'calling with multiple paths' do
84
+ let(:middleware) { Rack::SendGridWebhookVerification.new(@app, public_key, /\/email/, /\/events/) }
85
+
86
+ it "should not intercept when the path doesn't match" do
87
+ expect(SendGrid::EventWebhook).to_not receive(:new)
88
+ request = Rack::MockRequest.env_for('/sms_events')
89
+ status, headers, body = middleware.call(request)
90
+ expect(status).to eq(200)
91
+ end
92
+
93
+ it 'should allow a request through if it is verified' do
94
+ options = {
95
+ :input => Fixtures::EventWebhook::PAYLOAD,
96
+ 'Content-Type' => "application/json"
97
+ }
98
+ options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
99
+ options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
100
+ request = Rack::MockRequest.env_for('/events', options)
101
+ status, headers, body = middleware.call(request)
102
+ expect(status).to eq(200)
103
+ end
104
+
105
+ it 'should short circuit a request to 403 if there is no signature or timestamp' do
106
+ options = {
107
+ :input => Fixtures::EventWebhook::PAYLOAD,
108
+ 'Content-Type' => "application/json"
109
+ }
110
+ request = Rack::MockRequest.env_for('/events', options)
111
+ status, headers, body = middleware.call(request)
112
+ expect(status).to eq(403)
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+ require './spec/fixtures/event_webhook'
3
+
4
+ describe SendGrid::EventWebhook do
5
+ describe '.verify_signature' do
6
+ it 'verifies a valid signature' do
7
+ unless skip_jruby
8
+ expect(verify(
9
+ Fixtures::EventWebhook::PUBLIC_KEY,
10
+ Fixtures::EventWebhook::PAYLOAD,
11
+ Fixtures::EventWebhook::SIGNATURE,
12
+ Fixtures::EventWebhook::TIMESTAMP
13
+ )).to be true
14
+ end
15
+ end
16
+
17
+ it 'rejects a bad key' do
18
+ unless skip_jruby
19
+ expect(verify(
20
+ Fixtures::EventWebhook::FAILING_PUBLIC_KEY,
21
+ Fixtures::EventWebhook::PAYLOAD,
22
+ Fixtures::EventWebhook::SIGNATURE,
23
+ Fixtures::EventWebhook::TIMESTAMP
24
+ )).to be false
25
+ end
26
+ end
27
+
28
+ it 'rejects a bad payload' do
29
+ unless skip_jruby
30
+ expect(verify(
31
+ Fixtures::EventWebhook::PUBLIC_KEY,
32
+ 'payload',
33
+ Fixtures::EventWebhook::SIGNATURE,
34
+ Fixtures::EventWebhook::TIMESTAMP
35
+ )).to be false
36
+ end
37
+ end
38
+
39
+ it 'rejects a bad signature' do
40
+ unless skip_jruby
41
+ expect(verify(
42
+ Fixtures::EventWebhook::PUBLIC_KEY,
43
+ Fixtures::EventWebhook::PAYLOAD,
44
+ Fixtures::EventWebhook::FAILING_SIGNATURE,
45
+ Fixtures::EventWebhook::TIMESTAMP
46
+ )).to be false
47
+ end
48
+ end
49
+
50
+ it 'rejects a bad timestamp' do
51
+ unless skip_jruby
52
+ expect(verify(
53
+ Fixtures::EventWebhook::PUBLIC_KEY,
54
+ Fixtures::EventWebhook::PAYLOAD,
55
+ Fixtures::EventWebhook::SIGNATURE,
56
+ 'timestamp'
57
+ )).to be false
58
+ end
59
+ end
60
+
61
+ it 'rejects a missing signature' do
62
+ unless skip_jruby
63
+ expect(verify(
64
+ Fixtures::EventWebhook::PUBLIC_KEY,
65
+ Fixtures::EventWebhook::PAYLOAD,
66
+ nil,
67
+ Fixtures::EventWebhook::TIMESTAMP
68
+ )).to be false
69
+ end
70
+ end
71
+
72
+ it 'throws an error when using jruby' do
73
+ if skip_jruby
74
+ expect{ verify(
75
+ Fixtures::EventWebhook::PUBLIC_KEY,
76
+ Fixtures::EventWebhook::PAYLOAD,
77
+ Fixtures::EventWebhook::SIGNATURE,
78
+ Fixtures::EventWebhook::TIMESTAMP
79
+ )}.to raise_error(SendGrid::EventWebhook::NotSupportedError)
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ describe SendGrid::EventWebhookHeader do
86
+ it 'sets the signature header constant' do
87
+ expect(SendGrid::EventWebhookHeader::SIGNATURE).to eq("HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE")
88
+ end
89
+
90
+ it 'sets the timestamp header constant' do
91
+ expect(SendGrid::EventWebhookHeader::TIMESTAMP).to eq("HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP")
92
+ end
93
+ end
94
+
95
+ def verify(public_key, payload, signature, timestamp)
96
+ ew = SendGrid::EventWebhook.new
97
+ ec_public_key = ew.convert_public_key_to_ecdsa(public_key)
98
+ ew.verify_signature(ec_public_key, payload, signature, timestamp)
99
+ end
100
+
101
+ def skip_jruby
102
+ RUBY_PLATFORM == 'java'
103
+ end