Skip to content

Commit 9d0e7ce

Browse files
authored
Merge pull request #63308 from nextcloud/backport/62580/stable32
[stable32] fix(iMIP): Prevent mails from carrying an unrelated user's name
2 parents fd6a1bc + 596015e commit 9d0e7ce

4 files changed

Lines changed: 270 additions & 8 deletions

File tree

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

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010

1111
use OCA\DAV\CalDAV\CalendarObject;
1212
use OCA\DAV\CalDAV\EventComparisonService;
13+
use OCP\Accounts\IAccountManager;
1314
use OCP\AppFramework\Utility\ITimeFactory;
1415
use OCP\Defaults;
1516
use OCP\IAppConfig;
17+
use OCP\IUser;
1618
use OCP\IUserSession;
1719
use OCP\Mail\IMailer;
1820
use OCP\Mail\Provider\Address;
@@ -63,6 +65,7 @@ public function __construct(
6365
private IMipService $imipService,
6466
private EventComparisonService $eventComparisonService,
6567
private IMailManager $mailManager,
68+
private IAccountManager $accountManager,
6669
) {
6770
parent::__construct('');
6871
}
@@ -179,21 +182,17 @@ public function schedule(Message $iTipMessage) {
179182
}
180183
$this->imipService->setL10nFromAttendee($attendee);
181184

182-
// Build the sender name.
185+
$sender = substr($iTipMessage->sender, 7);
186+
183187
// Due to a bug in sabre, the senderName property for an iTIP message can actually also be a VObject Property
184-
// If the iTIP message senderName is null or empty use the user session name as the senderName
185188
if (($iTipMessage->senderName instanceof Parameter) && !empty(trim($iTipMessage->senderName->getValue()))) {
186189
$senderName = trim($iTipMessage->senderName->getValue());
187190
} elseif (is_string($iTipMessage->senderName) && !empty(trim($iTipMessage->senderName))) {
188191
$senderName = trim($iTipMessage->senderName);
189-
} elseif ($this->userSession->getUser() !== null) {
190-
$senderName = trim($this->userSession->getUser()->getDisplayName());
191192
} else {
192-
$senderName = '';
193+
$senderName = $this->getSenderNameFor($sender);
193194
}
194195

195-
$sender = substr($iTipMessage->sender, 7);
196-
197196
$replyingAttendee = null;
198197
switch (strtolower($iTipMessage->method)) {
199198
case self::METHOD_REPLY:
@@ -333,6 +332,40 @@ public function schedule(Message $iTipMessage) {
333332
}
334333
}
335334

335+
/**
336+
* Messages are regularly brokered on behalf of somebody else, so the
337+
* session user's name is only used when the sender address is one of
338+
* theirs.
339+
*/
340+
private function getSenderNameFor(string $sender): ?string {
341+
$user = $this->userSession->getUser();
342+
if ($user !== null && $this->isAddressOfUser($sender, $user)) {
343+
return trim($user->getDisplayName()) ?: null;
344+
}
345+
346+
return null;
347+
}
348+
349+
/**
350+
* Profile email addresses are part of the user's calendar-user-address-set
351+
* and therefore valid sender addresses next to the system email address.
352+
*/
353+
private function isAddressOfUser(string $address, IUser $user): bool {
354+
if (strcasecmp((string)$user->getEMailAddress(), $address) === 0) {
355+
return true;
356+
}
357+
358+
$emailCollection = $this->accountManager->getAccount($user)
359+
->getPropertyCollection(IAccountManager::COLLECTION_EMAIL);
360+
foreach ($emailCollection->getProperties() as $property) {
361+
if (strcasecmp($property->getValue(), $address) === 0) {
362+
return true;
363+
}
364+
}
365+
366+
return false;
367+
}
368+
336369
/**
337370
* @return ?VCalendar
338371
*/

apps/dav/lib/Server.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ public function __construct(
356356
$userSession,
357357
\OCP\Server::get(IMipService::class),
358358
\OCP\Server::get(EventComparisonService::class),
359-
\OCP\Server::get(\OCP\Mail\Provider\IManager::class)
359+
\OCP\Server::get(\OCP\Mail\Provider\IManager::class),
360+
\OCP\Server::get(IAccountManager::class),
360361
));
361362
}
362363
$this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use OCA\DAV\CalDAV\EventComparisonService;
1414
use OCA\DAV\CalDAV\Schedule\IMipPlugin;
1515
use OCA\DAV\CalDAV\Schedule\IMipService;
16+
use OCP\Accounts\IAccountManager;
1617
use OCP\AppFramework\Utility\ITimeFactory;
1718
use OCP\Defaults;
1819
use OCP\IAppConfig;
@@ -55,6 +56,7 @@ class IMipPluginCharsetTest extends TestCase {
5556
private IUserSession&MockObject $userSession;
5657
private LoggerInterface $logger;
5758
private IUserManager&MockObject $userManager;
59+
private IAccountManager&MockObject $accountManager;
5860

5961
// Services
6062
private EventComparisonService $eventComparisonService;
@@ -120,6 +122,7 @@ protected function setUp(): void {
120122
$this->userSession->method('getUser')
121123
->willReturn($user);
122124
$this->mailManager = $this->createMock(IManager::class);
125+
$this->accountManager = $this->createMock(IAccountManager::class);
123126
$this->imipPlugin = new IMipPlugin(
124127
$this->appConfig,
125128
$this->mailer,
@@ -130,6 +133,7 @@ protected function setUp(): void {
130133
$this->imipService,
131134
$this->eventComparisonService,
132135
$this->mailManager,
136+
$this->accountManager,
133137
);
134138

135139
// ITipMessage

0 commit comments

Comments
 (0)