make Calendars shareable via CalDAV
authorLars Kneschke <l.kneschke@metaways.de>
Tue, 4 Feb 2014 16:17:27 +0000 (17:17 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 4 Sep 2014 09:25:28 +0000 (11:25 +0200)
Change-Id: I990735bb16415f32d1556ecf575f8a23435932bb
Reviewed-on: http://gerrit.tine20.com/customers/318
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Calendar/Frontend/CalDAVTest.php
tests/tine20/Calendar/Frontend/WebDAV/ContainerTest.php
tests/tine20/Tinebase/WebDav/PrincipalBackendTest.php
tine20/Calendar/Frontend/WebDAV/Container.php
tine20/Tinebase/Server/WebDAV.php
tine20/Tinebase/WebDav/PrincipalBackend.php
tine20/Tinebase/WebDav/Root.php

index 744ee91..def5130 100644 (file)
@@ -161,6 +161,5 @@ class Calendar_Frontend_CalDAVTest extends PHPUnit_Framework_TestCase
         $container = Tinebase_Container::getInstance()->getContainerByName('Calendar', $randomName, Tinebase_Model_Container::TYPE_PERSONAL, Tinebase_Core::getUser());
         
         $this->assertTrue($container instanceof Tinebase_Model_Container);
-        
     }
 }
index 9d9c72d..67a169d 100644 (file)
@@ -294,6 +294,18 @@ class Calendar_Frontend_WebDAV_ContainerTest extends PHPUnit_Framework_TestCase
     }
     
     /**
+     * test Calendar_Frontend_WebDAV_Container::getShares
+     */
+    public function testGetShares()
+    {
+        $container = new Calendar_Frontend_WebDAV_Container($this->objects['initialContainer']);
+        
+        $shares = $container->getShares();
+        
+        $this->assertEquals(3, count($shares));
+    }
+    
+    /**
      * return vcalendar as string and replace organizers email address with emailaddess of current user
      * 
      * @param string $_filename  file to open
index 9913168..401f3f2 100644 (file)
  */
 require_once dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR . 'TestHelper.php';
 
-if (!defined('PHPUnit_MAIN_METHOD')) {
-    define('PHPUnit_MAIN_METHOD', 'Tinebase_WebDav_PrincipalBackendTest::main');
-}
-
 /**
  * Test class for Tinebase_Group
  * @depricated, some fns might be moved to other testclasses
  */
-class Tinebase_WebDav_PrincipalBackendTest extends PHPUnit_Framework_TestCase
+class Tinebase_WebDav_PrincipalBackendTest extends TestCase
 {
     /**
      * @var array test objects
@@ -35,18 +31,6 @@ class Tinebase_WebDav_PrincipalBackendTest extends PHPUnit_Framework_TestCase
     protected $_backend;
     
     /**
-     * Runs the test methods of this class.
-     *
-     * @access public
-     * @static
-     */
-    public static function main()
-    {
-        $suite  = new PHPUnit_Framework_TestSuite('Tinebase_WebDav_PrincipalBackendTest');
-        PHPUnit_TextUI_TestRunner::run($suite);
-    }
-    
-    /**
      * Sets up the fixture.
      * This method is called before a test is executed.
      *
@@ -54,32 +38,57 @@ class Tinebase_WebDav_PrincipalBackendTest extends PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
+        parent::setUp();
+        
         $this->_backend = new Tinebase_WebDav_PrincipalBackend();
     }
     
     /**
-     * Tears down the fixture
-     * This method is called after a test is executed.
-     *
-     * @access protected
+     * test getPrincipalsByPrefix with groups prefix
+     */
+    public function testGetPrincipalsByGroupPrefix()
+    {
+        $principals = $this->_backend->getPrincipalsByPrefix(Tinebase_WebDav_PrincipalBackend::PREFIX_GROUPS);
+
+        $this->assertGreaterThanOrEqual(1, count($principals));
+    }
+    
+    /**
+     * test getPrincipalsByPrefix with users prefix
      */
-    protected function tearDown()
+    public function testGetPrincipalsByUserPrefix()
     {
+        $principals = $this->_backend->getPrincipalsByPrefix(Tinebase_WebDav_PrincipalBackend::PREFIX_USERS);
+
+        $this->assertGreaterThanOrEqual(1, count($principals));
+    }
+    
+    /**
+     * @todo it's just a fake test // the test has to use a list_id when backend logic is implemented finaly
+     */
+    public function testGetPrincipalByGroupPath()
+    {
+        $principal = $this->_backend->getPrincipalByPath(Tinebase_WebDav_PrincipalBackend::PREFIX_GROUPS . '/' . Tinebase_Core::getUser()->accountPrimaryGroup);
+        
+        //var_dump($principal);
+        
+        $this->assertEquals(Tinebase_WebDav_PrincipalBackend::PREFIX_GROUPS . '/' . Tinebase_Core::getUser()->accountPrimaryGroup, $principal['uri']);
+        $this->assertEquals('Tine 2.0 group ' . Tinebase_Core::getUser()->accountPrimaryGroup, $principal['{DAV:}displayname']);
     }
     
-    public function testGetPrincipalByPath()
+    public function testGetPrincipalByUserPath()
     {
-        $principal = $this->_backend->getPrincipalByPath('principals/users/' . Tinebase_Core::getUser()->contact_id);
+        $principal = $this->_backend->getPrincipalByPath(Tinebase_WebDav_PrincipalBackend::PREFIX_USERS . '/' . Tinebase_Core::getUser()->contact_id);
         
         //var_dump($principal);
         
-        $this->assertEquals('principals/users/' . Tinebase_Core::getUser()->contact_id, $principal['uri']);
+        $this->assertEquals(Tinebase_WebDav_PrincipalBackend::PREFIX_USERS . '/' . Tinebase_Core::getUser()->contact_id, $principal['uri']);
         $this->assertEquals(Tinebase_Core::getUser()->accountDisplayName, $principal['{DAV:}displayname']);
     }
     
     public function testGetGroupMembership()
     {
-        $groupMemberships = $this->_backend->getGroupMembership('principals/users/' . Tinebase_Core::getUser()->contact_id);
+        $groupMemberships = $this->_backend->getGroupMembership(Tinebase_WebDav_PrincipalBackend::PREFIX_USERS . '/' . Tinebase_Core::getUser()->contact_id);
         
         //var_dump($groupMemberships);
         
@@ -88,9 +97,9 @@ class Tinebase_WebDav_PrincipalBackendTest extends PHPUnit_Framework_TestCase
     
     public function testSearchPrincipals()
     {
-        $uris = $this->_backend->searchPrincipals('principals/users/', array(
-            '{http://sabredav.org/ns}email-address' => Tinebase_Core::getUser()->accountEmailAddress
-        ));
+        $uris = $this->_backend->searchPrincipals(Tinebase_WebDav_PrincipalBackend::PREFIX_USERS, array(
+            '{http://sabredav.org/ns}email-address' => Tinebase_Core::getUser()->accountEmailAddress)
+        );
         
         $this->assertEquals(1, count($uris), 'could not find user by email address ' . Tinebase_Core::getUser()->accountEmailAddress);
         $this->assertContains('principals/users/' . Tinebase_Core::getUser()->contact_id, $uris);
index f017899..afb2e99 100644 (file)
@@ -20,7 +20,7 @@ use Sabre\CalDAV;
  * @package     Calendar
  * @subpackage  Frontend
  */
-class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstract implements Sabre\CalDAV\ICalendar
+class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstract implements Sabre\CalDAV\ICalendar, Sabre\CalDAV\IShareableCalendar
 {
     protected $_applicationName = 'Calendar';
     
@@ -255,6 +255,56 @@ class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstr
     }
     
     /**
+     * (non-PHPdoc)
+     * @see \Sabre\CalDAV\IShareableCalendar::getShares()
+     */
+    public function getShares()
+    {
+        $result = array();
+        
+        foreach (Tinebase_Container::getInstance()->getGrantsOfContainer($this->_container) as $grant) {
+            
+            switch ($grant->account_type) {
+                case 'anyone':
+                    $href       = '/principals/groups/anyone';
+                    $commonName = 'Anyone';
+                    break;
+                
+                case 'group':
+                    $list       = Tinebase_Group::getInstance()->getGroupById($grant->account_id);
+                     
+                    $href       = '/principals/groups/' . $list->list_id;
+                    $commonName = $list->name;
+                    
+                    break;
+                    
+                case 'user':
+                    $contact    = Tinebase_User::getInstance()->getUserById($grant->account_id);
+                     
+                    $href       = '/principals/users/' . $contact->contact_id;
+                    $commonName = $contact->accountDisplayName;
+                    break;
+            }
+            
+            $writeAble = $grant[Tinebase_Model_Grants::GRANT_ADMIN] || 
+                         ( $grant[Tinebase_Model_Grants::GRANT_READ] && 
+                           $grant[Tinebase_Model_Grants::GRANT_ADD]  && 
+                           $grant[Tinebase_Model_Grants::GRANT_EDIT] &&
+                           $grant[Tinebase_Model_Grants::GRANT_DELETE] );
+            
+            $result[] = array(
+                'href'       => $href,
+                'commonName' => $commonName,
+                'status'     => Sabre\CalDAV\SharingPlugin::STATUS_ACCEPTED,
+                'readOnly'   => !$writeAble, 
+                'summary'    => null            //optional
+            ); 
+        }
+        
+        return $result;
+    }
+    
+    /**
      * Returns the list of supported privileges for this node.
      *
      * The returned data structure is a list of nested privileges.
@@ -266,8 +316,8 @@ class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstr
      *
      * @return array|null
      */
-    public function getSupportedPrivilegeSet() {
-
+    public function getSupportedPrivilegeSet() 
+    {
         $default = DAVACL\Plugin::getDefaultSupportedPrivilegeSet();
 
         // We need to inject 'read-free-busy' in the tree, aggregated under
@@ -284,4 +334,13 @@ class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstr
         
         return $default;
     }
+    
+    /**
+     * (non-PHPdoc)
+     * @see \Sabre\CalDAV\IShareableCalendar::updateShares()
+     */
+    public function updateShares(array $add, array $remove)
+    {
+        
+    }
 }
index 97bea2b..2e8d2d4 100644 (file)
@@ -100,12 +100,13 @@ class Tinebase_Server_WebDAV extends Tinebase_Server_Abstract implements Tinebas
         );
         
         $aclPlugin = new \Sabre\DAVACL\Plugin();
-        $aclPlugin->defaultUsernamePath = 'principals/users';
-        $aclPlugin->principalCollectionSet = array($aclPlugin->defaultUsernamePath/*, 'principals/groups'*/);
+        $aclPlugin->defaultUsernamePath    = Tinebase_WebDav_PrincipalBackend::PREFIX_USERS;
+        $aclPlugin->principalCollectionSet = array (Tinebase_WebDav_PrincipalBackend::PREFIX_USERS, Tinebase_WebDav_PrincipalBackend::PREFIX_GROUPS);
         self::$_server->addPlugin($aclPlugin);
         
         self::$_server->addPlugin(new \Sabre\CardDAV\Plugin());
         self::$_server->addPlugin(new \Sabre\CalDAV\Plugin());
+        self::$_server->addPlugin(new \Sabre\CalDAV\SharingPlugin());
         self::$_server->addPlugin(new Calendar_Frontend_CalDAV_PluginAutoSchedule());
         self::$_server->addPlugin(new Calendar_Frontend_CalDAV_PluginDefaultAlarms());
         self::$_server->addPlugin(new Tinebase_WebDav_Plugin_Inverse());
index 1db7197..9662c37 100644 (file)
@@ -20,39 +20,84 @@ use Sabre\DAVACL;
  */
 class Tinebase_WebDav_PrincipalBackend implements DAVACL\PrincipalBackend\BackendInterface
 {
+    const PREFIX_USERS  = 'principals/users';
+    const PREFIX_GROUPS = 'principals/groups';
+    
     /**
      * (non-PHPdoc)
      * @see Sabre\DAVACL\IPrincipalBackend::getPrincipalsByPrefix()
+     * @todo currently we return the current user and his groups only // we should return ALL users/groups here
      */
     public function getPrincipalsByPrefix($prefixPath) 
     {
-        $principal = array(
-            'uri'               => 'principals/users/' . Tinebase_Core::getUser()->contact_id,
-            '{DAV:}displayname' => Tinebase_Core::getUser()->accountDisplayName
-        );
+        $principals = array();
         
-        if (!empty(Tinebase_Core::getUser()->accountEmailAddress)) {
-            $principal['{http://sabredav.org/ns}email-address'] = Tinebase_Core::getUser()->accountEmailAddress;
+        switch ($prefixPath) {
+            case self::PREFIX_GROUPS:
+                $groups = Tinebase_Group::getInstance()->getMultiple(Tinebase_Core::getUser()->getGroupMemberships());
+                
+                foreach ($groups as $group) {
+                    if (empty($group->list_id)) {
+                        continue;
+                    }
+                    $principals[] = array(
+                        'uri'               => self::PREFIX_GROUPS . '/' . $group->list_id,
+                        '{DAV:}displayname' => $group->name
+                    );
+                }
+                
+                
+                break;
+                
+            case self::PREFIX_USERS:
+                $principal = array(
+                    'uri'               => self::PREFIX_USERS . '/' . Tinebase_Core::getUser()->contact_id,
+                    '{DAV:}displayname' => Tinebase_Core::getUser()->accountDisplayName
+                );
+                
+                if (!empty(Tinebase_Core::getUser()->accountEmailAddress)) {
+                    $principal['{http://sabredav.org/ns}email-address'] = Tinebase_Core::getUser()->accountEmailAddress;
+                }
+                
+                $principals[] = $principal;
+                
+                break;
         }
         
-        $principals = array($principal);
-        
         return $principals;
     }
     
     /**
      * (non-PHPdoc)
      * @see Sabre\DAVACL\IPrincipalBackend::getPrincipalByPath()
+     * @todo implement search for users and groups
      */
     public function getPrincipalByPath($path) 
     {
-        $principal = array(
-            'uri'               => 'principals/users/' . Tinebase_Core::getUser()->contact_id,
-            '{DAV:}displayname' => Tinebase_Core::getUser()->accountDisplayName
-        );
+        $principal = null;
+        
+        list($prefix, $name) = \Sabre\DAV\URLUtil::splitPath($path);
         
-        if (!empty(Tinebase_Core::getUser()->accountEmailAddress)) {
-            $principal['{http://sabredav.org/ns}email-address'] = Tinebase_Core::getUser()->accountEmailAddress;
+        switch ($prefix) {
+            case self::PREFIX_GROUPS:
+                $principal = array(
+                    'uri'               => self::PREFIX_GROUPS . '/' . $name,
+                    '{DAV:}displayname' => 'Tine 2.0 group ' . $name
+                );
+                
+                break;
+                
+            case self::PREFIX_USERS:
+                $principal = array(
+                    'uri'               => self::PREFIX_USERS . '/' . Tinebase_Core::getUser()->contact_id,
+                    '{DAV:}displayname' => Tinebase_Core::getUser()->accountDisplayName
+                );
+                
+                if (!empty(Tinebase_Core::getUser()->accountEmailAddress)) {
+                    $principal['{http://sabredav.org/ns}email-address'] = Tinebase_Core::getUser()->accountEmailAddress;
+                }
+                
+                break;
         }
         
         return $principal;
@@ -136,25 +181,30 @@ class Tinebase_WebDav_PrincipalBackend implements DAVACL\PrincipalBackend\Backen
         
         $principalUris = array();
         
-        if (!empty($searchProperties['{http://sabredav.org/ns}email-address'])) {
-            $filter = new Addressbook_Model_ContactFilter(array(
-                array(
-                    'field'     => 'email_query',
-                    'operator'  => 'equals',
-                    'value'     => $searchProperties['{http://sabredav.org/ns}email-address']
-                ),
-                array(
-                    'field'     => 'type',
-                    'operator'  => 'equals',
-                    'value'     => Addressbook_Model_Contact::CONTACTTYPE_USER
-                )
-            ));
-            
-            $result = Addressbook_Controller_Contact::getInstance()->search($filter, null, false, true);
-            
-            if (count($result) > 0) {
-                $principalUris[] = 'principals/users/' . $result[0];
-            }
+        switch ($prefixPath) {
+            case self::PREFIX_USERS:
+                if (!empty($searchProperties['{http://sabredav.org/ns}email-address'])) {
+                    $filter = new Addressbook_Model_ContactFilter(array(
+                        array(
+                            'field'     => 'email_query',
+                            'operator'  => 'equals',
+                            'value'     => $searchProperties['{http://sabredav.org/ns}email-address']
+                        ),
+                        array(
+                            'field'     => 'type',
+                            'operator'  => 'equals',
+                            'value'     => Addressbook_Model_Contact::CONTACTTYPE_USER
+                        )
+                    ));
+                    
+                    $result = Addressbook_Controller_Contact::getInstance()->search($filter, null, false, true);
+                    
+                    if (count($result) > 0) {
+                        $principalUris[] = 'principals/users/' . $result[0];
+                    }
+                }
+                
+                break;
         }
         
         return $principalUris;
index edd2a05..5c41552 100644 (file)
@@ -64,8 +64,8 @@ class Tinebase_WebDav_Root extends DAV\SimpleCollection
             new DAV\SimpleCollection('tasks',                          $caldavTasksChildren),
             new DAV\SimpleCollection('webdav',                         $webdavChildren),
             new DAV\SimpleCollection('principals', array(
-                new DAVACL\PrincipalCollection(new Tinebase_WebDav_PrincipalBackend(), 'principals/users'),
-                new DAVACL\PrincipalCollection(new Tinebase_WebDav_PrincipalBackend(), 'principals/groups')
+                new DAVACL\PrincipalCollection(new Tinebase_WebDav_PrincipalBackend(), Tinebase_WebDav_PrincipalBackend::PREFIX_USERS),
+                new DAVACL\PrincipalCollection(new Tinebase_WebDav_PrincipalBackend(), Tinebase_WebDav_PrincipalBackend::PREFIX_GROUPS)
             )),
             // main entry point for ownCloud 
             new DAV\SimpleCollection('remote.php',                     $ownCloudChildren)