]> source.dussan.org Git - nextcloud-server.git/commitdiff
perf: skip request without write permission 38747/head
authorDaniel Kesselberg <mail@danielkesselberg.de>
Mon, 12 Jun 2023 09:26:23 +0000 (11:26 +0200)
committerAnna (Rebase PR Action) <miaulalala@users.noreply.github.com>
Mon, 19 Jun 2023 13:42:13 +0000 (13:42 +0000)
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
apps/dav/lib/Connector/Sabre/DavAclPlugin.php
build/integration/features/bootstrap/CalDavContext.php
build/integration/features/bootstrap/CardDavContext.php
build/integration/features/caldav.feature
build/integration/features/carddav.feature

index 6842975835dfd647f5f95449a1d4f0c5657bd053..7fa94d7b90398c0804f5522e2a67b07def7c12a5 100644 (file)
@@ -94,8 +94,19 @@ class DavAclPlugin extends \Sabre\DAVACL\Plugin {
                $path = $request->getPath();
 
                // prevent the plugin from causing an unneeded overhead for file requests
-               if (strpos($path, 'files/') !== 0) {
-                       parent::beforeMethod($request, $response);
+               if (str_starts_with($path, 'files/')) {
+                       return;
+               }
+
+               parent::beforeMethod($request, $response);
+
+               $createAddressbookOrCalendarRequest = ($request->getMethod() === 'MKCALENDAR' || $request->getMethod() === 'MKCOL')
+                       && (str_starts_with($path, 'addressbooks/') || str_starts_with($path, 'calendars/'));
+
+               if ($createAddressbookOrCalendarRequest) {
+                       [$parentName] = \Sabre\Uri\split($path);
+                       // is calendars/users/bob or addressbooks/users/bob writeable?
+                       $this->checkPrivileges($parentName, '{DAV:}write');
                }
        }
 }
index 49d8c8e596357c1eb4648342c69379960a18e0a4..936463b579ef4c4ca000cc8cebf74d8e4c3d78ba 100644 (file)
@@ -27,6 +27,7 @@
 require __DIR__ . '/../../vendor/autoload.php';
 
 use GuzzleHttp\Client;
+use GuzzleHttp\Exception\GuzzleException;
 use Psr\Http\Message\ResponseInterface;
 
 class CalDavContext implements \Behat\Behat\Context\Context {
@@ -233,4 +234,28 @@ class CalDavContext implements \Behat\Behat\Context\Context {
                        );
                }
        }
+
+       /**
+        * @When :user sends a create calendar request to :calendar on the endpoint :endpoint
+        */
+       public function sendsCreateCalendarRequest(string $user, string $calendar, string $endpoint) {
+               $davUrl = $this->baseUrl . $endpoint . $calendar;
+               $password = ($user === 'admin') ? 'admin' : '123456';
+
+               try {
+                       $this->response = $this->client->request(
+                               'MKCALENDAR',
+                               $davUrl,
+                               [
+                                       '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>',
+                                       'auth' => [
+                                               $user,
+                                               $password,
+                                       ],
+                               ]
+                       );
+               } catch (GuzzleException $e) {
+                       $this->response = $e->getResponse();
+               }
+       }
 }
index 18a9f3dd24958b97481ef6c3becfcf446e62f975..80d96215ebaae92b5911e165280a756e03a016de 100644 (file)
@@ -26,6 +26,7 @@
 require __DIR__ . '/../../vendor/autoload.php';
 
 use GuzzleHttp\Client;
+use GuzzleHttp\Exception\GuzzleException;
 use GuzzleHttp\Message\ResponseInterface;
 
 class CardDavContext implements \Behat\Behat\Context\Context {
@@ -311,4 +312,64 @@ class CardDavContext implements \Behat\Behat\Context\Context {
                        }
                }
        }
+
+       /**
+        * @When :user sends a create addressbook request to :addressbook on the endpoint :endpoint
+        */
+       public function sendsCreateAddressbookRequest(string $user, string $addressbook, string $endpoint) {
+               $davUrl = $this->baseUrl . $endpoint . $addressbook;
+               $password = ($user === 'admin') ? 'admin' : '123456';
+
+               try {
+                       $this->response = $this->client->request(
+                               'MKCOL',
+                               $davUrl,
+                               [
+                                       'body' => '<d:mkcol xmlns:card="urn:ietf:params:xml:ns:carddav"
+                                 xmlns:d="DAV:">
+               <d:set>
+                 <d:prop>
+                       <d:resourcetype>
+                               <d:collection />,<card:addressbook />
+                         </d:resourcetype>,<d:displayname>' . $addressbook . '</d:displayname>
+                 </d:prop>
+               </d:set>
+         </d:mkcol>',
+                                       'auth' => [
+                                               $user,
+                                               $password,
+                                       ],
+                                       'headers' => [
+                                               'Content-Type' => 'application/xml;charset=UTF-8',
+                                       ],
+                               ]
+                       );
+               } catch (GuzzleException $e) {
+                       $this->response = $e->getResponse();
+               }
+       }
+
+       /**
+        * @Then The CardDAV HTTP status code should be :code
+        * @param int $code
+        * @throws \Exception
+        */
+       public function theCarddavHttpStatusCodeShouldBe($code) {
+               if ((int)$code !== $this->response->getStatusCode()) {
+                       throw new \Exception(
+                               sprintf(
+                                       'Expected %s got %s',
+                                       (int)$code,
+                                       $this->response->getStatusCode()
+                               )
+                       );
+               }
+
+               $body = $this->response->getBody()->getContents();
+               if ($body && substr($body, 0, 1) === '<') {
+                       $reader = new Sabre\Xml\Reader();
+                       $reader->xml($body);
+                       $this->responseXml = $reader->parse();
+               }
+       }
 }
index 2bddbc3e9e4086ff3ccb907934096a98e5ef650f..e2cb4f8dc9235481dc69f3ff8b7273423af6e7ed 100644 (file)
@@ -58,4 +58,20 @@ Feature: caldav
     Then The CalDAV HTTP status code should be "202"
     When "admin" requests calendar "/" on the endpoint "/remote.php/dav/public-calendars"
     Then The CalDAV HTTP status code should be "207"
-    Then There should be "0" calendars in the response body
\ No newline at end of file
+    Then There should be "0" calendars in the response body
+
+  Scenario: Create calendar request for non-existing calendar of another user
+    Given user "user0" exists
+    When "user0" sends a create calendar request to "admin/MyCalendar2" on the endpoint "/remote.php/dav/calendars/"
+    Then The CalDAV HTTP status code should be "404"
+    And The exception is "Sabre\DAV\Exception\NotFound"
+    And The error message is "Node with name 'admin' could not be found"
+
+  Scenario: Create calendar request for existing calendar of another user
+    Given user "user0" exists
+    When "admin" creates a calendar named "MyCalendar2"
+    Then The CalDAV HTTP status code should be "201"
+    When "user0" sends a create calendar request to "admin/MyCalendar2" on the endpoint "/remote.php/dav/calendars/"
+    Then The CalDAV HTTP status code should be "404"
+    And The exception is "Sabre\DAV\Exception\NotFound"
+    And The error message is "Node with name 'admin' could not be found"
index e0c11ec8dc19a3f52da7f5c6eb5e6e5363995b22..9c9df6ddd94be687012771dc146b4cf5e1517bf1 100644 (file)
@@ -62,3 +62,18 @@ Feature: carddav
       |X-Permitted-Cross-Domain-Policies|none|
       |X-Robots-Tag|noindex, nofollow|
       |X-XSS-Protection|1; mode=block|
+
+  Scenario: Create addressbook request for non-existing addressbook of another user
+    Given user "user0" exists
+    When "user0" sends a create addressbook request to "admin/MyAddressbook2" on the endpoint "/remote.php/dav/addressbooks/"
+    Then The CardDAV HTTP status code should be "404"
+    And The CardDAV exception is "Sabre\DAV\Exception\NotFound"
+    And The CardDAV error message is "File not found: admin in 'addressbooks'"
+
+  Scenario: Create addressbook request for existing addressbook of another user
+    Given user "user0" exists
+    When "admin" creates an addressbook named "MyAddressbook2" with statuscode "201"
+    When "user0" sends a create addressbook request to "admin/MyAddressbook2" on the endpoint "/remote.php/dav/addressbooks/"
+    Then The CardDAV HTTP status code should be "404"
+    And The CardDAV exception is "Sabre\DAV\Exception\NotFound"
+    And The CardDAV error message is "File not found: admin in 'addressbooks'"