diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index 07df0637d57f4..62f544c579ae5 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -371,6 +371,12 @@ + + + + + + @@ -452,6 +458,9 @@ + + + recipientName]]> @@ -864,6 +873,11 @@ + + + + + @@ -1572,6 +1586,7 @@ + @@ -2079,6 +2094,7 @@ + @@ -2201,6 +2217,10 @@ + + + + getId()]]> @@ -3053,6 +3073,11 @@ + + + + + diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index f91dddca7dc5f..d525f0d67f55c 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -655,6 +655,7 @@ 'OCP\\Mail\\Headers\\AutoSubmitted' => $baseDir . '/lib/public/Mail/Headers/AutoSubmitted.php', 'OCP\\Mail\\IAttachment' => $baseDir . '/lib/public/Mail/IAttachment.php', 'OCP\\Mail\\IEMailTemplate' => $baseDir . '/lib/public/Mail/IEMailTemplate.php', + 'OCP\\Mail\\IEmailValidator' => $baseDir . '/lib/public/Mail/IEmailValidator.php', 'OCP\\Mail\\IMailer' => $baseDir . '/lib/public/Mail/IMailer.php', 'OCP\\Mail\\IMessage' => $baseDir . '/lib/public/Mail/IMessage.php', 'OCP\\Mail\\Provider\\Address' => $baseDir . '/lib/public/Mail/Provider/Address.php', @@ -1820,6 +1821,7 @@ 'OC\\Log\\Systemdlog' => $baseDir . '/lib/private/Log/Systemdlog.php', 'OC\\Mail\\Attachment' => $baseDir . '/lib/private/Mail/Attachment.php', 'OC\\Mail\\EMailTemplate' => $baseDir . '/lib/private/Mail/EMailTemplate.php', + 'OC\\Mail\\EmailValidator' => $baseDir . '/lib/private/Mail/EmailValidator.php', 'OC\\Mail\\Mailer' => $baseDir . '/lib/private/Mail/Mailer.php', 'OC\\Mail\\Message' => $baseDir . '/lib/private/Mail/Message.php', 'OC\\Mail\\Provider\\Manager' => $baseDir . '/lib/private/Mail/Provider/Manager.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index a93f079ee7ed9..b6e6529e7c32a 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -696,6 +696,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\Mail\\Headers\\AutoSubmitted' => __DIR__ . '/../../..' . '/lib/public/Mail/Headers/AutoSubmitted.php', 'OCP\\Mail\\IAttachment' => __DIR__ . '/../../..' . '/lib/public/Mail/IAttachment.php', 'OCP\\Mail\\IEMailTemplate' => __DIR__ . '/../../..' . '/lib/public/Mail/IEMailTemplate.php', + 'OCP\\Mail\\IEmailValidator' => __DIR__ . '/../../..' . '/lib/public/Mail/IEmailValidator.php', 'OCP\\Mail\\IMailer' => __DIR__ . '/../../..' . '/lib/public/Mail/IMailer.php', 'OCP\\Mail\\IMessage' => __DIR__ . '/../../..' . '/lib/public/Mail/IMessage.php', 'OCP\\Mail\\Provider\\Address' => __DIR__ . '/../../..' . '/lib/public/Mail/Provider/Address.php', @@ -1861,6 +1862,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Log\\Systemdlog' => __DIR__ . '/../../..' . '/lib/private/Log/Systemdlog.php', 'OC\\Mail\\Attachment' => __DIR__ . '/../../..' . '/lib/private/Mail/Attachment.php', 'OC\\Mail\\EMailTemplate' => __DIR__ . '/../../..' . '/lib/private/Mail/EMailTemplate.php', + 'OC\\Mail\\EmailValidator' => __DIR__ . '/../../..' . '/lib/private/Mail/EmailValidator.php', 'OC\\Mail\\Mailer' => __DIR__ . '/../../..' . '/lib/private/Mail/Mailer.php', 'OC\\Mail\\Message' => __DIR__ . '/../../..' . '/lib/private/Mail/Message.php', 'OC\\Mail\\Provider\\Manager' => __DIR__ . '/../../..' . '/lib/private/Mail/Provider/Manager.php', diff --git a/lib/private/Mail/EmailValidator.php b/lib/private/Mail/EmailValidator.php new file mode 100644 index 0000000000000..e819817b7a94a --- /dev/null +++ b/lib/private/Mail/EmailValidator.php @@ -0,0 +1,37 @@ +appConfig->getValueString('core', 'enforce_strict_email_check', 'yes') === 'yes'; + + $validator = new EquliasEmailValidator(); + $validation = $strictMailCheck ? new NoRFCWarningsValidation() : new RFCValidation(); + + return $validator->isValid($email, $validation); + } +} diff --git a/lib/private/Mail/Mailer.php b/lib/private/Mail/Mailer.php index bdc4d6760e068..7791a32e6e5bd 100644 --- a/lib/private/Mail/Mailer.php +++ b/lib/private/Mail/Mailer.php @@ -8,9 +8,6 @@ */ namespace OC\Mail; -use Egulias\EmailValidator\EmailValidator; -use Egulias\EmailValidator\Validation\NoRFCWarningsValidation; -use Egulias\EmailValidator\Validation\RFCValidation; use OCP\Defaults; use OCP\EventDispatcher\IEventDispatcher; use OCP\IBinaryFinder; @@ -21,6 +18,7 @@ use OCP\Mail\Events\BeforeMessageSent; use OCP\Mail\IAttachment; use OCP\Mail\IEMailTemplate; +use OCP\Mail\IEmailValidator; use OCP\Mail\IMailer; use OCP\Mail\IMessage; use Psr\Log\LoggerInterface; @@ -69,6 +67,7 @@ public function __construct( private IL10N $l10n, private IEventDispatcher $dispatcher, private IFactory $l10nFactory, + private IEmailValidator $emailValidator, ) { } @@ -234,18 +233,10 @@ public function send(IMessage $message): array { /** * @param string $email Email address to be validated * @return bool True if the mail address is valid, false otherwise + * @deprecated 26.0.0 use IEmailValidator.isValid instead */ public function validateMailAddress(string $email): bool { - if ($email === '') { - // Shortcut: empty addresses are never valid - return false; - } - - $strictMailCheck = $this->config->getAppValue('core', 'enforce_strict_email_check', 'yes') === 'yes'; - $validator = new EmailValidator(); - $validation = $strictMailCheck ? new NoRFCWarningsValidation() : new RFCValidation(); - - return $validator->isValid($email, $validation); + return $this->emailValidator->isValid($email); } protected function getInstance(): MailerInterface { diff --git a/lib/private/Server.php b/lib/private/Server.php index 22cd13438b847..b2a7939b2f036 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -77,6 +77,7 @@ use OC\Lockdown\LockdownManager; use OC\Log\LogFactory; use OC\Log\PsrLoggerAdapter; +use OC\Mail\EmailValidator; use OC\Mail\Mailer; use OC\Memcache\ArrayCache; use OC\Memcache\Factory; @@ -195,6 +196,7 @@ use OCP\Lock\ILockingProvider; use OCP\Lockdown\ILockdownManager; use OCP\Log\ILogFactory; +use OCP\Mail\IEmailValidator; use OCP\Mail\IMailer; use OCP\OCM\ICapabilityAwareOCMProvider; use OCP\OCM\IOCMDiscoveryService; @@ -916,6 +918,9 @@ public function __construct($webRoot, \OC\Config $config) { ); }); + /** @since 32.0.0 */ + $this->registerAlias(IEmailValidator::class, EmailValidator::class); + $this->registerService(IMailer::class, function (Server $c) { return new Mailer( $c->get(\OCP\IConfig::class), @@ -924,7 +929,8 @@ public function __construct($webRoot, \OC\Config $config) { $c->get(IURLGenerator::class), $c->getL10N('lib'), $c->get(IEventDispatcher::class), - $c->get(IFactory::class) + $c->get(IFactory::class), + $c->get(IEmailValidator::class), ); }); diff --git a/lib/public/Mail/IEmailValidator.php b/lib/public/Mail/IEmailValidator.php new file mode 100644 index 0000000000000..403148c1fd702 --- /dev/null +++ b/lib/public/Mail/IEmailValidator.php @@ -0,0 +1,24 @@ +appConfig = $this->createMock(IAppConfig::class); + $this->emailValidator = new EmailValidator($this->appConfig); + } + + public static function mailAddressProvider(): array { + return [ + ['lukas@nextcloud.com', true, false], + ['lukas@localhost', true, false], + ['lukas@192.168.1.1', true, false], + ['lukas@éxämplè.com', true, false], + ['asdf', false, false], + ['', false, false], + ['lukas@nextcloud.org@nextcloud.com', false, false], + ['test@localhost', true, false], + ['test@localhost', false, true], + ]; + } + + #[DataProvider('mailAddressProvider')] + public function testIsValid($email, $expected, $strict): void { + $this->appConfig + ->expects($this->atMost(1)) + ->method('getValueString') + ->with('core', 'enforce_strict_email_check', 'yes') + ->willReturn($strict ? 'yes' : 'no'); + $this->assertSame($expected, $this->emailValidator->isValid($email)); + } +} diff --git a/tests/lib/Mail/MailerTest.php b/tests/lib/Mail/MailerTest.php index 7b911e5c4e2d1..8ed0386ff7d5d 100644 --- a/tests/lib/Mail/MailerTest.php +++ b/tests/lib/Mail/MailerTest.php @@ -19,6 +19,7 @@ use OCP\IURLGenerator; use OCP\L10N\IFactory; use OCP\Mail\Events\BeforeMessageSent; +use OCP\Mail\IEmailValidator; use OCP\Server; use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; @@ -61,7 +62,8 @@ protected function setUp(): void { $this->urlGenerator, $this->l10n, $this->dispatcher, - $this->createMock(IFactory::class) + $this->createMock(IFactory::class), + $this->createMock(IEmailValidator::class), ); } @@ -181,7 +183,8 @@ public function testEvents(): void { $this->urlGenerator, $this->l10n, $this->dispatcher, - $this->createMock(IFactory::class) + $this->createMock(IFactory::class), + $this->createMock(IEmailValidator::class), ] ) ->getMock(); @@ -226,33 +229,6 @@ public function testSendInvalidMailException(): void { $this->mailer->send($message); } - /** - * @return array - */ - public static function mailAddressProvider(): array { - return [ - ['lukas@owncloud.com', true, false], - ['lukas@localhost', true, false], - ['lukas@192.168.1.1', true, false], - ['lukas@éxämplè.com', true, false], - ['asdf', false, false], - ['', false, false], - ['lukas@owncloud.org@owncloud.com', false, false], - ['test@localhost', true, false], - ['test@localhost', false, true], - ]; - } - - #[\PHPUnit\Framework\Attributes\DataProvider('mailAddressProvider')] - public function testValidateMailAddress($email, $expected, $strict): void { - $this->config - ->expects($this->atMost(1)) - ->method('getAppValue') - ->with('core', 'enforce_strict_email_check') - ->willReturn($strict ? 'yes' : 'no'); - $this->assertSame($expected, $this->mailer->validateMailAddress($email)); - } - public function testCreateEMailTemplate(): void { $this->config->method('getSystemValueString') ->with('mail_template_class', '') diff --git a/tests/lib/Traits/EmailValidatorTrait.php b/tests/lib/Traits/EmailValidatorTrait.php new file mode 100644 index 0000000000000..38014854122aa --- /dev/null +++ b/tests/lib/Traits/EmailValidatorTrait.php @@ -0,0 +1,30 @@ +createMock(IAppConfig::class); + $appConfig->method('getValueString') + ->with('core', 'enforce_strict_email_check', 'yes') + ->willReturn('yes'); + + return new EmailValidator($appConfig); + } +}