Skip to content

Commit

Permalink
Merge pull request #70 from experius/feature/SPC-4644
Browse files Browse the repository at this point in the history
Feature/spc 4644
  • Loading branch information
mhaagen85 authored Nov 8, 2024
2 parents ef8a626 + 1c0373d commit 59bb7d3
Show file tree
Hide file tree
Showing 10 changed files with 264 additions and 60 deletions.
19 changes: 3 additions & 16 deletions Model/Config/Source/EmailTemplates.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,16 @@

class EmailTemplates implements ArrayInterface
{
/**
* @var Config
*/
protected $templateConfig;

/**
* @var CollectionFactory
*/
protected $emailTemplateCollectionFactory;

/**
* EmailTemplates constructor.
*
* @param Config $templateConfig
* @param CollectionFactory $emailTemplateCollectionFactory
*/
public function __construct(
Config $templateConfig,
CollectionFactory $emailTemplateCollectionFactory
) {
$this->templateConfig = $templateConfig;
$this->emailTemplateCollectionFactory = $emailTemplateCollectionFactory;
}
protected Config $templateConfig,
protected CollectionFactory $emailTemplateCollectionFactory
) {}

/**
* To option array
Expand Down
76 changes: 76 additions & 0 deletions Model/Emailcatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Framework\Registry;
use Experius\EmailCatcher\Registry\CurrentTemplate;
use Magento\Store\Model\ScopeInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;

class Emailcatcher extends AbstractModel
{
const CONFIG_PATH_EMAIL_CATCHER_ENABLED = 'emailcatcher/general/enabled';
const CONFIG_PATH_DEVELOPMENT_EMAIL_CATCHER_ADMIN_ALLOWED_ENABLED = 'emailcatcher/development/enabled';
const CONFIG_PATH_WHITELIST_APPLY_WHITELIST = 'emailcatcher/whitelist/apply_whitelist';
const CONFIG_PATH_BLACKLIST_APPLY_BlACKLIST = 'emailcatcher/blacklist/apply_blacklist';
const CONFIG_PATH_TEMPLATE_WHITELIST = 'emailcatcher/whitelist/email_templates';
const CONFIG_PATH_DEVELOPMENT_EMAIL_CATCHER_ALLOWED_ADDRESSES = 'emailcatcher/development/allow_email_addresses';

/**
* @var string
*/
Expand All @@ -38,6 +47,7 @@ public function __construct(
Context $context,
Registry $registry,
protected CurrentTemplate $currentTemplate,
protected ScopeConfigInterface $scopeConfig,
AbstractResource $resource = null,
AbstractDb $resourceCollection = null,
array $data = []
Expand Down Expand Up @@ -120,4 +130,70 @@ public function imapUtf8($string)
{
return (function_exists('imap_utf8') && is_string($string)) ? imap_utf8($string) : $string;
}

/**
* @return bool
*/
public function blackListEnabled(): bool
{
return $this->scopeConfig->isSetFlag(
self::CONFIG_PATH_BLACKLIST_APPLY_BlACKLIST,
ScopeInterface::SCOPE_STORE
);
}

/**
* @return bool
*/
public function whitelistEnabled(): bool
{
return $this->scopeConfig->isSetFlag(
self::CONFIG_PATH_WHITELIST_APPLY_WHITELIST,
ScopeInterface::SCOPE_STORE
);
}

/**
* @return mixed
*/
public function getWhitelistedTemplates(): mixed
{
return $this->scopeConfig->getValue(
Emailcatcher::CONFIG_PATH_TEMPLATE_WHITELIST,
ScopeInterface::SCOPE_STORE
);
}

/**
* @return bool
*/
public function emailCatcherEnabled(): bool
{
return $this->scopeConfig->isSetFlag(
self::CONFIG_PATH_EMAIL_CATCHER_ENABLED,
ScopeInterface::SCOPE_STORE
);
}

/**
* @return bool
*/
public function developmentAdminAllowedEnabled(): bool
{
return $this->scopeConfig->isSetFlag(
Emailcatcher::CONFIG_PATH_DEVELOPMENT_EMAIL_CATCHER_ADMIN_ALLOWED_ENABLED,
ScopeInterface::SCOPE_STORE
);
}

/**
* @return array|mixed
*/
public function getDevelopmentAdminAllowedEmailAddresses(): mixed
{
return $this->scopeConfig->getValue(
Emailcatcher::CONFIG_PATH_DEVELOPMENT_EMAIL_CATCHER_ALLOWED_ADDRESSES,
ScopeInterface::SCOPE_STORE) ?: [];
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class TransportBuilder
* @param CurrentTemplate $currentTemplate
*/
public function __construct(
private CurrentTemplate $currentTemplate
protected CurrentTemplate $currentTemplate
) {
}

Expand Down
72 changes: 38 additions & 34 deletions Plugin/Magento/Framework/Mail/TransportInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,22 @@
use Magento\Framework\App\Config\ScopeConfigInterface;
use \Magento\Store\Model\ScopeInterface;
use Experius\EmailCatcher\Registry\CurrentTemplate;
use Experius\EmailCatcher\Model\Emailcatcher;

class TransportInterface
{
const CONFIG_PATH_EMAIL_CATCHER_ENABLED = 'emailcatcher/general/enabled';
const CONFIG_PATH_WHITELIST_APPLY_WHITELIST = 'emailcatcher/whitelist/apply_whitelist';
const CONFIG_PATH_TEMPLATE_WHITELIST = 'emailcatcher/whitelist/email_templates';

/**
* @param ScopeConfigInterface $scopeConfig
* @param EmailcatcherFactory $emailCatcher
* @param EmailcatcherFactory $emailCatcherFactory
* @param CurrentTemplate $currentTemplate
* @param Emailcatcher $emailcatcher
*/
public function __construct(
private ScopeConfigInterface $scopeConfig,
private EmailcatcherFactory $emailCatcher,
private CurrentTemplate $currentTemplate
) {
}
protected ScopeConfigInterface $scopeConfig,
protected EmailcatcherFactory $emailCatcherFactory,
protected CurrentTemplate $currentTemplate,
protected Emailcatcher $emailcatcher
) {}

/**
* Around sendMessage plugin
Expand All @@ -42,18 +40,23 @@ public function aroundSendMessage(
\Magento\Framework\Mail\TransportInterface $subject,
\Closure $proceed
) {
if (!$this->scopeConfig->isSetFlag(self::CONFIG_PATH_EMAIL_CATCHER_ENABLED, ScopeInterface::SCOPE_STORE)) {
if (!$this->emailcatcher->emailCatcherEnabled()) {
return $proceed();
}

if ($this->emailcatcher->blackListEnabled() && in_array($this->getToEmailAddress($subject), $this->getBlacklistEmailAddresses())) {
$subject->getMessage()->setSubject('Prevent Being Sent - Blacklisted Email Address');
$this->saveMessage($subject);

return;
}

$this->saveMessage($subject);

// Proceed if whitelist feature is not enabled
if (!$this->scopeConfig->isSetFlag(self::CONFIG_PATH_WHITELIST_APPLY_WHITELIST, ScopeInterface::SCOPE_STORE)) {
if (!$this->emailcatcher->whitelistEnabled()) {
return $proceed();
}

// Check if template is whitelisted
$currentTemplate = $this->currentTemplate->get();
if (!empty($this->getTemplateWhitelist())) {
if (in_array($currentTemplate, $this->getTemplateWhitelist())) {
Expand All @@ -63,38 +66,39 @@ public function aroundSendMessage(
}

/**
* Save message
*
* @param $subject
* @return void
* @throws \ReflectionException
*/
private function saveMessage($subject)
private function saveMessage($subject): void
{
// For >= 2.2
if (method_exists($subject, 'getMessage')) {
$this->emailCatcher->create()->saveMessage($subject->getMessage());
} else {
//For < 2.2
$reflection = new \ReflectionClass($subject);
$property = $reflection->getProperty('_message');
$property->setAccessible(true);
$this->emailCatcher->create()->saveMessage($property->getValue($subject));
}
$this->emailCatcherFactory->create()->saveMessage($subject->getMessage());
}

/**
* Get whitelisted templates
*
* @return array
*/
private function getTemplateWhitelist()
private function getTemplateWhitelist(): array
{
$templates = $this->scopeConfig->getValue(
self::CONFIG_PATH_TEMPLATE_WHITELIST,
ScopeInterface::SCOPE_STORE
);
$templates = $this->emailcatcher->getWhitelistedTemplates();

return $templates ? explode(',', $templates) : [];
}

/**
* @return array
*/
protected function getBlacklistEmailAddresses() : array
{
return explode(',', $this->scopeConfig->getValue('emailcatcher/blacklist/block_email_addresses'));
}

/**
* @param $subject
* @return string
*/
protected function getToEmailAddress($subject): string
{
return $subject->getMessage()->getTo()[0]->getEmail() ?? '';
}
}
94 changes: 94 additions & 0 deletions Plugin/Magento/Framework/Mail/TransportInterfacePlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace Experius\EmailCatcher\Plugin\Magento\Framework\Mail;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\User\Model\ResourceModel\User\CollectionFactory as UserCollectionFactory;
use Experius\EmailCatcher\Model\Emailcatcher;

class TransportInterfacePlugin
{
/**
* @param ScopeConfigInterface $scopeConfig
* @param UserCollectionFactory $userCollectionFactory
* @param Emailcatcher $emailcatcher
*/
public function __construct(
protected ScopeConfigInterface $scopeConfig,
protected UserCollectionFactory $userCollectionFactory,
protected Emailcatcher $emailcatcher
) {}

/**
* @param \Magento\Framework\Mail\TransportInterface $subject
* @param \Closure $proceed
* @return void
*/
public function aroundSendMessage(
\Magento\Framework\Mail\TransportInterface $subject,
\Closure $proceed
): void
{
if (!$this->scopeConfig->isSetFlag('system/smtp/disable', ScopeInterface::SCOPE_STORE)) {
$proceed();
return;
}

if ($this->emailcatcher->developmentAdminAllowedEnabled()) {
$emailAddresses = [];
foreach ($subject->getMessage()->getTo() as $to) {
$emailAddresses[] = $to->getEmail();
}
foreach ($subject->getMessage()->getCc() as $cc) {
$emailAddresses[] = $cc->getEmail();
}
foreach ($subject->getMessage()->getBcc() as $bcc) {
$emailAddresses[] = $bcc->getEmail();
}
if ($this->containsOnlyAdminUsers($emailAddresses)) {
$proceed();
}
}
}

/**
* @param $emailAddresses
* @return bool
*/
public function containsOnlyAdminUsers($emailAddresses): bool
{
$nonAdminEmailAddresses = array_diff($emailAddresses, $this->getAdminAndCustomAllowedEmails());

return count($nonAdminEmailAddresses) === 0;
}

/**
* @return array
*/
protected function getAdminAndCustomAllowedEmails(): array
{
return array_merge($this->getAdminEmails(), $this->getCustomAllowedEmails());
}

/**
* @return array
*/
protected function getAdminEmails(): array
{
$collection = $this->userCollectionFactory->create();

return $collection->addFieldToSelect('email')->getColumnValues('email');
}

/**
* @return array
*/
protected function getCustomAllowedEmails(): array
{
$customEmails = $this->emailcatcher->getDevelopmentAdminAllowedEmailAddresses();

return !is_array($customEmails) ? explode(',', $customEmails) : $customEmails;
}

}
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
- Resend a caught email
- Cleanup emails older than 30 days (cron or manual)
- Send emails based on whitelisted email templates
- Block emails based on blacklisted email list
- Enable admin user to receive email while magento email communication is disabled


## Versions

Expand Down Expand Up @@ -56,5 +59,13 @@ Utilise whitelist functionality
- Stores > Settings > Configuration > Advanced > Email Catcher > Whitelist > Apply whitelist (emailcatcher/whitelist/apply_whitelist)
- Stores > Settings > Configuration > Advanced > Email Catcher > Whitelist > Whitelisted templates (emailcatcher/whitelist/email_templates)

Utilise blacklist functionality
- Stores > Settings > Configuration > Advanced > Email Catcher > Blacklist > Apply blacklist (emailcatcher/blacklist/apply_blacklist)
- Stores > Settings > Configuration > Advanced > Email Catcher > Blacklist > Blacklisted templates (emailcatcher/blacklist/block_email_addresses)

Utilise enable admin user receive email
- Stores > Settings > Configuration > Advanced > Email Catcher > General > Enable Admin User Receive Email (emailcatcher/development/enabled)
- Stores > Settings > Configuration > Advanced > Email Catcher > General > Admin User Email (emailcatcher/development/allow_email_addresses)

Admin grid
- System > Tools > Email Catcher
Loading

0 comments on commit 59bb7d3

Please sign in to comment.