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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +1 -1
- data/.gitignore +2 -0
- data/.rubocop.yml +6 -0
- data/.travis.yml +12 -21
- data/CHANGELOG.md +57 -8
- data/CONTRIBUTING.md +10 -17
- data/Dockerfile +14 -0
- data/FIRST_TIMERS.md +79 -0
- data/Gemfile +0 -1
- data/ISSUE_TEMPLATE.md +5 -1
- data/Makefile +9 -2
- data/PULL_REQUEST_TEMPLATE.md +1 -1
- data/README.md +22 -21
- data/TROUBLESHOOTING.md +5 -5
- data/USAGE.md +35 -36
- data/examples/helpers/eventwebhook/example.rb +16 -0
- data/examples/helpers/mail/example.rb +11 -4
- data/examples/mail/mail.rb +1 -1
- data/lib/rack/sendgrid_webhook_verification.rb +52 -0
- data/lib/sendgrid-ruby.rb +2 -0
- data/lib/sendgrid/helpers/eventwebhook/eventwebhook.rb +52 -0
- data/lib/sendgrid/helpers/inbound/README.md +5 -5
- data/lib/sendgrid/helpers/inbound/public/index.html +1 -1
- data/lib/sendgrid/helpers/mail/README.md +3 -3
- data/lib/sendgrid/helpers/settings/README.md +2 -2
- data/lib/sendgrid/version.rb +1 -1
- data/mail_helper_v3.md +9 -9
- data/sendgrid-ruby.gemspec +2 -0
- data/spec/fixtures/event_webhook.rb +16 -0
- data/spec/rack/sendgrid_webhook_verification_spec.rb +116 -0
- data/spec/sendgrid/helpers/eventwebhook/eventwebhook_spec.rb +103 -0
- data/spec/spec_helper.rb +2 -0
- data/static/img/github-fork.png +0 -0
- data/static/img/github-sign-up.png +0 -0
- data/test/sendgrid/helpers/mail/test_mail.rb +1 -1
- data/test/sendgrid/test_sendgrid-ruby.rb +24 -59
- data/twilio_sendgrid_logo.png +0 -0
- data/use-cases/README.md +16 -0
- data/use-cases/domain-authentication.md +5 -0
- data/use-cases/email-statistics.md +52 -0
- data/use-cases/legacy-templates.md +98 -0
- data/use-cases/sms.md +39 -0
- data/use-cases/transactional-templates.md +111 -0
- data/use-cases/twilio-email.md +13 -0
- data/use-cases/twilio-setup.md +54 -0
- metadata +54 -8
- data/USE_CASES.md +0 -405
- data/docker/Dockerfile +0 -12
- data/docker/README.md +0 -30
- 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](
|
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](
|
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](
|
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](
|
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](
|
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/
|
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](
|
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](
|
14
|
-
- [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/
|
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](
|
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](
|
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)
|
data/lib/sendgrid/version.rb
CHANGED
data/mail_helper_v3.md
CHANGED
@@ -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/
|
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)](
|
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)](
|
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)](
|
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)](
|
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)](
|
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)](
|
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
|
-
|
350
|
+
<title></title>
|
351
351
|
</head>
|
352
352
|
<body>
|
353
353
|
Hello -name-,
|
data/sendgrid-ruby.gemspec
CHANGED
@@ -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
|