Skip to content

Commit 22e2419

Browse files
authored
Merge pull request #48134 from nextcloud/feat/mail-provider-settings
feat: mail provider settings
2 parents 423f576 + 3e87069 commit 22e2419

File tree

8 files changed

+258
-20
lines changed

8 files changed

+258
-20
lines changed

apps/dav/lib/CalDAV/Schedule/IMipPlugin.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use OCA\DAV\CalDAV\EventComparisonService;
1313
use OCP\AppFramework\Utility\ITimeFactory;
1414
use OCP\Defaults;
15-
use OCP\IConfig;
15+
use OCP\IAppConfig;
1616
use OCP\IUserSession;
1717
use OCP\Mail\IMailer;
1818
use OCP\Mail\Provider\Address;
@@ -45,6 +45,7 @@
4545
* @license http://sabre.io/license/ Modified BSD License
4646
*/
4747
class IMipPlugin extends SabreIMipPlugin {
48+
4849
private ?VCalendar $vCalendar = null;
4950
public const MAX_DATE = '2038-01-01';
5051
public const METHOD_REQUEST = 'request';
@@ -53,7 +54,7 @@ class IMipPlugin extends SabreIMipPlugin {
5354
public const IMIP_INDENT = 15;
5455

5556
public function __construct(
56-
private IConfig $config,
57+
private IAppConfig $config,
5758
private IMailer $mailer,
5859
private LoggerInterface $logger,
5960
private ITimeFactory $timeFactory,
@@ -240,7 +241,7 @@ public function schedule(Message $iTipMessage) {
240241
*/
241242

242243
$recipientDomain = substr(strrchr($recipient, '@'), 1);
243-
$invitationLinkRecipients = explode(',', preg_replace('/\s+/', '', strtolower($this->config->getAppValue('dav', 'invitation_link_recipients', 'yes'))));
244+
$invitationLinkRecipients = explode(',', preg_replace('/\s+/', '', strtolower($this->config->getValueString('dav', 'invitation_link_recipients', 'yes'))));
244245

245246
if (strcmp('yes', $invitationLinkRecipients[0]) === 0
246247
|| in_array(strtolower($recipient), $invitationLinkRecipients)
@@ -259,12 +260,13 @@ public function schedule(Message $iTipMessage) {
259260
$mailService = null;
260261

261262
try {
262-
// retrieve user object
263-
$user = $this->userSession->getUser();
264-
// evaluate if user object exist
265-
if ($user !== null) {
266-
// retrieve appropriate service with the same address as sender
267-
$mailService = $this->mailManager->findServiceByAddress($user->getUID(), $sender);
263+
if ($this->config->getValueBool('core', 'mail_providers_enabled', true)) {
264+
// retrieve user object
265+
$user = $this->userSession->getUser();
266+
if ($user !== null) {
267+
// retrieve appropriate service with the same address as sender
268+
$mailService = $this->mailManager->findServiceByAddress($user->getUID(), $sender);
269+
}
268270
}
269271
// evaluate if a mail service was found and has sending capabilities
270272
if ($mailService !== null && $mailService instanceof IMessageSend) {

apps/dav/lib/Server.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
use OCP\EventDispatcher\IEventDispatcher;
7171
use OCP\Files\IFilenameValidator;
7272
use OCP\FilesMetadata\IFilesMetadataManager;
73+
use OCP\IAppConfig;
7374
use OCP\ICacheFactory;
7475
use OCP\IConfig;
7576
use OCP\IPreview;
@@ -311,7 +312,7 @@ public function __construct(
311312
));
312313
if (\OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
313314
$this->server->addPlugin(new IMipPlugin(
314-
\OC::$server->get(IConfig::class),
315+
\OC::$server->get(IAppConfig::class),
315316
\OC::$server->get(IMailer::class),
316317
\OC::$server->get(LoggerInterface::class),
317318
\OC::$server->get(ITimeFactory::class),

apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php

Lines changed: 117 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use OCA\DAV\CalDAV\Schedule\IMipService;
1212
use OCP\AppFramework\Utility\ITimeFactory;
1313
use OCP\Defaults;
14-
use OCP\IConfig;
14+
use OCP\IAppConfig;
1515
use OCP\IUser;
1616
use OCP\IUserSession;
1717
use OCP\Mail\IAttachment;
@@ -52,7 +52,7 @@ class IMipPluginTest extends TestCase {
5252
/** @var ITimeFactory|MockObject */
5353
private $timeFactory;
5454

55-
/** @var IConfig|MockObject */
55+
/** @var IAppConfig|MockObject */
5656
private $config;
5757

5858
/** @var IUserSession|MockObject */
@@ -105,7 +105,7 @@ protected function setUp(): void {
105105
$this->timeFactory = $this->createMock(ITimeFactory::class);
106106
$this->timeFactory->method('getTime')->willReturn(1496912528); // 2017-01-01
107107

108-
$this->config = $this->createMock(IConfig::class);
108+
$this->config = $this->createMock(IAppConfig::class);
109109

110110
$this->user = $this->createMock(IUser::class);
111111

@@ -243,7 +243,7 @@ public function testParsingSingle(): void {
243243
->method('getAttendeeRsvpOrReqForParticipant')
244244
->willReturn(true);
245245
$this->config->expects(self::once())
246-
->method('getAppValue')
246+
->method('getValueString')
247247
->with('dav', 'invitation_link_recipients', 'yes')
248248
->willReturn('yes');
249249
$this->service->expects(self::once())
@@ -341,7 +341,7 @@ public function testAttendeeIsResource(): void {
341341
$this->service->expects(self::never())
342342
->method('getAttendeeRsvpOrReqForParticipant');
343343
$this->config->expects(self::never())
344-
->method('getAppValue');
344+
->method('getValueString');
345345
$this->service->expects(self::never())
346346
->method('createInvitationToken');
347347
$this->service->expects(self::never())
@@ -447,7 +447,7 @@ public function testParsingRecurrence(): void {
447447
->method('getAttendeeRsvpOrReqForParticipant')
448448
->willReturn(true);
449449
$this->config->expects(self::once())
450-
->method('getAppValue')
450+
->method('getValueString')
451451
->with('dav', 'invitation_link_recipients', 'yes')
452452
->willReturn('yes');
453453
$this->service->expects(self::once())
@@ -578,7 +578,7 @@ public function testFailedDelivery(): void {
578578
->method('getAttendeeRsvpOrReqForParticipant')
579579
->willReturn(true);
580580
$this->config->expects(self::once())
581-
->method('getAppValue')
581+
->method('getValueString')
582582
->with('dav', 'invitation_link_recipients', 'yes')
583583
->willReturn('yes');
584584
$this->service->expects(self::once())
@@ -633,7 +633,7 @@ public function testMailProviderSend(): void {
633633
];
634634
// construct system config mock returns
635635
$this->config->expects(self::once())
636-
->method('getAppValue')
636+
->method('getValueString')
637637
->with('dav', 'invitation_link_recipients', 'yes')
638638
->willReturn('yes');
639639
// construct user mock returns
@@ -708,6 +708,113 @@ public function testMailProviderSend(): void {
708708
$this->assertEquals('1.1', $message->getScheduleStatus());
709709
}
710710

711+
public function testMailProviderDisabled(): void {
712+
$message = new Message();
713+
$message->method = 'REQUEST';
714+
$newVCalendar = new VCalendar();
715+
$newVevent = new VEvent($newVCalendar, 'one', array_merge([
716+
'UID' => 'uid-1234',
717+
'SEQUENCE' => 1,
718+
'SUMMARY' => 'Fellowship meeting without (!) Boromir',
719+
'DTSTART' => new \DateTime('2016-01-01 00:00:00')
720+
], []));
721+
$newVevent->add('ORGANIZER', 'mailto:[email protected]');
722+
$newVevent->add('ATTENDEE', 'mailto:' . '[email protected]', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
723+
$message->message = $newVCalendar;
724+
$message->sender = 'mailto:[email protected]';
725+
$message->senderName = 'Mr. Wizard';
726+
$message->recipient = 'mailto:' . '[email protected]';
727+
// save the old copy in the plugin
728+
$oldVCalendar = new VCalendar();
729+
$oldVEvent = new VEvent($oldVCalendar, 'one', [
730+
'UID' => 'uid-1234',
731+
'SEQUENCE' => 0,
732+
'SUMMARY' => 'Fellowship meeting',
733+
'DTSTART' => new \DateTime('2016-01-01 00:00:00')
734+
]);
735+
$oldVEvent->add('ORGANIZER', 'mailto:[email protected]');
736+
$oldVEvent->add('ATTENDEE', 'mailto:' . '[email protected]', ['RSVP' => 'TRUE', 'CN' => 'Frodo']);
737+
$oldVEvent->add('ATTENDEE', 'mailto:' . '[email protected]', ['RSVP' => 'TRUE']);
738+
$oldVCalendar->add($oldVEvent);
739+
$data = ['invitee_name' => 'Mr. Wizard',
740+
'meeting_title' => 'Fellowship meeting without (!) Boromir',
741+
'attendee_name' => '[email protected]'
742+
];
743+
$attendees = $newVevent->select('ATTENDEE');
744+
$atnd = '';
745+
foreach ($attendees as $attendee) {
746+
if (strcasecmp($attendee->getValue(), $message->recipient) === 0) {
747+
$atnd = $attendee;
748+
}
749+
}
750+
$this->plugin->setVCalendar($oldVCalendar);
751+
$this->service->expects(self::once())
752+
->method('getLastOccurrence')
753+
->willReturn(1496912700);
754+
$this->mailer->expects(self::once())
755+
->method('validateMailAddress')
756+
757+
->willReturn(true);
758+
$this->eventComparisonService->expects(self::once())
759+
->method('findModified')
760+
->willReturn(['new' => [$newVevent], 'old' => [$oldVEvent]]);
761+
$this->service->expects(self::once())
762+
->method('getCurrentAttendee')
763+
->with($message)
764+
->willReturn($atnd);
765+
$this->service->expects(self::once())
766+
->method('isRoomOrResource')
767+
->with($atnd)
768+
->willReturn(false);
769+
$this->service->expects(self::once())
770+
->method('buildBodyData')
771+
->with($newVevent, $oldVEvent)
772+
->willReturn($data);
773+
$this->user->expects(self::any())
774+
->method('getUID')
775+
->willReturn('user1');
776+
$this->user->expects(self::any())
777+
->method('getDisplayName')
778+
->willReturn('Mr. Wizard');
779+
$this->userSession->expects(self::any())
780+
->method('getUser')
781+
->willReturn($this->user);
782+
$this->service->expects(self::once())
783+
->method('getFrom');
784+
$this->service->expects(self::once())
785+
->method('addSubjectAndHeading')
786+
->with($this->emailTemplate, 'request', 'Mr. Wizard', 'Fellowship meeting without (!) Boromir', true);
787+
$this->service->expects(self::once())
788+
->method('addBulletList')
789+
->with($this->emailTemplate, $newVevent, $data);
790+
$this->service->expects(self::once())
791+
->method('getAttendeeRsvpOrReqForParticipant')
792+
->willReturn(true);
793+
$this->config->expects(self::once())
794+
->method('getValueString')
795+
->with('dav', 'invitation_link_recipients', 'yes')
796+
->willReturn('yes');
797+
$this->config->expects(self::once())
798+
->method('getValueBool')
799+
->with('core', 'mail_providers_enabled', true)
800+
->willReturn(false);
801+
$this->service->expects(self::once())
802+
->method('createInvitationToken')
803+
->with($message, $newVevent, 1496912700)
804+
->willReturn('token');
805+
$this->service->expects(self::once())
806+
->method('addResponseButtons')
807+
->with($this->emailTemplate, 'token');
808+
$this->service->expects(self::once())
809+
->method('addMoreOptionsButton')
810+
->with($this->emailTemplate, 'token');
811+
$this->mailer->expects(self::once())
812+
->method('send')
813+
->willReturn([]);
814+
$this->plugin->schedule($message);
815+
$this->assertEquals('1.1', $message->getScheduleStatus());
816+
}
817+
711818
public function testNoOldEvent(): void {
712819
$message = new Message();
713820
$message->method = 'REQUEST';
@@ -779,7 +886,7 @@ public function testNoOldEvent(): void {
779886
->method('getAttendeeRsvpOrReqForParticipant')
780887
->willReturn(true);
781888
$this->config->expects(self::once())
782-
->method('getAppValue')
889+
->method('getValueString')
783890
->with('dav', 'invitation_link_recipients', 'yes')
784891
->willReturn('yes');
785892
$this->service->expects(self::once())
@@ -872,7 +979,7 @@ public function testNoButtons(): void {
872979
->method('getAttendeeRsvpOrReqForParticipant')
873980
->willReturn(true);
874981
$this->config->expects(self::once())
875-
->method('getAppValue')
982+
->method('getValueString')
876983
->with('dav', 'invitation_link_recipients', 'yes')
877984
->willReturn('no');
878985
$this->service->expects(self::never())

apps/settings/composer/composer/autoload_classmap.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
'OCA\\Settings\\Hooks' => $baseDir . '/../lib/Hooks.php',
4141
'OCA\\Settings\\Listener\\AppPasswordCreatedActivityListener' => $baseDir . '/../lib/Listener/AppPasswordCreatedActivityListener.php',
4242
'OCA\\Settings\\Listener\\GroupRemovedListener' => $baseDir . '/../lib/Listener/GroupRemovedListener.php',
43+
'OCA\\Settings\\Listener\\MailProviderListener' => $baseDir . '/../lib/Listener/MailProviderListener.php',
4344
'OCA\\Settings\\Listener\\UserAddedToGroupActivityListener' => $baseDir . '/../lib/Listener/UserAddedToGroupActivityListener.php',
4445
'OCA\\Settings\\Listener\\UserRemovedFromGroupActivityListener' => $baseDir . '/../lib/Listener/UserRemovedFromGroupActivityListener.php',
4546
'OCA\\Settings\\Mailer\\NewUserMailHelper' => $baseDir . '/../lib/Mailer/NewUserMailHelper.php',
@@ -67,6 +68,7 @@
6768
'OCA\\Settings\\Settings\\Admin\\ArtificialIntelligence' => $baseDir . '/../lib/Settings/Admin/ArtificialIntelligence.php',
6869
'OCA\\Settings\\Settings\\Admin\\Delegation' => $baseDir . '/../lib/Settings/Admin/Delegation.php',
6970
'OCA\\Settings\\Settings\\Admin\\Mail' => $baseDir . '/../lib/Settings/Admin/Mail.php',
71+
'OCA\\Settings\\Settings\\Admin\\MailProvider' => $baseDir . '/../lib/Settings/Admin/MailProvider.php',
7072
'OCA\\Settings\\Settings\\Admin\\Overview' => $baseDir . '/../lib/Settings/Admin/Overview.php',
7173
'OCA\\Settings\\Settings\\Admin\\Security' => $baseDir . '/../lib/Settings/Admin/Security.php',
7274
'OCA\\Settings\\Settings\\Admin\\Server' => $baseDir . '/../lib/Settings/Admin/Server.php',

apps/settings/composer/composer/autoload_static.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class ComposerStaticInitSettings
5555
'OCA\\Settings\\Hooks' => __DIR__ . '/..' . '/../lib/Hooks.php',
5656
'OCA\\Settings\\Listener\\AppPasswordCreatedActivityListener' => __DIR__ . '/..' . '/../lib/Listener/AppPasswordCreatedActivityListener.php',
5757
'OCA\\Settings\\Listener\\GroupRemovedListener' => __DIR__ . '/..' . '/../lib/Listener/GroupRemovedListener.php',
58+
'OCA\\Settings\\Listener\\MailProviderListener' => __DIR__ . '/..' . '/../lib/Listener/MailProviderListener.php',
5859
'OCA\\Settings\\Listener\\UserAddedToGroupActivityListener' => __DIR__ . '/..' . '/../lib/Listener/UserAddedToGroupActivityListener.php',
5960
'OCA\\Settings\\Listener\\UserRemovedFromGroupActivityListener' => __DIR__ . '/..' . '/../lib/Listener/UserRemovedFromGroupActivityListener.php',
6061
'OCA\\Settings\\Mailer\\NewUserMailHelper' => __DIR__ . '/..' . '/../lib/Mailer/NewUserMailHelper.php',
@@ -82,6 +83,7 @@ class ComposerStaticInitSettings
8283
'OCA\\Settings\\Settings\\Admin\\ArtificialIntelligence' => __DIR__ . '/..' . '/../lib/Settings/Admin/ArtificialIntelligence.php',
8384
'OCA\\Settings\\Settings\\Admin\\Delegation' => __DIR__ . '/..' . '/../lib/Settings/Admin/Delegation.php',
8485
'OCA\\Settings\\Settings\\Admin\\Mail' => __DIR__ . '/..' . '/../lib/Settings/Admin/Mail.php',
86+
'OCA\\Settings\\Settings\\Admin\\MailProvider' => __DIR__ . '/..' . '/../lib/Settings/Admin/MailProvider.php',
8587
'OCA\\Settings\\Settings\\Admin\\Overview' => __DIR__ . '/..' . '/../lib/Settings/Admin/Overview.php',
8688
'OCA\\Settings\\Settings\\Admin\\Security' => __DIR__ . '/..' . '/../lib/Settings/Admin/Security.php',
8789
'OCA\\Settings\\Settings\\Admin\\Server' => __DIR__ . '/..' . '/../lib/Settings/Admin/Server.php',

apps/settings/lib/AppInfo/Application.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
use OCA\Settings\Hooks;
1616
use OCA\Settings\Listener\AppPasswordCreatedActivityListener;
1717
use OCA\Settings\Listener\GroupRemovedListener;
18+
use OCA\Settings\Listener\MailProviderListener;
1819
use OCA\Settings\Listener\UserAddedToGroupActivityListener;
1920
use OCA\Settings\Listener\UserRemovedFromGroupActivityListener;
2021
use OCA\Settings\Mailer\NewUserMailHelper;
2122
use OCA\Settings\Middleware\SubadminMiddleware;
2223
use OCA\Settings\Search\AppSearch;
2324
use OCA\Settings\Search\SectionSearch;
2425
use OCA\Settings\Search\UserSearch;
26+
use OCA\Settings\Settings\Admin\MailProvider;
2527
use OCA\Settings\SetupChecks\AllowedAdminRanges;
2628
use OCA\Settings\SetupChecks\AppDirsWithDifferentOwner;
2729
use OCA\Settings\SetupChecks\BruteForceThrottler;
@@ -86,6 +88,8 @@
8688
use OCP\Group\Events\UserAddedEvent;
8789
use OCP\Group\Events\UserRemovedEvent;
8890
use OCP\IServerContainer;
91+
use OCP\Settings\Events\DeclarativeSettingsGetValueEvent;
92+
use OCP\Settings\Events\DeclarativeSettingsSetValueEvent;
8993
use OCP\Settings\IManager;
9094
use OCP\Util;
9195

@@ -113,10 +117,17 @@ public function register(IRegistrationContext $context): void {
113117
$context->registerEventListener(UserRemovedEvent::class, UserRemovedFromGroupActivityListener::class);
114118
$context->registerEventListener(GroupDeletedEvent::class, GroupRemovedListener::class);
115119

120+
// Register Mail Provider listeners
121+
$context->registerEventListener(DeclarativeSettingsGetValueEvent::class, MailProviderListener::class);
122+
$context->registerEventListener(DeclarativeSettingsSetValueEvent::class, MailProviderListener::class);
123+
116124
// Register well-known handlers
117125
$context->registerWellKnownHandler(SecurityTxtHandler::class);
118126
$context->registerWellKnownHandler(ChangePasswordHandler::class);
119127

128+
// Register Settings Form(s)
129+
$context->registerDeclarativeSettings(MailProvider::class);
130+
120131
/**
121132
* Core class wrappers
122133
*/

0 commit comments

Comments
 (0)