feat: email recipient whitelist
This commit is contained in:
1 parent
4cab57d136
commit
7cf39850e6
4 files changed
+308
No files matched your search
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\EventListener;
|
||||
|
||||
use App\EventListener\EmailRecipientWhitelistSubscriber;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Mailer\Envelope;
|
||||
use Symfony\Component\Mailer\Event\MessageEvent;
|
||||
use Symfony\Component\Mime\Address;
|
||||
use Symfony\Component\Mime\Email;
|
||||
|
||||
/**
|
||||
* The guard that keeps staging from mailing real teamers: everything not whitelisted has to
|
||||
* leave the envelope, and a mail with nothing left must not be sent at all.
|
||||
*/
|
||||
class EmailRecipientWhitelistSubscriberTest extends TestCase
|
||||
{
|
||||
public function testKeepsEnvelopeUntouchedWhenEveryRecipientIsWhitelisted(): void
|
||||
{
|
||||
$event = $this->event(['[email protected]', '[email protected]']);
|
||||
|
||||
$this->subscriber(['.*@ep-reisen\.de', 'qa@example\.com'])->onMessage($event);
|
||||
|
||||
self::assertFalse($event->isRejected());
|
||||
self::assertSame(
|
||||
['[email protected]', '[email protected]'],
|
||||
$this->addresses($event)
|
||||
);
|
||||
}
|
||||
|
||||
public function testStripsTheRecipientsThatAreNotWhitelisted(): void
|
||||
{
|
||||
$event = $this->event(['[email protected]', '[email protected]', '[email protected]']);
|
||||
|
||||
$this->subscriber(['.*@ep-reisen\.de'])->onMessage($event);
|
||||
|
||||
self::assertFalse($event->isRejected());
|
||||
self::assertSame(['[email protected]'], $this->addresses($event));
|
||||
}
|
||||
|
||||
public function testRejectsTheMailWhenNoRecipientIsWhitelisted(): void
|
||||
{
|
||||
$event = $this->event(['[email protected]', '[email protected]']);
|
||||
|
||||
$this->subscriber(['.*@ep-reisen\.de'])->onMessage($event);
|
||||
|
||||
self::assertTrue($event->isRejected());
|
||||
}
|
||||
|
||||
public function testDoesNothingWithoutAWhitelist(): void
|
||||
{
|
||||
$event = $this->event(['[email protected]']);
|
||||
|
||||
$this->subscriber([])->onMessage($event);
|
||||
|
||||
self::assertFalse($event->isRejected());
|
||||
self::assertSame(['[email protected]'], $this->addresses($event));
|
||||
}
|
||||
|
||||
public function testPatternsAreAnchoredToTheWholeAddress(): void
|
||||
{
|
||||
$event = $this->event(['[email protected]']);
|
||||
|
||||
$this->subscriber(['.*@ep-reisen\.de'])->onMessage($event);
|
||||
|
||||
self::assertTrue($event->isRejected());
|
||||
}
|
||||
|
||||
public function testMatchingIsCaseInsensitive(): void
|
||||
{
|
||||
$event = $this->event(['[email protected]']);
|
||||
|
||||
$this->subscriber(['.*@ep-reisen\.de'])->onMessage($event);
|
||||
|
||||
self::assertFalse($event->isRejected());
|
||||
self::assertSame(['[email protected]'], $this->addresses($event));
|
||||
}
|
||||
|
||||
public function testBlankPatternsAreIgnoredInsteadOfDroppingEveryMail(): void
|
||||
{
|
||||
$event = $this->event(['[email protected]']);
|
||||
|
||||
$this->subscriber([' ', '', "\t"])->onMessage($event);
|
||||
|
||||
self::assertFalse($event->isRejected());
|
||||
self::assertSame(['[email protected]'], $this->addresses($event));
|
||||
}
|
||||
|
||||
public function testPatternsAreTrimmed(): void
|
||||
{
|
||||
$event = $this->event(['[email protected]', '[email protected]']);
|
||||
|
||||
$this->subscriber([' .*@ep-reisen\\.de '])->onMessage($event);
|
||||
|
||||
self::assertFalse($event->isRejected());
|
||||
self::assertSame(['[email protected]'], $this->addresses($event));
|
||||
}
|
||||
|
||||
public function testAnInvalidPatternFailsLoudlyOnConstruction(): void
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Invalid recipient whitelist pattern ".*@ep-reisen\\.de("');
|
||||
|
||||
$this->subscriber(['.*@ep-reisen\\.de(']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $allowedRecipients
|
||||
*/
|
||||
private function subscriber(array $allowedRecipients): EmailRecipientWhitelistSubscriber
|
||||
{
|
||||
return new EmailRecipientWhitelistSubscriber($allowedRecipients, new NullLogger());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $recipients
|
||||
*/
|
||||
private function event(array $recipients): MessageEvent
|
||||
{
|
||||
$email = (new Email())
|
||||
->from('[email protected]')
|
||||
->to(...$recipients)
|
||||
->subject('Honorarvertrag fällig')
|
||||
->text('...')
|
||||
;
|
||||
|
||||
return new MessageEvent(
|
||||
$email,
|
||||
new Envelope(new Address('[email protected]'), Address::createArray($recipients)),
|
||||
'main'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function addresses(MessageEvent $event): array
|
||||
{
|
||||
return array_map(
|
||||
static fn (Address $address) => $address->getAddress(),
|
||||
$event->getEnvelope()->getRecipients()
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user