Skip to content

[Mailer][Webhook] Fix SendGrid Webhook parsing #58401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
{"email":"hello@world.com","event":"dropped","reason":"Bounced Address","sg_event_id":"ZHJvcC0xMDk5NDkxOS1MUnpYbF9OSFN0T0doUTRrb2ZTbV9BLTA","sg_message_id":"LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0","smtp-id":"<LRzXl_NHStOGhQ4kofSm_A@ismtpd0039p1iad1.sendgrid.net>","timestamp":1600112492},
{"email":"hello@world.com","event":"click","sg_event_id":"ZHJvcC0xMDk5NDkxOS1MUnpYbF9OSFN0T0doUTRrb2ZTbV9BLTA","sg_message_id":"LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0","smtp-id":"<LRzXl_NHStOGhQ4kofSm_A@ismtpd0039p1iad1.sendgrid.net>","timestamp":1600112492}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent;
use Symfony\Component\RemoteEvent\Event\Mailer\MailerEngagementEvent;

$wh1 = new MailerDeliveryEvent(MailerDeliveryEvent::DROPPED, 'LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)[0]);
$wh1->setRecipientEmail('hello@world.com');
$wh1->setTags([]);
$wh1->setMetadata([]);
$wh1->setReason('Bounced Address');
$wh1->setDate(\DateTimeImmutable::createFromFormat('U', 1600112492));

$wh2 = new MailerEngagementEvent(MailerEngagementEvent::CLICK, 'LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)[1]);
$wh2->setRecipientEmail('hello@world.com');
$wh2->setTags([]);
$wh2->setMetadata([]);
$wh2->setDate(\DateTimeImmutable::createFromFormat('U', 1600112492));

return [$wh1, $wh2];
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
$wh->setReason('Bounced Address');
$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1600112492));

return $wh;
return [$wh];
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@
*/
class SendgridSignedRequestParserTest extends AbstractRequestParserTestCase
{
private const PRIVATE_KEY = <<<'KEY'
-----BEGIN RSA PRIVATE KEY-----
MIICWgIBAAKBgHH/ZmiTGDi6/1IIx4vOKedN24Zuxj9G0ioNpCbNssQlukWijQiz
UaOZ98JgEA11jGY1gFwCKYVSH5e1ZWN+m4hdxNQoNn8QaODzyo2ocGbobzrIuMJp
mroyl6WmNa0jW8DMoW1Mpsxo/Vw9FrkAL+eSYgR8ZFWeXbcD8yRfVm/lAgMBAAEC
gYBDqSUtWHD96u9zz0Yw0pLIeMudBM6h6/T9hM8zQM+j4AipIAu5aEVCZzZIph+g
/W3xlDu1YIsoWE/sCXw+C31gLgDAd/4++G+3nuQumv5TgdWyZkXrFZ+HiPk77fqh
F6U+5vTSYS/BOueisDUY7ndgf9pFVZtj5rKHHOmL26KFgQJBAK6npY3H1UyYHi/t
vaxH/5KVqBDWuUE1+MjyVF0KbjyZOzMka7/4DenbBsZRDCqNrP8psuCwOFPf+vwN
uVmE7vECQQCnF4F/INbeZkL3EQTMhCF3kIuY9jtB/ah+FQ/zom0gcw4zNAzKVeFm
SmCTAeZbqq+fTFgwueIE4mPv4hiT0Hg1AkBIqoGr6p+pPYUZxd1rh40i7Nc/Ikdz
hUQcPw6woz1YQxypW5blCQyo5rL74g6gyc9XXn8JEuhspTzkj8U1JKTRAkASdDAj
IDda3KRssP58r+MaV2ZzgE5PHXqsYhse50NyIALjeM4o0o9QQsqjscQFP7ahu0bK
Kt1heLdc2PWp7Y45AkAdAVZd//vS9FLU397DZAf7h+5qhUmPkm8vxnehCH+olQXq
SPExlMI7PVpISz7jk9hRF31NStTZok//CUcq+yxJ
-----END RSA PRIVATE KEY-----
KEY;
private const SECRET = 'MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHH/ZmiTGDi6/1IIx4vOKedN24Zuxj9G0ioNpCbNssQlukWijQizUaOZ98JgEA11jGY1gFwCKYVSH5e1ZWN+m4hdxNQoNn8QaODzyo2ocGbobzrIuMJpmroyl6WmNa0jW8DMoW1Mpsxo/Vw9FrkAL+eSYgR8ZFWeXbcD8yRfVm/lAgMBAAE=';

protected function createRequestParser(): RequestParserInterface
{
return new SendgridRequestParser(new SendgridPayloadConverter(), true);
Expand All @@ -34,15 +53,19 @@ protected function createRequestParser(): RequestParserInterface
*/
protected function createRequest(string $payload): Request
{
$payload = str_replace("\n", "\r\n", $payload);

openssl_sign('1600112502'.$payload, $signature, self::PRIVATE_KEY, \OPENSSL_ALGO_SHA256);

return Request::create('/', 'POST', [], [], [], [
'Content-Type' => 'application/json',
'HTTP_X-Twilio-Email-Event-Webhook-Signature' => 'MEUCIGHQVtGj+Y3LkG9fLcxf3qfI10QysgDWmMOVmxG0u6ZUAiEAyBiXDWzM+uOe5W0JuG+luQAbPIqHh89M15TluLtEZtM=',
'HTTP_X-Twilio-Email-Event-Webhook-Signature' => base64_encode($signature),
'HTTP_X-Twilio-Email-Event-Webhook-Timestamp' => '1600112502',
], str_replace("\n", "\r\n", $payload));
], $payload);
}

protected function getSecret(): string
{
return 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g==';
return self::SECRET;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ protected function getRequestMatcher(): RequestMatcherInterface
]);
}

protected function doParse(Request $request, string $secret): ?AbstractMailerEvent
/**
* @return AbstractMailerEvent[]
*/
protected function doParse(Request $request, string $secret): array
{
$content = $request->toArray();
if (
Expand Down Expand Up @@ -69,7 +72,7 @@ protected function doParse(Request $request, string $secret): ?AbstractMailerEve
}

try {
return $this->converter->convert($content[0]);
return array_map($this->converter->convert(...), $content);
} catch (ParseException $e) {
throw new RejectWebhookException(406, $e->getMessage(), $e);
}
Expand Down
5 changes: 3 additions & 2 deletions src/Symfony/Component/Mailer/Bridge/Sendgrid/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
},
"require-dev": {
"symfony/http-client": "^6.4|^7.0",
"symfony/webhook": "^6.4|^7.0"
"symfony/webhook": "^7.2"
},
"conflict": {
"symfony/mime": "<6.4",
"symfony/http-foundation": "<6.4"
"symfony/http-foundation": "<6.4",
"symfony/webhook": "<7.2"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Mailer\\Bridge\\Sendgrid\\": "" },
Expand Down
Loading