Skip to content

Commit 8b742ab

Browse files
authored
Merge pull request #28997 from nextcloud/fix/set-attendee-as-recipient
2 parents 2be0eda + fab887c commit 8b742ab

3 files changed

Lines changed: 85 additions & 25 deletions

File tree

apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,10 @@ public function handleITipMessage(Message $iTipMessage) {
124124
$schedulingPlugin = $this->server->getPlugin('caldav-schedule');
125125
$schedulingPlugin->scheduleLocalDelivery($iTipMessage);
126126
}
127+
128+
public function isExternalAttendee(string $principalUri): bool {
129+
/** @var \Sabre\DAVACL\Plugin $aclPlugin */
130+
$aclPlugin = $this->server->getPlugin('acl');
131+
return $aclPlugin->getPrincipalByUri($principalUri) === null;
132+
}
127133
}

apps/dav/lib/Controller/InvitationResponseController.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,12 @@ private function buildITipResponse(array $row, string $partStat, int $guests = n
198198
$iTipMessage->method = 'REPLY';
199199
$iTipMessage->sequence = $row['sequence'];
200200
$iTipMessage->sender = $row['attendee'];
201-
$iTipMessage->recipient = $row['organizer'];
201+
202+
if ($this->responseServer->isExternalAttendee($row['attendee'])) {
203+
$iTipMessage->recipient = $row['organizer'];
204+
} else {
205+
$iTipMessage->recipient = $row['attendee'];
206+
}
202207

203208
$message = <<<EOF
204209
BEGIN:VCALENDAR

apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* along with this program. If not, see <http://www.gnu.org/licenses/>.
2828
*
2929
*/
30+
3031
namespace OCA\DAV\Tests\Unit\DAV\Controller;
3132

3233
use OCA\DAV\CalDAV\InvitationResponse\InvitationResponseServer;
@@ -77,7 +78,17 @@ protected function setUp(): void {
7778
);
7879
}
7980

80-
public function testAccept() {
81+
public function attendeeProvider(): array {
82+
return [
83+
'local attendee' => [false],
84+
'external attendee' => [true]
85+
];
86+
}
87+
88+
/**
89+
* @dataProvider attendeeProvider
90+
*/
91+
public function testAccept(bool $isExternalAttendee): void {
8192
$this->buildQueryExpects('TOKEN123', [
8293
'id' => 0,
8394
'uid' => 'this-is-the-events-uid',
@@ -110,21 +121,26 @@ public function testAccept() {
110121
$called = false;
111122
$this->responseServer->expects($this->once())
112123
->method('handleITipMessage')
113-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
124+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
114125
$called = true;
115126
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
116127
$this->assertEquals('VEVENT', $iTipMessage->component);
117128
$this->assertEquals('REPLY', $iTipMessage->method);
118129
$this->assertEquals(null, $iTipMessage->sequence);
119130
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
120-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
131+
if ($isExternalAttendee) {
132+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
133+
} else {
134+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
135+
}
121136

122137
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
123138

124139
$this->assertEquals($expected, $iTipMessage->message->serialize());
125140
});
126-
127-
141+
$this->responseServer->expects($this->once())
142+
->method('isExternalAttendee')
143+
->willReturn($isExternalAttendee);
128144

129145
$response = $this->controller->accept('TOKEN123');
130146
$this->assertInstanceOf(TemplateResponse::class, $response);
@@ -133,7 +149,10 @@ public function testAccept() {
133149
$this->assertTrue($called);
134150
}
135151

136-
public function testAcceptSequence() {
152+
/**
153+
* @dataProvider attendeeProvider
154+
*/
155+
public function testAcceptSequence(bool $isExternalAttendee): void {
137156
$this->buildQueryExpects('TOKEN123', [
138157
'id' => 0,
139158
'uid' => 'this-is-the-events-uid',
@@ -166,21 +185,26 @@ public function testAcceptSequence() {
166185
$called = false;
167186
$this->responseServer->expects($this->once())
168187
->method('handleITipMessage')
169-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
188+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
170189
$called = true;
171190
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
172191
$this->assertEquals('VEVENT', $iTipMessage->component);
173192
$this->assertEquals('REPLY', $iTipMessage->method);
174193
$this->assertEquals(1337, $iTipMessage->sequence);
175194
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
176-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
195+
if ($isExternalAttendee) {
196+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
197+
} else {
198+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
199+
}
177200

178201
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
179202

180203
$this->assertEquals($expected, $iTipMessage->message->serialize());
181204
});
182-
183-
205+
$this->responseServer->expects($this->once())
206+
->method('isExternalAttendee')
207+
->willReturn($isExternalAttendee);
184208

185209
$response = $this->controller->accept('TOKEN123');
186210
$this->assertInstanceOf(TemplateResponse::class, $response);
@@ -189,7 +213,10 @@ public function testAcceptSequence() {
189213
$this->assertTrue($called);
190214
}
191215

192-
public function testAcceptRecurrenceId() {
216+
/**
217+
* @dataProvider attendeeProvider
218+
*/
219+
public function testAcceptRecurrenceId(bool $isExternalAttendee): void {
193220
$this->buildQueryExpects('TOKEN123', [
194221
'id' => 0,
195222
'uid' => 'this-is-the-events-uid',
@@ -223,21 +250,26 @@ public function testAcceptRecurrenceId() {
223250
$called = false;
224251
$this->responseServer->expects($this->once())
225252
->method('handleITipMessage')
226-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
253+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
227254
$called = true;
228255
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
229256
$this->assertEquals('VEVENT', $iTipMessage->component);
230257
$this->assertEquals('REPLY', $iTipMessage->method);
231258
$this->assertEquals(0, $iTipMessage->sequence);
232259
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
233-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
260+
if ($isExternalAttendee) {
261+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
262+
} else {
263+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
264+
}
234265

235266
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
236267

237268
$this->assertEquals($expected, $iTipMessage->message->serialize());
238269
});
239-
240-
270+
$this->responseServer->expects($this->once())
271+
->method('isExternalAttendee')
272+
->willReturn($isExternalAttendee);
241273

242274
$response = $this->controller->accept('TOKEN123');
243275
$this->assertInstanceOf(TemplateResponse::class, $response);
@@ -273,7 +305,10 @@ public function testAcceptExpiredToken() {
273305
$this->assertEquals([], $response->getParams());
274306
}
275307

276-
public function testDecline() {
308+
/**
309+
* @dataProvider attendeeProvider
310+
*/
311+
public function testDecline(bool $isExternalAttendee): void {
277312
$this->buildQueryExpects('TOKEN123', [
278313
'id' => 0,
279314
'uid' => 'this-is-the-events-uid',
@@ -306,21 +341,26 @@ public function testDecline() {
306341
$called = false;
307342
$this->responseServer->expects($this->once())
308343
->method('handleITipMessage')
309-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
344+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
310345
$called = true;
311346
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
312347
$this->assertEquals('VEVENT', $iTipMessage->component);
313348
$this->assertEquals('REPLY', $iTipMessage->method);
314349
$this->assertEquals(null, $iTipMessage->sequence);
315350
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
316-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
351+
if ($isExternalAttendee) {
352+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
353+
} else {
354+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
355+
}
317356

318357
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
319358

320359
$this->assertEquals($expected, $iTipMessage->message->serialize());
321360
});
322-
323-
361+
$this->responseServer->expects($this->once())
362+
->method('isExternalAttendee')
363+
->willReturn($isExternalAttendee);
324364

325365
$response = $this->controller->decline('TOKEN123');
326366
$this->assertInstanceOf(TemplateResponse::class, $response);
@@ -336,7 +376,10 @@ public function testOptions() {
336376
$this->assertEquals(['token' => 'TOKEN123'], $response->getParams());
337377
}
338378

339-
public function testProcessMoreOptionsResult() {
379+
/**
380+
* @dataProvider attendeeProvider
381+
*/
382+
public function testProcessMoreOptionsResult(bool $isExternalAttendee): void {
340383
$this->request->expects($this->at(0))
341384
->method('getParam')
342385
->with('partStat')
@@ -384,20 +427,26 @@ public function testProcessMoreOptionsResult() {
384427
$called = false;
385428
$this->responseServer->expects($this->once())
386429
->method('handleITipMessage')
387-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
430+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
388431
$called = true;
389432
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
390433
$this->assertEquals('VEVENT', $iTipMessage->component);
391434
$this->assertEquals('REPLY', $iTipMessage->method);
392435
$this->assertEquals(null, $iTipMessage->sequence);
393436
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
394-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
437+
if ($isExternalAttendee) {
438+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
439+
} else {
440+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
441+
}
395442

396443
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
397444

398445
$this->assertEquals($expected, $iTipMessage->message->serialize());
399446
});
400-
447+
$this->responseServer->expects($this->once())
448+
->method('isExternalAttendee')
449+
->willReturn($isExternalAttendee);
401450

402451

403452
$response = $this->controller->processMoreOptionsResult('TOKEN123');

0 commit comments

Comments
 (0)