diff --git a/apps/dav/lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php b/apps/dav/lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php index 0fd39a9e45970..6ac8bf28877c2 100644 --- a/apps/dav/lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php +++ b/apps/dav/lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php @@ -16,6 +16,7 @@ use OCP\L10N\IFactory as L10NFactory; use OCP\Mail\Headers\AutoSubmitted; use OCP\Mail\IEMailTemplate; +use OCP\Mail\IEmailValidator; use OCP\Mail\IMailer; use OCP\Util; use Psr\Log\LoggerInterface; @@ -39,6 +40,7 @@ public function __construct( LoggerInterface $logger, L10NFactory $l10nFactory, IURLGenerator $urlGenerator, + private IEmailValidator $emailValidator, ) { parent::__construct($logger, $l10nFactory, $urlGenerator, $config); } @@ -96,7 +98,7 @@ public function send(VEvent $vevent, $template->addFooter(); foreach ($emailAddresses as $emailAddress) { - if (!$this->mailer->validateMailAddress($emailAddress)) { + if (!$this->emailValidator->isValid($emailAddress)) { $this->logger->error('Email address {address} for reminder notification is incorrect', ['app' => 'dav', 'address' => $emailAddress]); continue; } @@ -180,7 +182,7 @@ private function getOrganizerEMailAndNameFromEvent(VEvent $vevent):?array { $organizerEMail = substr($organizer->getValue(), 7); - if (!$this->mailer->validateMailAddress($organizerEMail)) { + if (!$this->emailValidator->isValid($organizerEMail)) { return null; } @@ -251,7 +253,7 @@ private function getAllEMailAddressesFromEvent(VEvent $vevent):array { foreach ($emailAddressesOfDelegates as $addressesOfDelegate) { if (strcasecmp($addressesOfDelegate, 'mailto:') === 0) { $delegateEmail = substr($addressesOfDelegate, 7); - if ($this->mailer->validateMailAddress($delegateEmail)) { + if ($this->emailValidator->isValid($delegateEmail)) { $emailAddresses[$delegateEmail] = []; } } @@ -311,7 +313,7 @@ private function getEMailAddressOfAttendee(VObject\Property $attendee): ?string return null; } $attendeeEMail = substr($attendee->getValue(), 7); - if (!$this->mailer->validateMailAddress($attendeeEMail)) { + if (!$this->emailValidator->isValid($attendeeEMail)) { return null; } diff --git a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php index 2af6b162d8dc2..ffb16b4ef90d4 100644 --- a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php +++ b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php @@ -14,6 +14,7 @@ use OCP\Defaults; use OCP\IAppConfig; use OCP\IUserSession; +use OCP\Mail\IEmailValidator; use OCP\Mail\IMailer; use OCP\Mail\Provider\Address; use OCP\Mail\Provider\Attachment; @@ -63,6 +64,7 @@ public function __construct( private IMipService $imipService, private EventComparisonService $eventComparisonService, private IMailManager $mailManager, + private IEmailValidator $emailValidator, ) { parent::__construct(''); } @@ -119,7 +121,7 @@ public function schedule(Message $iTipMessage) { // Strip off mailto: $recipient = substr($iTipMessage->recipient, 7); - if (!$this->mailer->validateMailAddress($recipient)) { + if (!$this->emailValidator->isValid($recipient)) { // Nothing to send if the recipient doesn't have a valid email address $iTipMessage->scheduleStatus = '5.0; EMail delivery failed'; return; diff --git a/apps/dav/lib/Listener/CalendarContactInteractionListener.php b/apps/dav/lib/Listener/CalendarContactInteractionListener.php index a7f00e452c47d..d14af77ac5230 100644 --- a/apps/dav/lib/Listener/CalendarContactInteractionListener.php +++ b/apps/dav/lib/Listener/CalendarContactInteractionListener.php @@ -18,7 +18,7 @@ use OCP\EventDispatcher\IEventListener; use OCP\IUser; use OCP\IUserSession; -use OCP\Mail\IMailer; +use OCP\Mail\IEmailValidator; use Psr\Log\LoggerInterface; use Sabre\VObject\Component\VEvent; use Sabre\VObject\Parameter; @@ -36,7 +36,7 @@ public function __construct( private IEventDispatcher $dispatcher, private IUserSession $userSession, private Principal $principalConnector, - private IMailer $mailer, + private IEmailValidator $emailValidator, private LoggerInterface $logger, ) { } @@ -129,7 +129,7 @@ private function emitFromObject(VEvent $vevent, IUser $user): void { continue; } $email = substr($mailTo, strlen('mailto:')); - if (!$this->mailer->validateMailAddress($email)) { + if (!$this->emailValidator->isValid($email)) { // This really isn't a valid email continue; } diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index d2bd3e6077b3a..9e9434844652b 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -350,7 +350,8 @@ public function __construct( $userSession, \OCP\Server::get(IMipService::class), \OCP\Server::get(EventComparisonService::class), - \OCP\Server::get(\OCP\Mail\Provider\IManager::class) + \OCP\Server::get(\OCP\Mail\Provider\IManager::class), + \OCP\Server::get(\OCP\Mail\IEmailValidator::class), )); } $this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin()); diff --git a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/EmailProviderTest.php b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/EmailProviderTest.php index f7fbac2c4073e..d9978a76fd839 100644 --- a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/EmailProviderTest.php +++ b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/EmailProviderTest.php @@ -17,8 +17,10 @@ use OCP\Util; use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\Component\VCalendar; +use Test\Traits\EmailValidatorTrait; class EmailProviderTest extends AbstractNotificationProviderTestCase { + use EmailValidatorTrait; public const USER_EMAIL = 'frodo@hobb.it'; private IMailer&MockObject $mailer; @@ -32,7 +34,8 @@ protected function setUp(): void { $this->mailer, $this->logger, $this->l10nFactory, - $this->urlGenerator + $this->urlGenerator, + $this->getEmailValidatorWithStrictEmailCheck(), ); } @@ -93,15 +96,6 @@ public function testSendWithoutAttendees():void { $template2 ); - $this->mailer->expects($this->exactly(4)) - ->method('validateMailAddress') - ->willReturnMap([ - ['uid1@example.com', true], - ['uid2@example.com', true], - ['uid3@example.com', true], - ['invalid', false], - ]); - $this->mailer->expects($this->exactly(3)) ->method('createMessage') ->with() @@ -189,17 +183,6 @@ public function testSendWithAttendeesWhenOwnerIsOrganizer(): void { $template1, $template2, ); - $this->mailer->expects($this->atLeastOnce()) - ->method('validateMailAddress') - ->willReturnMap([ - ['foo1@example.org', true], - ['foo3@example.org', true], - ['foo4@example.org', true], - ['uid1@example.com', true], - ['uid2@example.com', true], - ['uid3@example.com', true], - ['invalid', false], - ]); $this->mailer->expects($this->exactly(6)) ->method('createMessage') ->with() @@ -277,17 +260,6 @@ public function testSendWithAttendeesWhenOwnerIsAttendee(): void { ->willReturnOnConsecutiveCalls( $template1, ); - $this->mailer->expects($this->atLeastOnce()) - ->method('validateMailAddress') - ->willReturnMap([ - ['foo1@example.org', true], - ['foo3@example.org', true], - ['foo4@example.org', true], - ['uid1@example.com', true], - ['uid2@example.com', true], - ['uid3@example.com', true], - ['invalid', false], - ]); $this->mailer->expects($this->exactly(2)) ->method('createMessage') ->with() diff --git a/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginCharsetTest.php b/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginCharsetTest.php index fa52d5319c9b3..b228adea9b59c 100644 --- a/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginCharsetTest.php +++ b/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginCharsetTest.php @@ -38,8 +38,10 @@ use Sabre\VObject\Property\ICalendar\CalAddress; use Symfony\Component\Mime\Email; use Test\TestCase; +use Test\Traits\EmailValidatorTrait; class IMipPluginCharsetTest extends TestCase { + use EmailValidatorTrait; // Dependencies private Defaults&MockObject $defaults; private IAppConfig&MockObject $appConfig; @@ -102,8 +104,6 @@ protected function setUp(): void { $this->mailer = $this->createMock(IMailer::class); $this->mailer->method('createMessage') ->willReturn($message); - $this->mailer->method('validateMailAddress') - ->willReturn(true); $this->logger = new NullLogger(); $this->defaults = $this->createMock(Defaults::class); $this->defaults->method('getName') @@ -125,6 +125,7 @@ protected function setUp(): void { $this->imipService, $this->eventComparisonService, $this->mailManager, + $this->getEmailValidatorWithStrictEmailCheck(), ); // ITipMessage diff --git a/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php b/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php index 8e71bfa6edffc..e7dca1372741a 100644 --- a/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php +++ b/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php @@ -30,6 +30,7 @@ use Sabre\VObject\Component\VEvent; use Sabre\VObject\ITip\Message; use Test\TestCase; +use Test\Traits\EmailValidatorTrait; use function array_merge; interface IMailServiceMock extends IMailService, IMailMessageSend { @@ -38,6 +39,8 @@ interface IMailServiceMock extends IMailService, IMailMessageSend { } class IMipPluginTest extends TestCase { + use EmailValidatorTrait; + private IMessage&MockObject $mailMessage; private IMailer&MockObject $mailer; private IEMailTemplate&MockObject $emailTemplate; @@ -107,6 +110,7 @@ protected function setUp(): void { $this->service, $this->eventComparisonService, $this->mailManager, + $this->getEmailValidatorWithStrictEmailCheck(), ); } @@ -173,10 +177,6 @@ public function testParsingSingle(): void { $this->service->expects(self::once()) ->method('getLastOccurrence') ->willReturn(1496912700); - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('frodo@hobb.it') - ->willReturn(true); $this->eventComparisonService->expects(self::once()) ->method('findModified') ->willReturn(['new' => [$newVevent], 'old' => [$oldVEvent]]); @@ -280,10 +280,6 @@ public function testAttendeeIsResource(): void { $this->service->expects(self::once()) ->method('getLastOccurrence') ->willReturn(1496912700); - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('the-shire@hobb.it') - ->willReturn(true); $this->eventComparisonService->expects(self::once()) ->method('findModified') ->willReturn(['new' => [$newVevent], 'old' => [$oldVEvent]]); @@ -358,10 +354,6 @@ public function testAttendeeIsCircle(): void { $this->service->expects(self::once()) ->method('getLastOccurrence') ->willReturn(1496912700); - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('circle+82utEV1Fle8wvxndZLK5TVAPtxj8IIe@middle.earth') - ->willReturn(true); $this->eventComparisonService->expects(self::once()) ->method('findModified') ->willReturn(['new' => [$newVevent], 'old' => null]); @@ -463,10 +455,6 @@ public function testParsingRecurrence(): void { $this->service->expects(self::once()) ->method('getLastOccurrence') ->willReturn(1496912700); - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('frodo@hobb.it') - ->willReturn(true); $this->eventComparisonService->expects(self::once()) ->method('findModified') ->willReturn(['old' => [] ,'new' => [$newVevent]]); @@ -541,15 +529,11 @@ public function testEmailValidationFailed(): void { $message->message->VEVENT->add('ATTENDEE', 'mailto:' . 'frodo@hobb.it', ['RSVP' => 'TRUE']); $message->sender = 'mailto:gandalf@wiz.ard'; $message->senderName = 'Mr. Wizard'; - $message->recipient = 'mailto:' . 'frodo@hobb.it'; + $message->recipient = 'mailto:' . 'frodo@@hobb.it'; $this->service->expects(self::once()) ->method('getLastOccurrence') ->willReturn(1496912700); - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('frodo@hobb.it') - ->willReturn(false); $this->plugin->schedule($message); $this->assertEquals('5.0', $message->getScheduleStatus()); @@ -598,10 +582,6 @@ public function testFailedDelivery(): void { $this->service->expects(self::once()) ->method('getLastOccurrence') ->willReturn(1496912700); - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('frodo@hobb.it') - ->willReturn(true); $this->eventComparisonService->expects(self::once()) ->method('findModified') ->willReturn(['old' => [] ,'new' => [$newVevent]]); @@ -755,11 +735,6 @@ public function testMailProviderSend(): void { $this->eventComparisonService->expects(self::once()) ->method('findModified') ->willReturn(['old' => [] ,'new' => [$event]]); - // construct mail mock returns - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('frodo@hobb.it') - ->willReturn(true); // construct mail provider mock returns $this->mailService ->method('initiateMessage') @@ -819,10 +794,6 @@ public function testMailProviderDisabled(): void { $this->service->expects(self::once()) ->method('getLastOccurrence') ->willReturn(1496912700); - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('frodo@hobb.it') - ->willReturn(true); $this->eventComparisonService->expects(self::once()) ->method('findModified') ->willReturn(['new' => [$newVevent], 'old' => [$oldVEvent]]); @@ -917,10 +888,6 @@ public function testNoOldEvent(): void { $this->service->expects(self::once()) ->method('getLastOccurrence') ->willReturn(1496912700); - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('frodo@hobb.it') - ->willReturn(true); $this->eventComparisonService->expects(self::once()) ->method('findModified') ->with($newVCalendar, null) @@ -1014,10 +981,6 @@ public function testNoButtons(): void { $this->service->expects(self::once()) ->method('getLastOccurrence') ->willReturn(1496912700); - $this->mailer->expects(self::once()) - ->method('validateMailAddress') - ->with('frodo@hobb.it') - ->willReturn(true); $this->eventComparisonService->expects(self::once()) ->method('findModified') ->with($newVCalendar, null) diff --git a/apps/dav/tests/unit/Listener/CalendarContactInteractionListenerTest.php b/apps/dav/tests/unit/Listener/CalendarContactInteractionListenerTest.php index dc3dce8a62fc7..0ee641006a219 100644 --- a/apps/dav/tests/unit/Listener/CalendarContactInteractionListenerTest.php +++ b/apps/dav/tests/unit/Listener/CalendarContactInteractionListenerTest.php @@ -17,17 +17,18 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\IUser; use OCP\IUserSession; -use OCP\Mail\IMailer; use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; +use Test\Traits\EmailValidatorTrait; class CalendarContactInteractionListenerTest extends TestCase { + use EmailValidatorTrait; + private IEventDispatcher&MockObject $eventDispatcher; private IUserSession&MockObject $userSession; private Principal&MockObject $principalConnector; private LoggerInterface&MockObject $logger; - private IMailer&MockObject $mailer; private CalendarContactInteractionListener $listener; protected function setUp(): void { @@ -36,14 +37,13 @@ protected function setUp(): void { $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->userSession = $this->createMock(IUserSession::class); $this->principalConnector = $this->createMock(Principal::class); - $this->mailer = $this->createMock(IMailer::class); $this->logger = $this->createMock(LoggerInterface::class); $this->listener = new CalendarContactInteractionListener( $this->eventDispatcher, $this->userSession, $this->principalConnector, - $this->mailer, + $this->getEmailValidatorWithStrictEmailCheck(), $this->logger ); } @@ -162,7 +162,6 @@ public function testParseCalendarEvent(): void { EVENT]); $user = $this->createMock(IUser::class); $this->userSession->expects(self::once())->method('getUser')->willReturn($user); - $this->mailer->expects(self::once())->method('validateMailAddress')->willReturn(true); $this->eventDispatcher->expects(self::once()) ->method('dispatchTyped') ->with(self::equalTo((new ContactInteractedWithEvent($user))->setEmail('user@domain.tld'))); diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index 8ba50d54d3fce..1520ef2e61ff6 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -55,6 +55,7 @@ use OCP\IUserManager; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; +use OCP\Mail\IEmailValidator; use OCP\Mail\IMailer; use OCP\Server; use OCP\Share\Exceptions\GenericShareException; @@ -102,6 +103,7 @@ public function __construct( private IProviderFactory $factory, private IMailer $mailer, private ITagManager $tagManager, + private IEmailValidator $emailValidator, private ?TrustedServers $trustedServers, private ?string $userId = null, ) { @@ -746,7 +748,7 @@ public function createShare( // Only share by mail have a recipient if (is_string($shareWith) && $shareType === IShare::TYPE_EMAIL) { // If sending a mail have been requested, validate the mail address - if ($share->getMailSend() && !$this->mailer->validateMailAddress($shareWith)) { + if ($share->getMailSend() && !$this->emailValidator->isValid($shareWith)) { throw new OCSNotFoundException($this->l->t('Please specify a valid email address')); } $share->setSharedWith($shareWith); diff --git a/apps/files_sharing/tests/ApiTest.php b/apps/files_sharing/tests/ApiTest.php index abb72793bc0c9..759e2011c2512 100644 --- a/apps/files_sharing/tests/ApiTest.php +++ b/apps/files_sharing/tests/ApiTest.php @@ -41,6 +41,7 @@ use PHPUnit\Framework\MockObject\MockObject; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; +use Test\Traits\EmailValidatorTrait; /** * Class ApiTest @@ -49,6 +50,8 @@ * TODO: convert to real integration tests */ class ApiTest extends TestCase { + use EmailValidatorTrait; + public const TEST_FOLDER_NAME = '/folder_share_api_test'; public const APP_NAME = 'files_sharing'; @@ -141,6 +144,7 @@ private function createOCS($userId) { $providerFactory, $mailer, $tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $trustedServers, $userId, ); diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php index 7286299df00f0..93ce63c10209b 100644 --- a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php @@ -54,6 +54,7 @@ use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; use Test\TestCase; +use Test\Traits\EmailValidatorTrait; /** * Class ShareAPIControllerTest @@ -62,6 +63,7 @@ * @group DB */ class ShareAPIControllerTest extends TestCase { + use EmailValidatorTrait; private string $appName = 'files_sharing'; private string $currentUser; @@ -146,8 +148,9 @@ protected function setUp(): void { $this->factory, $this->mailer, $this->tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $this->trustedServers, - $this->currentUser + $this->currentUser, ); } @@ -177,6 +180,7 @@ private function mockFormatShare() { $this->factory, $this->mailer, $this->tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $this->trustedServers, $this->currentUser, ])->onlyMethods(['formatShare']) @@ -889,6 +893,7 @@ public function testGetShare(array $shareParams, array $result, bool $attributes $this->factory, $this->mailer, $this->tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $this->trustedServers, $this->currentUser, ]) @@ -1603,6 +1608,7 @@ function (array $shareParams): IShare { $this->factory, $this->mailer, $this->tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $this->trustedServers, $this->currentUser, ]) @@ -1976,6 +1982,7 @@ public function testCreateShareUser(): void { $this->factory, $this->mailer, $this->tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $this->trustedServers, $this->currentUser, ])->onlyMethods(['formatShare']) @@ -2076,6 +2083,7 @@ public function testCreateShareGroup(): void { $this->factory, $this->mailer, $this->tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $this->trustedServers, $this->currentUser, ])->onlyMethods(['formatShare']) @@ -2504,6 +2512,7 @@ public function testCreateShareRemote(): void { $this->factory, $this->mailer, $this->tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $this->trustedServers, $this->currentUser, ])->onlyMethods(['formatShare']) @@ -2577,6 +2586,7 @@ public function testCreateShareRemoteGroup(): void { $this->factory, $this->mailer, $this->tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $this->trustedServers, $this->currentUser, ])->onlyMethods(['formatShare']) @@ -2817,6 +2827,7 @@ public function testCreateReshareOfFederatedMountNoDeletePermissions(): void { $this->factory, $this->mailer, $this->tagManager, + $this->getEmailValidatorWithStrictEmailCheck(), $this->trustedServers, $this->currentUser, ])->onlyMethods(['formatShare']) diff --git a/apps/sharebymail/lib/ShareByMailProvider.php b/apps/sharebymail/lib/ShareByMailProvider.php index d28f7c51327a9..c443459a7127b 100644 --- a/apps/sharebymail/lib/ShareByMailProvider.php +++ b/apps/sharebymail/lib/ShareByMailProvider.php @@ -25,6 +25,7 @@ use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserManager; +use OCP\Mail\IEmailValidator; use OCP\Mail\IMailer; use OCP\Security\Events\GenerateSecurePasswordEvent; use OCP\Security\IHasher; @@ -70,6 +71,7 @@ public function __construct( private IHasher $hasher, private IEventDispatcher $eventDispatcher, private IShareManager $shareManager, + private IEmailValidator $emailValidator, ) { } @@ -246,7 +248,7 @@ public function sendMailNotification(IShare $share): bool { $emails = $this->getSharedWithEmails($share); $validEmails = array_filter($emails, function (string $email) { - return $this->mailer->validateMailAddress($email); + return $this->emailValidator->isValid($email); }); if (count($validEmails) === 0) { @@ -722,7 +724,7 @@ public function update(IShare $share, ?string $plainTextPassword = null): IShare || ($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) { $emails = $this->getSharedWithEmails($share); $validEmails = array_filter($emails, function ($email) { - return $this->mailer->validateMailAddress($email); + return $this->emailValidator->isValid($email); }); $this->sendPassword($share, $plainTextPassword, $validEmails); } diff --git a/apps/sharebymail/tests/ShareByMailProviderTest.php b/apps/sharebymail/tests/ShareByMailProviderTest.php index 8f70516f12cc5..9a5116fb29c9f 100644 --- a/apps/sharebymail/tests/ShareByMailProviderTest.php +++ b/apps/sharebymail/tests/ShareByMailProviderTest.php @@ -41,6 +41,7 @@ use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; +use Test\Traits\EmailValidatorTrait; /** * Class ShareByMailProviderTest @@ -49,6 +50,7 @@ * @group DB */ class ShareByMailProviderTest extends TestCase { + use EmailValidatorTrait; private IDBConnection $connection; @@ -122,6 +124,7 @@ private function getInstance(array $mockedMethods = []) { $this->hasher, $this->eventDispatcher, $this->shareManager, + $this->getEmailValidatorWithStrictEmailCheck(), ]) ->onlyMethods($mockedMethods) ->getMock(); @@ -143,6 +146,7 @@ private function getInstance(array $mockedMethods = []) { $this->hasher, $this->eventDispatcher, $this->shareManager, + $this->getEmailValidatorWithStrictEmailCheck(), ); } @@ -199,9 +203,6 @@ public function testCreateSendPasswordByMailWithoutEnforcedPasswordProtection(): $share->expects($this->any())->method('getNote')->willReturn(''); $share->expects($this->any())->method('getToken')->willReturn('token'); - // Assume the mail address is valid. - $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42); @@ -241,9 +242,6 @@ public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswo $share->expects($this->any())->method('getNote')->willReturn(''); $share->expects($this->any())->method('getToken')->willReturn('token'); - // Assume the mail address is valid. - $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); @@ -287,9 +285,6 @@ public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswo $share->expects($this->any())->method('getNote')->willReturn(''); $share->expects($this->any())->method('getToken')->willReturn('token'); - // Assume the mail address is valid. - $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance([ 'getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', @@ -352,9 +347,6 @@ public function testCreateSendPasswordByMailWithEnforcedPasswordProtectionWithPe ->method('dispatchTyped') ->with(new GenerateSecurePasswordEvent(PasswordContext::SHARING)); - // Assume the mail address is valid. - $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'createPasswordSendActivity', 'sendPasswordToOwner']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); @@ -435,9 +427,6 @@ public function testCreateSendPasswordByMailWithPasswordAndWithEnforcedPasswordP ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) ->willReturn('https://example.com/file.txt'); - // Assume the mail address is valid. - $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendPasswordToOwner']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); @@ -526,9 +515,6 @@ public function testCreateSendPasswordByTalkWithEnforcedPasswordProtectionWithPe ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) ->willReturn('https://example.com/file.txt'); - // Assume the mail address is valid. - $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); @@ -624,9 +610,6 @@ public function sendNotificationToMultipleEmails() { 'receiver3@example.com', ]); - // Assume the mail address is valid. - $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); @@ -1188,7 +1171,6 @@ public function testGetSharesInFolder(): void { ->willReturn(new Share($rootFolder, $userManager)); $provider = $this->getInstance(['sendMailNotification', 'createShareActivity']); - $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); $u1 = $userManager->createUser('testFed', md5((string)time())); $u2 = $userManager->createUser('testFed2', md5((string)time())); @@ -1235,7 +1217,6 @@ public function testGetAccessList(): void { ->willReturn(new Share($rootFolder, $userManager)); $provider = $this->getInstance(['sendMailNotification', 'createShareActivity']); - $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); $u1 = $userManager->createUser('testFed', md5((string)time())); $u2 = $userManager->createUser('testFed2', md5((string)time())); @@ -1370,9 +1351,6 @@ public function testSendMailNotificationWithSameUserAndUserEmail(): void { ->method('useTemplate') ->with($template); - $this->mailer->expects($this->once()) - ->method('validateMailAddress') - ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') @@ -1492,9 +1470,6 @@ public function testSendMailNotificationWithSameUserAndUserEmailAndNote(): void ->method('useTemplate') ->with($template); - $this->mailer->expects($this->once()) - ->method('validateMailAddress') - ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') @@ -1619,9 +1594,6 @@ public function testSendMailNotificationWithSameUserAndUserEmailAndExpiration(): ->method('useTemplate') ->with($template); - $this->mailer->expects($this->once()) - ->method('validateMailAddress') - ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') @@ -1717,9 +1689,6 @@ public function testSendMailNotificationWithDifferentUserAndNoUserEmail(): void ->method('useTemplate') ->with($template); - $this->mailer->expects($this->once()) - ->method('validateMailAddress') - ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') @@ -1818,9 +1787,6 @@ public function testSendMailNotificationWithSameUserAndUserEmailAndReplyToDesact ->method('useTemplate') ->with($template); - $this->mailer->expects($this->once()) - ->method('validateMailAddress') - ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') @@ -1915,9 +1881,6 @@ public function testSendMailNotificationWithDifferentUserAndNoUserEmailAndReplyT ->method('useTemplate') ->with($template); - $this->mailer->expects($this->once()) - ->method('validateMailAddress') - ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index df8b4d89e8bec..3e39a93fc527c 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -356,12 +356,6 @@ - - - - - - @@ -431,9 +425,6 @@ - - - recipientName]]> @@ -841,11 +832,6 @@ - - - - - @@ -1458,7 +1444,6 @@ - @@ -2061,10 +2046,6 @@ - - - - getId()]]> @@ -2822,11 +2803,6 @@ - - - - - @@ -3755,7 +3731,6 @@ - diff --git a/core/Command/User/Add.php b/core/Command/User/Add.php index 4de4e247991b1..440bced4c2e37 100644 --- a/core/Command/User/Add.php +++ b/core/Command/User/Add.php @@ -15,7 +15,7 @@ use OCP\IGroupManager; use OCP\IUser; use OCP\IUserManager; -use OCP\Mail\IMailer; +use OCP\Mail\IEmailValidator; use OCP\Security\Events\GenerateSecurePasswordEvent; use OCP\Security\ISecureRandom; use Symfony\Component\Console\Command\Command; @@ -30,7 +30,7 @@ class Add extends Command { public function __construct( protected IUserManager $userManager, protected IGroupManager $groupManager, - protected IMailer $mailer, + private IEmailValidator $emailValidator, private IAppConfig $appConfig, private NewUserMailHelper $mailHelper, private IEventDispatcher $eventDispatcher, @@ -169,7 +169,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $email = $input->getOption('email'); if (!empty($email)) { - if (!$this->mailer->validateMailAddress($email)) { + if (!$this->emailValidator->isValid($email)) { $output->writeln(\sprintf( 'The given email address "%s" is invalid. Email not set for the user.', $email, diff --git a/lib/private/Collaboration/Collaborators/MailPlugin.php b/lib/private/Collaboration/Collaborators/MailPlugin.php index 55e3945ace2f0..889e5ec7bfb09 100644 --- a/lib/private/Collaboration/Collaborators/MailPlugin.php +++ b/lib/private/Collaboration/Collaborators/MailPlugin.php @@ -17,7 +17,7 @@ use OCP\IGroupManager; use OCP\IUser; use OCP\IUserSession; -use OCP\Mail\IMailer; +use OCP\Mail\IEmailValidator; use OCP\Share\IShare; class MailPlugin implements ISearchPlugin { @@ -40,7 +40,7 @@ public function __construct( private IGroupManager $groupManager, private KnownUserService $knownUserService, private IUserSession $userSession, - private IMailer $mailer, + private IEmailValidator $emailValidator, private mixed $shareWithGroupOnlyExcludeGroupsList = [], ) { $this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes'; @@ -236,7 +236,7 @@ public function search($search, $limit, $offset, ISearchResult $searchResult): b $userResults['wide'] = array_slice($userResults['wide'], $offset, $limit); } - if (!$searchResult->hasExactIdMatch($emailType) && $this->mailer->validateMailAddress($search)) { + if (!$searchResult->hasExactIdMatch($emailType) && $this->emailValidator->isValid($search)) { $result['exact'][] = [ 'label' => $search, 'uuid' => $search, diff --git a/lib/public/Util.php b/lib/public/Util.php index 2adbf5c2b7f39..70a862880f19d 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -15,7 +15,7 @@ use OC\AppScriptSort; use OC\Security\CSRF\CsrfTokenManager; use OCP\L10N\IFactory; -use OCP\Mail\IMailer; +use OCP\Mail\IEmailValidator; use OCP\Share\IManager; use Psr\Container\ContainerExceptionInterface; @@ -305,8 +305,8 @@ public static function getDefaultEmailAddress(string $user_part): string { $host_name = $config->getSystemValueString('mail_domain', $host_name); $defaultEmailAddress = $user_part . '@' . $host_name; - $mailer = \OCP\Server::get(IMailer::class); - if ($mailer->validateMailAddress($defaultEmailAddress)) { + $emailValidator = \OCP\Server::get(IEmailValidator::class); + if ($emailValidator->isValid($defaultEmailAddress)) { return $defaultEmailAddress; } diff --git a/tests/Core/Command/User/AddTest.php b/tests/Core/Command/User/AddTest.php index 5a8bc3abea1e9..748a9b60ef632 100644 --- a/tests/Core/Command/User/AddTest.php +++ b/tests/Core/Command/User/AddTest.php @@ -22,8 +22,11 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Test\TestCase; +use Test\Traits\EmailValidatorTrait; class AddTest extends TestCase { + use EmailValidatorTrait; + /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ private $userManager; @@ -62,7 +65,6 @@ public function setUp(): void { $this->userManager = static::createMock(IUserManager::class); $this->groupManager = static::createStub(IGroupManager::class); - $this->mailer = static::createMock(IMailer::class); $this->appConfig = static::createMock(IAppConfig::class); $this->mailHelper = static::createMock(NewUserMailHelper::class); $this->eventDispatcher = static::createStub(IEventDispatcher::class); @@ -76,7 +78,7 @@ public function setUp(): void { $this->addCommand = new Add( $this->userManager, $this->groupManager, - $this->mailer, + $this->getEmailValidatorWithStrictEmailCheck(), $this->appConfig, $this->mailHelper, $this->eventDispatcher, @@ -100,9 +102,6 @@ public function testAddEmail( $this->appConfig->method('getValueString') ->willReturn($shouldSendEmail ? 'yes' : 'no'); - $this->mailer->method('validateMailAddress') - ->willReturn($isEmailValid); - $this->mailHelper->method('generateTemplate') ->willReturn(static::createMock(IEMailTemplate::class)); diff --git a/tests/lib/Collaboration/Collaborators/MailPluginTest.php b/tests/lib/Collaboration/Collaborators/MailPluginTest.php index b38b961a5126d..6c81a0d68e227 100644 --- a/tests/lib/Collaboration/Collaborators/MailPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/MailPluginTest.php @@ -22,11 +22,13 @@ use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; -use OCP\Mail\IMailer; use OCP\Share\IShare; use Test\TestCase; +use Test\Traits\EmailValidatorTrait; class MailPluginTest extends TestCase { + use EmailValidatorTrait; + /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ protected $config; @@ -51,9 +53,6 @@ class MailPluginTest extends TestCase { /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ protected $userSession; - /** @var IMailer|\PHPUnit\Framework\MockObject\MockObject */ - protected $mailer; - protected function setUp(): void { parent::setUp(); @@ -62,7 +61,6 @@ protected function setUp(): void { $this->groupManager = $this->createMock(IGroupManager::class); $this->knownUserService = $this->createMock(KnownUserService::class); $this->userSession = $this->createMock(IUserSession::class); - $this->mailer = $this->createMock(IMailer::class); $this->cloudIdManager = new CloudIdManager( $this->createMock(ICacheFactory::class), $this->createMock(IEventDispatcher::class), @@ -82,7 +80,7 @@ public function instantiatePlugin() { $this->groupManager, $this->knownUserService, $this->userSession, - $this->mailer + $this->getEmailValidatorWithStrictEmailCheck(), ); } @@ -115,9 +113,6 @@ function ($appName, $key, $default) use ($shareeEnumeration) { $this->userSession->method('getUser') ->willReturn($currentUser); - $this->mailer->method('validateMailAddress') - ->willReturn($validEmail); - $this->contactsManager->expects($this->any()) ->method('search') ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) { @@ -601,9 +596,6 @@ function ($appName, $key, $default) { ->method('getUID') ->willReturn('currentUser'); - $this->mailer->method('validateMailAddress') - ->willReturn($validEmail); - $this->contactsManager->expects($this->any()) ->method('search') ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) { diff --git a/tests/lib/Share20/ShareByMailProviderTest.php b/tests/lib/Share20/ShareByMailProviderTest.php index bbfdec50ea742..5180f49f2278d 100644 --- a/tests/lib/Share20/ShareByMailProviderTest.php +++ b/tests/lib/Share20/ShareByMailProviderTest.php @@ -29,6 +29,7 @@ use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; +use Test\Traits\EmailValidatorTrait; /** * Class ShareByMailProviderTest @@ -37,6 +38,8 @@ * @group DB */ class ShareByMailProviderTest extends TestCase { + use EmailValidatorTrait; + /** @var IDBConnection */ protected $dbConn; @@ -121,6 +124,7 @@ protected function setUp(): void { $this->hasher, $this->eventDispatcher, $this->shareManager, + $this->getEmailValidatorWithStrictEmailCheck(), ); }