[Pkg-owncloud-commits] [php-sabredav] 07/220: Moved the first bits of functionality into the generic plugin.

David Prévot taffit at moszumanska.debian.org
Thu May 12 01:21:01 UTC 2016


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository php-sabredav.

commit f79356738682018c15eba62013c36f9898b4cba9
Author: Evert Pot <me at evertpot.com>
Date:   Tue Jul 28 18:26:55 2015 -0400

    Moved the first bits of functionality into the generic plugin.
---
 lib/CalDAV/IShareableCalendar.php                  |  37 +---
 lib/CalDAV/ShareableCalendar.php                   |  52 ++++++
 lib/CalDAV/SharingPlugin.php                       |  23 +--
 .../Sharing/IShareableNode.php}                    |  24 +--
 lib/DAV/Sharing/Plugin.php                         | 193 +++++++++++++++++++++
 tests/Sabre/CalDAV/SharingPluginTest.php           |  12 +-
 tests/Sabre/DAVServerTest.php                      |   9 +
 7 files changed, 289 insertions(+), 61 deletions(-)

diff --git a/lib/CalDAV/IShareableCalendar.php b/lib/CalDAV/IShareableCalendar.php
index 7420d94..c7a6dc8 100644
--- a/lib/CalDAV/IShareableCalendar.php
+++ b/lib/CalDAV/IShareableCalendar.php
@@ -2,6 +2,8 @@
 
 namespace Sabre\CalDAV;
 
+use Sabre\DAV\Sharing\IShareableNode;
+
 /**
  * This interface represents a Calendar that can be shared with other users.
  *
@@ -9,40 +11,17 @@ namespace Sabre\CalDAV;
  * @author Evert Pot (http://evertpot.com/)
  * @license http://sabre.io/license/ Modified BSD License
  */
-interface IShareableCalendar extends ICalendar {
+interface IShareableCalendar extends IShareableNode {
 
     /**
-     * Updates the list of shares.
-     *
-     * The first array is a list of people that are to be added to the
-     * calendar.
+     * Marks this calendar as published.
      *
-     * Every element in the add array has the following properties:
-     *   * href - A url. Usually a mailto: address
-     *   * commonName - Usually a first and last name, or false
-     *   * summary - A description of the share, can also be false
-     *   * readOnly - A boolean value
+     * Publishing a calendar should automatically create a read-only, public,
+     * subscribable calendar.
      *
-     * Every element in the remove array is just the address string.
-     *
-     * @param array $add
-     * @param array $remove
+     * @param bool $value
      * @return void
      */
-    function updateShares(array $add, array $remove);
-
-    /**
-     * Returns the list of people whom this calendar is shared with.
-     *
-     * Every element in this array should have the following properties:
-     *   * href - Often a mailto: address
-     *   * commonName - Optional, for example a first + last name
-     *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
-     *   * readOnly - boolean
-     *   * summary - Optional, a description for the share
-     *
-     * @return array
-     */
-    function getShares();
+    function setPublishStatus($value);
 
 }
diff --git a/lib/CalDAV/ShareableCalendar.php b/lib/CalDAV/ShareableCalendar.php
index c81c963..6b2f04f 100644
--- a/lib/CalDAV/ShareableCalendar.php
+++ b/lib/CalDAV/ShareableCalendar.php
@@ -2,6 +2,8 @@
 
 namespace Sabre\CalDAV;
 
+use Sabre\DAVACL\Plugin as ACLPlugin;
+
 /**
  * This object represents a CalDAV calendar that can be shared with other
  * users.
@@ -69,4 +71,54 @@ class ShareableCalendar extends Calendar implements IShareableCalendar {
 
     }
 
+    /**
+     * Returns a list of ACE's for this node.
+     *
+     * Each ACE has the following properties:
+     *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+     *     currently the only supported privileges
+     *   * 'principal', a url to the principal who owns the node
+     *   * 'protected' (optional), indicating that this ACE is not allowed to
+     *      be updated.
+     *
+     * @return array
+     */
+    function getACL() {
+
+        // The top-level ACL only contains access information for the true
+        // owner of the calendar, so we need to add the information for the
+        // sharee.
+        $acl = parent::getACL();
+        $acl[] = [
+            'privilege' => '{DAV:}share',
+            'principal' => $this->calendarInfo['principaluri'],
+            'protected' => true,
+        ];
+        return $acl;
+
+    }
+
+    /**
+     * Returns the list of supported privileges for this node.
+     *
+     * The returned data structure is a list of nested privileges.
+     * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
+     * standard structure.
+     *
+     * If null is returned from this method, the default privilege set is used,
+     * which is fine for most common usecases.
+     *
+     * @return array|null
+     */
+    function getSupportedPrivilegeSet() {
+
+        $default = parent::getSupportedPrivilegeSet();
+        $default['aggregates'][] = [
+            'privilege' => '{DAV:}share',
+        ];
+
+        return $default;
+
+    }
+
 }
diff --git a/lib/CalDAV/SharingPlugin.php b/lib/CalDAV/SharingPlugin.php
index 94f5d67..492067a 100644
--- a/lib/CalDAV/SharingPlugin.php
+++ b/lib/CalDAV/SharingPlugin.php
@@ -83,6 +83,11 @@ class SharingPlugin extends DAV\ServerPlugin {
     function initialize(DAV\Server $server) {
 
         $this->server = $server;
+
+        if (is_null($this->server->getPlugin('sharing'))) {
+            throw new \LogicException('The generic "sharing" plugin must be loaded before the caldav sharing plugin. Call $server->addPlugin(new \Sabre\DAV\Sharing\Plugin()); before this one.');
+        }
+
         $server->resourceTypeMapping['Sabre\\CalDAV\\ISharedCalendar'] = '{' . Plugin::NS_CALENDARSERVER . '}shared';
 
         array_push(
@@ -272,22 +277,8 @@ class SharingPlugin extends DAV\ServerPlugin {
             case '{DAV:}share-resource' :
             case '{' . Plugin::NS_CALENDARSERVER . '}share' :
 
-                // We can only deal with IShareableCalendar objects
-                if (!$node instanceof IShareableCalendar) {
-                    return;
-                }
-
-                $this->server->transactionType = 'post-calendar-share';
-
-                // Getting ACL info
-                $acl = $this->server->getPlugin('acl');
-
-                // If there's no ACL support, we allow everything
-                if ($acl) {
-                    $acl->checkPrivileges($path, '{DAV:}share');
-                }
-
-                $node->updateShares($message->set, $message->remove);
+                $sharingPlugin = $this->server->getPlugin('sharing');
+                $sharingPlugin->shareResource($path, $message->set, $message->remove);
 
                 $response->setStatus(200);
                 // Adding this because sending a response body may cause issues,
diff --git a/lib/CalDAV/IShareableCalendar.php b/lib/DAV/Sharing/IShareableNode.php
similarity index 59%
copy from lib/CalDAV/IShareableCalendar.php
copy to lib/DAV/Sharing/IShareableNode.php
index 7420d94..4cbef50 100644
--- a/lib/CalDAV/IShareableCalendar.php
+++ b/lib/DAV/Sharing/IShareableNode.php
@@ -1,29 +1,34 @@
 <?php
 
-namespace Sabre\CalDAV;
+namespace Sabre\DAV\Sharing;
+
+use Sabre\DAV\INode;
 
 /**
- * This interface represents a Calendar that can be shared with other users.
+ * This interface represents a resource that can be shared with other users.
  *
- * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
+ * @copyright Copyright (C) 2007-2015 fruux GmbH. (https://fruux.com/)
  * @author Evert Pot (http://evertpot.com/)
  * @license http://sabre.io/license/ Modified BSD License
  */
-interface IShareableCalendar extends ICalendar {
+interface IShareableNode extends INode {
 
     /**
      * Updates the list of shares.
      *
      * The first array is a list of people that are to be added to the
-     * calendar.
+     * shared resource.
      *
      * Every element in the add array has the following properties:
      *   * href - A url. Usually a mailto: address
-     *   * commonName - Usually a first and last name, or false
      *   * summary - A description of the share, can also be false
      *   * readOnly - A boolean value
      *
-     * Every element in the remove array is just the address string.
+     * In addition to that, the array might have any additional properties,
+     * specified in clark-notation, such as '{DAV:}displayname'.
+     *
+     * Every element in the remove array is just the url of the sharee that's
+     * to be removed.
      *
      * @param array $add
      * @param array $remove
@@ -32,14 +37,13 @@ interface IShareableCalendar extends ICalendar {
     function updateShares(array $add, array $remove);
 
     /**
-     * Returns the list of people whom this calendar is shared with.
+     * Returns the list of people whom this resource is shared with.
      *
      * Every element in this array should have the following properties:
      *   * href - Often a mailto: address
      *   * commonName - Optional, for example a first + last name
-     *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
+     *   * status - See the Sabre\DAV\Sharing\Plugin::STATUS_ constants.
      *   * readOnly - boolean
-     *   * summary - Optional, a description for the share
      *
      * @return array
      */
diff --git a/lib/DAV/Sharing/Plugin.php b/lib/DAV/Sharing/Plugin.php
new file mode 100644
index 0000000..31b610b
--- /dev/null
+++ b/lib/DAV/Sharing/Plugin.php
@@ -0,0 +1,193 @@
+<?php
+
+namespace Sabre\DAV\Sharing;
+
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\Server;
+use Sabre\DAV\ServerPlugin;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
+
+/**
+ * This plugin implements HTTP requests and properties related to:
+ *
+ * draft-pot-webdav-resource-sharing-02
+ *
+ * This specification allows people to share webdav resources with others.
+ * 
+ * @copyright Copyright (C) 2007-2015 fruux GmbH. (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/) 
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Plugin extends ServerPlugin {
+
+    /**
+     * Reference to SabreDAV server object.
+     *
+     * @var Sabre\DAV\Server
+     */
+    protected $server;
+
+    /**
+     * This method should return a list of server-features.
+     *
+     * This is for example 'versioning' and is added to the DAV: header
+     * in an OPTIONS response.
+     *
+     * @return array
+     */
+    function getFeatures() {
+
+        return ['resource-sharing'];
+
+    }
+
+    /**
+     * Returns a plugin name.
+     *
+     * Using this name other plugins will be able to access other plugins
+     * using \Sabre\DAV\Server::getPlugin
+     *
+     * @return string
+     */
+    function getPluginName() {
+
+        return 'sharing';
+
+    }
+
+    /**
+     * This initializes the plugin.
+     *
+     * This function is called by Sabre\DAV\Server, after
+     * addPlugin is called.
+     *
+     * This method should set up the required event subscriptions.
+     *
+     * @param Server $server
+     * @return void
+     */
+    function initialize(Server $server) {
+
+        $this->server = $server;
+
+        $server->xml->elementMap['{DAV:}share-resource'] = 'Sabre\\DAV\\Xml\\Request\\ShareResource';
+        $server->on('method:POST',  [$this, 'httpPost']);
+
+    }
+
+    /**
+     * We intercept this to handle POST requests on shared resources
+     *
+     * @param RequestInterface $request
+     * @param ResponseInterface $response
+     * @return null|bool
+     */
+    function httpPost(RequestInterface $request, ResponseInterface $response) {
+
+        $path = $request->getPath();
+        $contentType = $request->getHeader('Content-Type');
+
+        // We're only interested in the davsharing content type.
+        if (strpos($contentType, 'application/davsharing+xml') === false) {
+            return;
+        }
+
+        $message = $this->server->xml->parse(
+            $request->getBody(),
+            $request->getUrl(),
+            $documentType
+        );
+
+        switch ($documentType) {
+
+            case '{DAV:}share-resource':
+
+                $this->shareResource($path, $message->set, $message->remove);
+                $response->setStatus(200);
+                // Adding this because sending a response body may cause issues,
+                // and I wanted some type of indicator the response was handled.
+                $response->setHeader('X-Sabre-Status', 'everything-went-well');
+
+                // Breaking the event chain
+                return false;
+
+            default :
+                throw new BadRequest('Unexpected document type: ' . $documentType . ' for this Content-Type');
+
+        }
+            
+    }
+
+    /**
+     * Updates the list of sharees on a shared resource.
+     *
+     * The set array is a list of people that are to be added to the
+     * shared resource.
+     *
+     * Every element in the add array has the following properties:
+     *   * href - A url. Usually a mailto: address
+     *   * summary - A description of the share, can also be false
+     *   * readOnly - A boolean value
+     *
+     * In addition to that, the array might have any additional properties,
+     * specified in clark-notation, such as '{DAV:}displayname'.
+     *
+     * Every element in the remove array is just the url of the sharee that's
+     * to be removed.
+     * 
+     * @param string $path 
+     * @param array $set 
+     * @param array $remove 
+     * @return void
+     */
+    function shareResource($path, $set, $remove) {
+
+        try {
+            $node = $this->server->tree->getNodeForPath($path);
+        } catch (DAV\Exception\NotFound $e) {
+            // If the target node is not found, we stop executing.
+            return;
+        }
+    
+        if (!$node instanceof IShareableNode) {
+
+            throw new Forbidden('Sharing is not allowed on this node');
+
+        }
+
+        // Getting ACL info
+        $acl = $this->server->getPlugin('acl');
+
+        // If there's no ACL support, we allow everything
+        if ($acl) {
+            $acl->checkPrivileges($path, '{DAV:}share');
+        }
+
+        $node->updateShares($set, $remove);
+
+    }
+
+    /**
+     * Returns a bunch of meta-data about the plugin.
+     *
+     * Providing this information is optional, and is mainly displayed by the
+     * Browser plugin.
+     *
+     * The description key in the returned array may contain html and will not
+     * be sanitized.
+     *
+     * @return array
+     */
+    function getPluginInfo() {
+
+        return [
+            'name'        => $this->getPluginName(),
+            'description' => 'This plugin implements WebDAV resource sharing',
+            'link'        => null,
+        ];
+
+    }
+
+}
diff --git a/tests/Sabre/CalDAV/SharingPluginTest.php b/tests/Sabre/CalDAV/SharingPluginTest.php
index cb8e28c..87c0395 100644
--- a/tests/Sabre/CalDAV/SharingPluginTest.php
+++ b/tests/Sabre/CalDAV/SharingPluginTest.php
@@ -205,11 +205,11 @@ RRR;
 
     function testShareRequestNoShareableCalendar() {
 
-        $request = HTTP\Sapi::createFromServerArray([
-            'REQUEST_METHOD' => 'POST',
-            'REQUEST_URI'    => '/calendars/user1/cal2',
-            'CONTENT_TYPE'   => 'text/xml',
-        ]);
+        $request = new HTTP\Request(
+            'POST',
+            '/calendars/user1/cal2',
+            ['Content-Type' => 'text/xml']
+        );
 
         $xml = '<?xml version="1.0"?>
 <cs:share xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
@@ -227,7 +227,7 @@ RRR;
         $request->setBody($xml);
 
         $response = $this->request($request);
-        $this->assertEquals(501, $response->status, $response->body);
+        $this->assertEquals(403, $response->getStatus(), $response->getBody());
 
     }
 
diff --git a/tests/Sabre/DAVServerTest.php b/tests/Sabre/DAVServerTest.php
index 6c79650..f26f2c3 100644
--- a/tests/Sabre/DAVServerTest.php
+++ b/tests/Sabre/DAVServerTest.php
@@ -89,6 +89,13 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
     protected $locksPlugin;
 
     /**
+     * Sharing plugin.
+     *
+     * @var \Sabre\DAV\Sharing\Plugin
+     */
+    protected $sharingPlugin;
+
+    /**
      * If this string is set, we will automatically log in the user with this
      * name.
      */
@@ -108,7 +115,9 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
             $this->server->addPlugin($this->caldavPlugin);
         }
         if ($this->setupCalDAVSharing) {
+            $this->sharingPlugin = new DAV\Sharing\Plugin();
             $this->caldavSharingPlugin = new CalDAV\SharingPlugin();
+            $this->server->addPlugin($this->sharingPlugin);
             $this->server->addPlugin($this->caldavSharingPlugin);
         }
         if ($this->setupCalDAVScheduling) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-php/php-sabredav.git



More information about the Pkg-owncloud-commits mailing list