Skip to content

Commit fd3df6e

Browse files
committed
perf: skip request without write permission
Signed-off-by: Daniel Kesselberg <[email protected]>
1 parent 39b716c commit fd3df6e

File tree

5 files changed

+131
-3
lines changed

5 files changed

+131
-3
lines changed

apps/dav/lib/Connector/Sabre/DavAclPlugin.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,19 @@ public function beforeMethod(RequestInterface $request, ResponseInterface $respo
9494
$path = $request->getPath();
9595

9696
// prevent the plugin from causing an unneeded overhead for file requests
97-
if (strpos($path, 'files/') !== 0) {
98-
parent::beforeMethod($request, $response);
97+
if (str_starts_with($path, 'files/')) {
98+
return;
99+
}
100+
101+
parent::beforeMethod($request, $response);
102+
103+
$createAddressbookOrCalendarRequest = ($request->getMethod() === 'MKCALENDAR' || $request->getMethod() === 'MKCOL')
104+
&& (str_starts_with($path, 'addressbooks/') || str_starts_with($path, 'calendars/'));
105+
106+
if ($createAddressbookOrCalendarRequest) {
107+
[$parentName] = \Sabre\Uri\split($path);
108+
// is calendars/users/bob or addressbooks/users/bob writeable?
109+
$this->checkPrivileges($parentName, '{DAV:}write');
99110
}
100111
}
101112
}

build/integration/features/bootstrap/CalDavContext.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
require __DIR__ . '/../../vendor/autoload.php';
2828

2929
use GuzzleHttp\Client;
30+
use GuzzleHttp\Exception\GuzzleException;
3031
use Psr\Http\Message\ResponseInterface;
3132

3233
class CalDavContext implements \Behat\Behat\Context\Context {
@@ -233,4 +234,28 @@ public function t($amount) {
233234
);
234235
}
235236
}
237+
238+
/**
239+
* @When :user sends a create calendar request to :calendar on the endpoint :endpoint
240+
*/
241+
public function sendsCreateCalendarRequest(string $user, string $calendar, string $endpoint) {
242+
$davUrl = $this->baseUrl . $endpoint . $calendar;
243+
$password = ($user === 'admin') ? 'admin' : '123456';
244+
245+
try {
246+
$this->response = $this->client->request(
247+
'MKCALENDAR',
248+
$davUrl,
249+
[
250+
'body' => '<c:mkcalendar xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:" xmlns:a="http://apple.com/ns/ical/" xmlns:o="http://owncloud.org/ns"><d:set><d:prop><d:displayname>test</d:displayname><o:calendar-enabled>1</o:calendar-enabled><a:calendar-color>#21213D</a:calendar-color><c:supported-calendar-component-set><c:comp name="VEVENT"/></c:supported-calendar-component-set></d:prop></d:set></c:mkcalendar>',
251+
'auth' => [
252+
$user,
253+
$password,
254+
],
255+
]
256+
);
257+
} catch (GuzzleException $e) {
258+
$this->response = $e->getResponse();
259+
}
260+
}
236261
}

build/integration/features/bootstrap/CardDavContext.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
require __DIR__ . '/../../vendor/autoload.php';
2727

2828
use GuzzleHttp\Client;
29+
use GuzzleHttp\Exception\GuzzleException;
2930
use GuzzleHttp\Message\ResponseInterface;
3031

3132
class CardDavContext implements \Behat\Behat\Context\Context {
@@ -311,4 +312,64 @@ public function theFollowingHttpHeadersShouldBeSet(\Behat\Gherkin\Node\TableNode
311312
}
312313
}
313314
}
315+
316+
/**
317+
* @When :user sends a create addressbook request to :addressbook on the endpoint :endpoint
318+
*/
319+
public function sendsCreateAddressbookRequest(string $user, string $addressbook, string $endpoint) {
320+
$davUrl = $this->baseUrl . $endpoint . $addressbook;
321+
$password = ($user === 'admin') ? 'admin' : '123456';
322+
323+
try {
324+
$this->response = $this->client->request(
325+
'MKCOL',
326+
$davUrl,
327+
[
328+
'body' => '<d:mkcol xmlns:card="urn:ietf:params:xml:ns:carddav"
329+
xmlns:d="DAV:">
330+
<d:set>
331+
<d:prop>
332+
<d:resourcetype>
333+
<d:collection />,<card:addressbook />
334+
</d:resourcetype>,<d:displayname>' . $addressbook . '</d:displayname>
335+
</d:prop>
336+
</d:set>
337+
</d:mkcol>',
338+
'auth' => [
339+
$user,
340+
$password,
341+
],
342+
'headers' => [
343+
'Content-Type' => 'application/xml;charset=UTF-8',
344+
],
345+
]
346+
);
347+
} catch (GuzzleException $e) {
348+
$this->response = $e->getResponse();
349+
}
350+
}
351+
352+
/**
353+
* @Then The CardDAV HTTP status code should be :code
354+
* @param int $code
355+
* @throws \Exception
356+
*/
357+
public function theCarddavHttpStatusCodeShouldBe($code) {
358+
if ((int)$code !== $this->response->getStatusCode()) {
359+
throw new \Exception(
360+
sprintf(
361+
'Expected %s got %s',
362+
(int)$code,
363+
$this->response->getStatusCode()
364+
)
365+
);
366+
}
367+
368+
$body = $this->response->getBody()->getContents();
369+
if ($body && substr($body, 0, 1) === '<') {
370+
$reader = new Sabre\Xml\Reader();
371+
$reader->xml($body);
372+
$this->responseXml = $reader->parse();
373+
}
374+
}
314375
}

build/integration/features/caldav.feature

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,20 @@ Feature: caldav
5858
Then The CalDAV HTTP status code should be "202"
5959
When "admin" requests calendar "/" on the endpoint "/remote.php/dav/public-calendars"
6060
Then The CalDAV HTTP status code should be "207"
61-
Then There should be "0" calendars in the response body
61+
Then There should be "0" calendars in the response body
62+
63+
Scenario: Create calendar request for non-existing calendar of another user
64+
Given user "user0" exists
65+
When "user0" sends a create calendar request to "admin/MyCalendar2" on the endpoint "/remote.php/dav/calendars/"
66+
Then The CalDAV HTTP status code should be "404"
67+
And The exception is "Sabre\DAV\Exception\NotFound"
68+
And The error message is "Node with name 'admin' could not be found"
69+
70+
Scenario: Create calendar request for existing calendar of another user
71+
Given user "user0" exists
72+
When "admin" creates a calendar named "MyCalendar2"
73+
Then The CalDAV HTTP status code should be "201"
74+
When "user0" sends a create calendar request to "admin/MyCalendar2" on the endpoint "/remote.php/dav/calendars/"
75+
Then The CalDAV HTTP status code should be "404"
76+
And The exception is "Sabre\DAV\Exception\NotFound"
77+
And The error message is "Node with name 'admin' could not be found"

build/integration/features/carddav.feature

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,18 @@ Feature: carddav
6262
|X-Permitted-Cross-Domain-Policies|none|
6363
|X-Robots-Tag|noindex, nofollow|
6464
|X-XSS-Protection|1; mode=block|
65+
66+
Scenario: Create addressbook request for non-existing addressbook of another user
67+
Given user "user0" exists
68+
When "user0" sends a create addressbook request to "admin/MyAddressbook2" on the endpoint "/remote.php/dav/addressbooks/"
69+
Then The CardDAV HTTP status code should be "404"
70+
And The CardDAV exception is "Sabre\DAV\Exception\NotFound"
71+
And The CardDAV error message is "File not found: admin in 'addressbooks'"
72+
73+
Scenario: Create addressbook request for existing addressbook of another user
74+
Given user "user0" exists
75+
When "admin" creates an addressbook named "MyAddressbook2" with statuscode "201"
76+
When "user0" sends a create addressbook request to "admin/MyAddressbook2" on the endpoint "/remote.php/dav/addressbooks/"
77+
Then The CardDAV HTTP status code should be "404"
78+
And The CardDAV exception is "Sabre\DAV\Exception\NotFound"
79+
And The CardDAV error message is "File not found: admin in 'addressbooks'"

0 commit comments

Comments
 (0)