Skip to content

Commit d0eb977

Browse files
kesselbMichaIng
authored andcommitted
Update attendence for external users
For local users it's possible to select their calendar via the principal url and first update their own attendance status. External users have no calendar event hence the recipient is the organizer. Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
1 parent 91da66a commit d0eb977

File tree

3 files changed

+84
-25
lines changed

3 files changed

+84
-25
lines changed

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

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

apps/dav/lib/Controller/InvitationResponseController.php

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

205210
$message = <<<EOF
206211
BEGIN:VCALENDAR

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

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,17 @@ protected function setUp(): void {
7676
);
7777
}
7878

79-
public function testAccept() {
79+
public function attendeeProvider(): array {
80+
return [
81+
'local attendee' => [false],
82+
'external attendee' => [true]
83+
];
84+
}
85+
86+
/**
87+
* @dataProvider attendeeProvider
88+
*/
89+
public function testAccept(bool $isExternalAttendee): void {
8090
$this->buildQueryExpects('TOKEN123', [
8191
'id' => 0,
8292
'uid' => 'this-is-the-events-uid',
@@ -109,21 +119,26 @@ public function testAccept() {
109119
$called = false;
110120
$this->responseServer->expects($this->once())
111121
->method('handleITipMessage')
112-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
122+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
113123
$called = true;
114124
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
115125
$this->assertEquals('VEVENT', $iTipMessage->component);
116126
$this->assertEquals('REPLY', $iTipMessage->method);
117127
$this->assertEquals(null, $iTipMessage->sequence);
118128
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
119-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
129+
if ($isExternalAttendee) {
130+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
131+
} else {
132+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
133+
}
120134

121135
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
122136

123137
$this->assertEquals($expected, $iTipMessage->message->serialize());
124138
});
125-
126-
139+
$this->responseServer->expects($this->once())
140+
->method('isExternalAttendee')
141+
->willReturn($isExternalAttendee);
127142

128143
$response = $this->controller->accept('TOKEN123');
129144
$this->assertInstanceOf(TemplateResponse::class, $response);
@@ -132,7 +147,10 @@ public function testAccept() {
132147
$this->assertTrue($called);
133148
}
134149

135-
public function testAcceptSequence() {
150+
/**
151+
* @dataProvider attendeeProvider
152+
*/
153+
public function testAcceptSequence(bool $isExternalAttendee): void {
136154
$this->buildQueryExpects('TOKEN123', [
137155
'id' => 0,
138156
'uid' => 'this-is-the-events-uid',
@@ -165,21 +183,26 @@ public function testAcceptSequence() {
165183
$called = false;
166184
$this->responseServer->expects($this->once())
167185
->method('handleITipMessage')
168-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
186+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
169187
$called = true;
170188
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
171189
$this->assertEquals('VEVENT', $iTipMessage->component);
172190
$this->assertEquals('REPLY', $iTipMessage->method);
173191
$this->assertEquals(1337, $iTipMessage->sequence);
174192
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
175-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
193+
if ($isExternalAttendee) {
194+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
195+
} else {
196+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
197+
}
176198

177199
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
178200

179201
$this->assertEquals($expected, $iTipMessage->message->serialize());
180202
});
181-
182-
203+
$this->responseServer->expects($this->once())
204+
->method('isExternalAttendee')
205+
->willReturn($isExternalAttendee);
183206

184207
$response = $this->controller->accept('TOKEN123');
185208
$this->assertInstanceOf(TemplateResponse::class, $response);
@@ -188,7 +211,10 @@ public function testAcceptSequence() {
188211
$this->assertTrue($called);
189212
}
190213

191-
public function testAcceptRecurrenceId() {
214+
/**
215+
* @dataProvider attendeeProvider
216+
*/
217+
public function testAcceptRecurrenceId(bool $isExternalAttendee): void {
192218
$this->buildQueryExpects('TOKEN123', [
193219
'id' => 0,
194220
'uid' => 'this-is-the-events-uid',
@@ -222,21 +248,26 @@ public function testAcceptRecurrenceId() {
222248
$called = false;
223249
$this->responseServer->expects($this->once())
224250
->method('handleITipMessage')
225-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
251+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
226252
$called = true;
227253
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
228254
$this->assertEquals('VEVENT', $iTipMessage->component);
229255
$this->assertEquals('REPLY', $iTipMessage->method);
230256
$this->assertEquals(0, $iTipMessage->sequence);
231257
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
232-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
258+
if ($isExternalAttendee) {
259+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
260+
} else {
261+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
262+
}
233263

234264
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
235265

236266
$this->assertEquals($expected, $iTipMessage->message->serialize());
237267
});
238-
239-
268+
$this->responseServer->expects($this->once())
269+
->method('isExternalAttendee')
270+
->willReturn($isExternalAttendee);
240271

241272
$response = $this->controller->accept('TOKEN123');
242273
$this->assertInstanceOf(TemplateResponse::class, $response);
@@ -272,7 +303,10 @@ public function testAcceptExpiredToken() {
272303
$this->assertEquals([], $response->getParams());
273304
}
274305

275-
public function testDecline() {
306+
/**
307+
* @dataProvider attendeeProvider
308+
*/
309+
public function testDecline(bool $isExternalAttendee): void {
276310
$this->buildQueryExpects('TOKEN123', [
277311
'id' => 0,
278312
'uid' => 'this-is-the-events-uid',
@@ -305,21 +339,26 @@ public function testDecline() {
305339
$called = false;
306340
$this->responseServer->expects($this->once())
307341
->method('handleITipMessage')
308-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
342+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
309343
$called = true;
310344
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
311345
$this->assertEquals('VEVENT', $iTipMessage->component);
312346
$this->assertEquals('REPLY', $iTipMessage->method);
313347
$this->assertEquals(null, $iTipMessage->sequence);
314348
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
315-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
349+
if ($isExternalAttendee) {
350+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
351+
} else {
352+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
353+
}
316354

317355
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
318356

319357
$this->assertEquals($expected, $iTipMessage->message->serialize());
320358
});
321-
322-
359+
$this->responseServer->expects($this->once())
360+
->method('isExternalAttendee')
361+
->willReturn($isExternalAttendee);
323362

324363
$response = $this->controller->decline('TOKEN123');
325364
$this->assertInstanceOf(TemplateResponse::class, $response);
@@ -335,7 +374,10 @@ public function testOptions() {
335374
$this->assertEquals(['token' => 'TOKEN123'], $response->getParams());
336375
}
337376

338-
public function testProcessMoreOptionsResult() {
377+
/**
378+
* @dataProvider attendeeProvider
379+
*/
380+
public function testProcessMoreOptionsResult(bool $isExternalAttendee): void {
339381
$this->request->expects($this->at(0))
340382
->method('getParam')
341383
->with('partStat')
@@ -383,20 +425,26 @@ public function testProcessMoreOptionsResult() {
383425
$called = false;
384426
$this->responseServer->expects($this->once())
385427
->method('handleITipMessage')
386-
->willReturnCallback(function (Message $iTipMessage) use (&$called, $expected) {
428+
->willReturnCallback(function (Message $iTipMessage) use (&$called, $isExternalAttendee, $expected) {
387429
$called = true;
388430
$this->assertEquals('this-is-the-events-uid', $iTipMessage->uid);
389431
$this->assertEquals('VEVENT', $iTipMessage->component);
390432
$this->assertEquals('REPLY', $iTipMessage->method);
391433
$this->assertEquals(null, $iTipMessage->sequence);
392434
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->sender);
393-
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
435+
if ($isExternalAttendee) {
436+
$this->assertEquals('mailto:organizer@foo.bar', $iTipMessage->recipient);
437+
} else {
438+
$this->assertEquals('mailto:attendee@foo.bar', $iTipMessage->recipient);
439+
}
394440

395441
$iTipMessage->scheduleStatus = '1.2;Message delivered locally';
396442

397443
$this->assertEquals($expected, $iTipMessage->message->serialize());
398444
});
399-
445+
$this->responseServer->expects($this->once())
446+
->method('isExternalAttendee')
447+
->willReturn($isExternalAttendee);
400448

401449

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

0 commit comments

Comments
 (0)