From 69d3601dcbb17ea9e2d868144159867a79d8e25c Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 6 Jul 2016 12:19:46 +0200 Subject: [PATCH 01/44] Proper work on Publishing --- apps/dav/appinfo/v1/caldav.php | 1 + apps/dav/lib/CalDAV/CalDavBackend.php | 37 ++++ apps/dav/lib/CalDAV/Calendar.php | 24 ++- .../lib/CalDAV/Publishing/PublishPlugin.php | 187 ++++++++++++++++++ .../lib/CalDAV/Publishing/Xml/Publisher.php | 55 ++++++ apps/dav/lib/Server.php | 1 + 6 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 apps/dav/lib/CalDAV/Publishing/PublishPlugin.php create mode 100644 apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index 13b4d3119c..4ac88ec328 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -71,6 +71,7 @@ $server->setBaseUri($baseuri); $server->addPlugin(new MaintenancePlugin()); $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, 'ownCloud')); $server->addPlugin(new \Sabre\CalDAV\Plugin()); +$server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin()); $server->addPlugin(new LegacyDAVACL()); if ($debugging) { diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 17479c490a..ed311fa0de 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1472,6 +1472,43 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription return $this->sharingBackend->getShares($resourceId); } + /** + * @param boolean $value + * @param \OCA\DAV\CalDAV\Calendar $calendar + */ + public function setPublishStatus($value, $calendar) { + $query = $this->db->getQueryBuilder(); + if ($value) { + $query->insert('dav_shares') + ->values([ + 'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()), + 'type' => $query->createNamedParameter('calendar'), + 'access' => $query->createNamedParameter(self::CLASSIFICATION_PUBLIC), + 'resourceid' => $query->createNamedParameter($calendar->getResourceId()) + ]); + } else { + $query->delete('dav_shares') + ->Where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) + ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::CLASSIFICATION_PUBLIC))); + } + $query->execute(); + } + + /** + * @param \OCA\DAV\CalDAV\Calendar $calendar + * @return boolean + */ + public function getPublishStatus($calendar) { + $query = $this->db->getQueryBuilder(); + $result = $query->select(['principaluri', 'access']) + ->from('dav_shares') + ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) + ->andWhere($query->expr()->eq('type', $query->createNamedParameter(self::CLASSIFICATION_PUBLIC))) + ->execute(); + + return count($result->fetch()) > 0; + } + /** * @param int $resourceId * @param array $acl diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index 821a71babb..f5607c6527 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -24,13 +24,14 @@ namespace OCA\DAV\CalDAV; use OCA\DAV\DAV\Sharing\IShareable; +use Sabre\CalDAV\IShareableCalendar; use OCP\IL10N; use Sabre\CalDAV\Backend\BackendInterface; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\PropPatch; -class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { +class Calendar extends \Sabre\CalDAV\Calendar implements IShareable, IShareableCalendar { public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n) { parent::__construct($caldavBackend, $calendarInfo); @@ -89,6 +90,13 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { return $this->calendarInfo['id']; } + /** + * @return str + */ + public function getPrincipalURI() { + return $this->calendarInfo['principaluri']; + } + function getACL() { $acl = [ [ @@ -236,6 +244,20 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { return $uris; } + /** + * @param boolean $value + */ + function setPublishStatus($value) { + $this->caldavBackend->setPublishStatus($value, $this); + } + + /** + * @return boolean $value + */ + function getPublishStatus() { + return $this->caldavBackend->getPublishStatus($this); + } + private function canWrite() { if (isset($this->calendarInfo['{http://owncloud.org/ns}read-only'])) { return !$this->calendarInfo['{http://owncloud.org/ns}read-only']; diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php new file mode 100644 index 0000000000..e6a5f0eb32 --- /dev/null +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -0,0 +1,187 @@ +server = $server; + + $this->server->on('method:POST', [$this, 'httpPost']); + $this->server->on('propFind', [$this, 'propFind']); + } + + function propFind(PropFind $propFind, INode $node) { + if ($node instanceof IShareableCalendar) { + $token = md5(\OC::$server->getConfig()->getSystemValue('secret','') . $node->getName()); + // $propFind->handle('{' . self::NS_CALENDARSERVER . '}publish-url', function() use ($node, $token) { + // return new Publisher($token); + // }); + + $propFind->handle('{' . self::NS_CALENDARSERVER . '}pre-publish-url', function() use ($node, $token) { + if ($node->getPublishStatus()) { + return new Publisher($token); + } + }); + } + } + + /** + * We intercept this to handle POST requests on calendars. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return null|bool + */ + function httpPost(RequestInterface $request, ResponseInterface $response) { + + $path = $request->getPath(); + + // Only handling xml + $contentType = $request->getHeader('Content-Type'); + if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) + return; + + // Making sure the node exists + try { + $node = $this->server->tree->getNodeForPath($path); + } catch (DAV\Exception\NotFound $e) { + return; + } + + $requestBody = $request->getBodyAsString(); + + // If this request handler could not deal with this POST request, it + // will return 'null' and other plugins get a chance to handle the + // request. + // + // However, we already requested the full body. This is a problem, + // because a body can only be read once. This is why we preemptively + // re-populated the request body with the existing data. + $request->setBody($requestBody); + + $message = $this->server->xml->parse($requestBody, $request->getUrl(), $documentType); + + switch ($documentType) { + + + case '{' . self::NS_CALENDARSERVER . '}publish-calendar' : + + // We can only deal with IShareableCalendar objects + if (!$node instanceof IShareableCalendar) { + return; + } + $this->server->transactionType = 'post-publish-calendar'; + + // Getting ACL info + $acl = $this->server->getPlugin('acl'); + + // If there's no ACL support, we allow everything + if ($acl) { + $acl->checkPrivileges($path, '{DAV:}write'); + } + + $node->setPublishStatus(true); + + // iCloud sends back the 202, so we will too. + $response->setStatus(202); + + // 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; + + case '{' . self::NS_CALENDARSERVER . '}unpublish-calendar' : + + // We can only deal with IShareableCalendar objects + if (!$node instanceof IShareableCalendar) { + return; + } + $this->server->transactionType = 'post-unpublish-calendar'; + + // Getting ACL info + $acl = $this->server->getPlugin('acl'); + + // If there's no ACL support, we allow everything + if ($acl) { + $acl->checkPrivileges($path, '{DAV:}write'); + } + + $node->setPublishStatus(false); + + $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; + + } + + + + } +} diff --git a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php new file mode 100644 index 0000000000..597652d0ef --- /dev/null +++ b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php @@ -0,0 +1,55 @@ +publishUrl = $publishUrl; + } + + /** + * @return str + */ + function getValue() { + return $this->publishUrl; + } + + /** + * The xmlSerialize metod is called during xml writing. + * + * Use the $writer argument to write its own xml serialization. + * + * An important note: do _not_ create a parent element. Any element + * implementing XmlSerializble should only ever write what's considered + * its 'inner xml'. + * + * The parent of the current element is responsible for writing a + * containing element. + * + * This allows serializers to be re-used for different element names. + * + * If you are opening new elements, you must also close them again. + * + * @param Writer $writer + * @return void + */ + function xmlSerialize(Writer $writer) { + + $cs = '{' . Plugin::NS_CALENDARSERVER . '}'; + $writer->write($this->publishUrl); + + } +} diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index 9058548489..defaddbd64 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -114,6 +114,7 @@ class Server { $this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin()); $this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin()); $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest())); + $this->server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin()); // addressbook plugins $this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin()); From 5824c2493b695562e3a58305ff2599819b4de105 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 6 Jul 2016 12:39:07 +0200 Subject: [PATCH 02/44] Make little corrections Function getPublishedStatus) is not working atm. --- apps/dav/appinfo/v1/caldav.php | 1 - apps/dav/lib/CalDAV/CalDavBackend.php | 5 ++- .../lib/CalDAV/Publishing/PublishPlugin.php | 45 ++++++++++--------- .../lib/CalDAV/Publishing/Xml/Publisher.php | 15 ++++++- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index 4ac88ec328..13b4d3119c 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -71,7 +71,6 @@ $server->setBaseUri($baseuri); $server->addPlugin(new MaintenancePlugin()); $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, 'ownCloud')); $server->addPlugin(new \Sabre\CalDAV\Plugin()); -$server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin()); $server->addPlugin(new LegacyDAVACL()); if ($debugging) { diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index ed311fa0de..43466b235e 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -66,6 +66,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription */ const MAX_DATE = '2038-01-01'; + const ACCESS_PUBLIC = 4; const CLASSIFICATION_PUBLIC = 0; const CLASSIFICATION_PRIVATE = 1; const CLASSIFICATION_CONFIDENTIAL = 2; @@ -1483,13 +1484,13 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription ->values([ 'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()), 'type' => $query->createNamedParameter('calendar'), - 'access' => $query->createNamedParameter(self::CLASSIFICATION_PUBLIC), + 'access' => $query->createNamedParameter(self::ACCESS_PUBLIC), 'resourceid' => $query->createNamedParameter($calendar->getResourceId()) ]); } else { $query->delete('dav_shares') ->Where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) - ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::CLASSIFICATION_PUBLIC))); + ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))); } $query->execute(); } diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index e6a5f0eb32..b1c4262420 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -6,13 +6,12 @@ namespace OCA\DAV\CalDAV\Publishing; use Sabre\DAV\PropFind; use Sabre\DAV\INode; -use OCP\IRequest; -use Sabre\CalDAV\IShareableCalendar; use Sabre\DAV\Server; use Sabre\DAV\ServerPlugin; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; use OCA\DAV\CalDAV\Publishing\Xml\Publisher; +use OCA\DAV\CalDAV\Calendar; class PublishPlugin extends ServerPlugin { @@ -70,36 +69,42 @@ class PublishPlugin extends ServerPlugin $this->server->on('propFind', [$this, 'propFind']); } - function propFind(PropFind $propFind, INode $node) { - if ($node instanceof IShareableCalendar) { - $token = md5(\OC::$server->getConfig()->getSystemValue('secret','') . $node->getName()); - // $propFind->handle('{' . self::NS_CALENDARSERVER . '}publish-url', function() use ($node, $token) { - // return new Publisher($token); - // }); + public function propFind(PropFind $propFind, INode $node) + { + if ($node instanceof Calendar) { + $token = md5(\OC::$server->getConfig()->getSystemValue('secret', '').$node->getName()); - $propFind->handle('{' . self::NS_CALENDARSERVER . '}pre-publish-url', function() use ($node, $token) { + $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $token) { if ($node->getPublishStatus()) { - return new Publisher($token); + return new Publisher($token, $node->getPublishStatus()); } }); + + $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $token) { + if ($node->getPublishStatus()) { + return new Publisher($token, false); + } + }); + } } - } /** * We intercept this to handle POST requests on calendars. * * @param RequestInterface $request * @param ResponseInterface $response + * * @return null|bool */ - function httpPost(RequestInterface $request, ResponseInterface $response) { - + public function httpPost(RequestInterface $request, ResponseInterface $response) + { $path = $request->getPath(); // Only handling xml $contentType = $request->getHeader('Content-Type'); - if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) + if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) { return; + } // Making sure the node exists try { @@ -123,11 +128,10 @@ class PublishPlugin extends ServerPlugin switch ($documentType) { - - case '{' . self::NS_CALENDARSERVER . '}publish-calendar' : + case '{'.self::NS_CALENDARSERVER.'}publish-calendar' : // We can only deal with IShareableCalendar objects - if (!$node instanceof IShareableCalendar) { + if (!$node instanceof Calendar) { return; } $this->server->transactionType = 'post-publish-calendar'; @@ -152,10 +156,10 @@ class PublishPlugin extends ServerPlugin // Breaking the event chain return false; - case '{' . self::NS_CALENDARSERVER . '}unpublish-calendar' : + case '{'.self::NS_CALENDARSERVER.'}unpublish-calendar' : // We can only deal with IShareableCalendar objects - if (!$node instanceof IShareableCalendar) { + if (!$node instanceof Calendar) { return; } $this->server->transactionType = 'post-unpublish-calendar'; @@ -180,8 +184,5 @@ class PublishPlugin extends ServerPlugin return false; } - - - } } diff --git a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php index 597652d0ef..008b5df912 100644 --- a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php +++ b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php @@ -13,11 +13,18 @@ class Publisher implements XmlSerializable { */ protected $publishUrl; + /** + * @var $isPublished + */ + protected $isPublished; + /** * @param str $publishUrl + * @param boolean $isPublished */ - function __construct($publishUrl) { + function __construct($publishUrl, $isPublished) { $this->publishUrl = $publishUrl; + $this->isPublished = $isPublished; } /** @@ -49,7 +56,11 @@ class Publisher implements XmlSerializable { function xmlSerialize(Writer $writer) { $cs = '{' . Plugin::NS_CALENDARSERVER . '}'; - $writer->write($this->publishUrl); + if (!$this->isPublished) { + $writer->write($this->publishUrl); + } else { + $writer->writeElement('{DAV:}href', $this->publishUrl); + } } } From 981c38f6d91be5a6de0ad319028afc3a4e931a2e Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 6 Jul 2016 12:42:32 +0200 Subject: [PATCH 03/44] Remove unnecessary implementation --- apps/dav/lib/CalDAV/Calendar.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index f5607c6527..6a811149e2 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -24,14 +24,13 @@ namespace OCA\DAV\CalDAV; use OCA\DAV\DAV\Sharing\IShareable; -use Sabre\CalDAV\IShareableCalendar; use OCP\IL10N; use Sabre\CalDAV\Backend\BackendInterface; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\PropPatch; -class Calendar extends \Sabre\CalDAV\Calendar implements IShareable, IShareableCalendar { +class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n) { parent::__construct($caldavBackend, $calendarInfo); From 1652a74febd10e56ec15fc90c93350fb48c796c4 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 6 Jul 2016 15:09:27 +0200 Subject: [PATCH 04/44] Fix publish-url property & getPublishStatus() fct --- apps/dav/lib/CalDAV/CalDavBackend.php | 9 +++++--- .../lib/CalDAV/Publishing/PublishPlugin.php | 21 +++++++++---------- .../lib/CalDAV/Publishing/Xml/Publisher.php | 4 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 43466b235e..8c65125110 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1501,13 +1501,16 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription */ public function getPublishStatus($calendar) { $query = $this->db->getQueryBuilder(); - $result = $query->select(['principaluri', 'access']) + $result = $query->select('count(id)') ->from('dav_shares') ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) - ->andWhere($query->expr()->eq('type', $query->createNamedParameter(self::CLASSIFICATION_PUBLIC))) + ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))) ->execute(); - return count($result->fetch()) > 0; + $row = $result->fetch(); + $result->closeCursor(); + + return $row; } /** diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index b1c4262420..f0be2f3a1b 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -72,19 +72,18 @@ class PublishPlugin extends ServerPlugin public function propFind(PropFind $propFind, INode $node) { if ($node instanceof Calendar) { - $token = md5(\OC::$server->getConfig()->getSystemValue('secret', '').$node->getName()); + $token = md5(\OC::$server->getConfig()->getSystemValue('secret', '').$node->getName()); + $publishUrl = $this->server->getBaseUri() . 'public-calendars/' . $token; - $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $token) { - if ($node->getPublishStatus()) { - return new Publisher($token, $node->getPublishStatus()); - } - }); + $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { + if ($node->getPublishStatus()) { + return new Publisher($publishUrl, $node->getPublishStatus()); + } + }); - $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $token) { - if ($node->getPublishStatus()) { - return new Publisher($token, false); - } - }); + $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) { + return new Publisher($publishUrl, false); + }); } } diff --git a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php index 008b5df912..6a0d8b2ec0 100644 --- a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php +++ b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php @@ -57,9 +57,9 @@ class Publisher implements XmlSerializable { $cs = '{' . Plugin::NS_CALENDARSERVER . '}'; if (!$this->isPublished) { - $writer->write($this->publishUrl); + $writer->write($this->publishUrl); // for pre-publish-url } else { - $writer->writeElement('{DAV:}href', $this->publishUrl); + $writer->writeElement('{DAV:}href', $this->publishUrl); // for publish-url } } From 4a0e6e2ad013fc6d7e43c0662438e94d6a8a7995 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 7 Jul 2016 09:39:57 +0200 Subject: [PATCH 05/44] Remove unnecessary line --- apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php index 6a0d8b2ec0..4926d3abf9 100644 --- a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php +++ b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php @@ -54,8 +54,6 @@ class Publisher implements XmlSerializable { * @return void */ function xmlSerialize(Writer $writer) { - - $cs = '{' . Plugin::NS_CALENDARSERVER . '}'; if (!$this->isPublished) { $writer->write($this->publishUrl); // for pre-publish-url } else { From f89961ddba9c8c34fb76b2c26ad2dd64762f431f Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 7 Jul 2016 09:45:01 +0200 Subject: [PATCH 06/44] Fix annotations --- apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php index 4926d3abf9..45a7fe0257 100644 --- a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php +++ b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php @@ -9,17 +9,17 @@ use Sabre\Xml\XmlSerializable; class Publisher implements XmlSerializable { /** - * @var $publishUrl + * @var string $publishUrl */ protected $publishUrl; /** - * @var $isPublished + * @var boolean $isPublished */ protected $isPublished; /** - * @param str $publishUrl + * @param string $publishUrl * @param boolean $isPublished */ function __construct($publishUrl, $isPublished) { @@ -28,7 +28,7 @@ class Publisher implements XmlSerializable { } /** - * @return str + * @return string */ function getValue() { return $this->publishUrl; From 72f35f8862f92cefb0e4dc8fb0b4f75f0270690a Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 7 Jul 2016 09:46:50 +0200 Subject: [PATCH 07/44] Use ressource ID instead of name --- apps/dav/lib/CalDAV/Publishing/PublishPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index f0be2f3a1b..67e04d7a8b 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -72,7 +72,7 @@ class PublishPlugin extends ServerPlugin public function propFind(PropFind $propFind, INode $node) { if ($node instanceof Calendar) { - $token = md5(\OC::$server->getConfig()->getSystemValue('secret', '').$node->getName()); + $token = md5(\OC::$server->getConfig()->getSystemValue('secret', '').$node->getResourceId()); $publishUrl = $this->server->getBaseUri() . 'public-calendars/' . $token; $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { From 7e5a82b968b2c40576e6bbc051022a6699ff9092 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 7 Jul 2016 10:16:56 +0200 Subject: [PATCH 08/44] Use urlgenerator to generate an absolute url And pass Config the correct way too --- .../lib/CalDAV/Publishing/PublishPlugin.php | 39 +++++++++++++++---- apps/dav/lib/Server.php | 5 ++- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 67e04d7a8b..c12071e367 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -2,8 +2,6 @@ namespace OCA\DAV\CalDAV\Publishing; -//use OCA\DAV\CalDAV\Publishing\Xml; - use Sabre\DAV\PropFind; use Sabre\DAV\INode; use Sabre\DAV\Server; @@ -12,10 +10,11 @@ use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; use OCA\DAV\CalDAV\Publishing\Xml\Publisher; use OCA\DAV\CalDAV\Calendar; +use OCP\IURLGenerator; +use OCP\IConfig; class PublishPlugin extends ServerPlugin { - const NS_OWNCLOUD = 'http://owncloud.org/ns'; const NS_CALENDARSERVER = 'http://calendarserver.org/ns/'; /** @@ -25,6 +24,31 @@ class PublishPlugin extends ServerPlugin */ protected $server; + /** + * Config instance to get instance secret. + * + * @var OCP\IConfig + */ + protected $config; + + /** + * URL Generator for absolute URLs. + * + * @var OCP\IURLGenerator + */ + protected $urlGenerator; + + /** + * PublishPlugin constructor. + * + * @param IURLGenerator $urlGenerator + */ + public function __construct(IConfig $config, IURLGenerator $urlGenerator) + { + $this->config = $config; + $this->urlGenerator = $urlGenerator; + } + /** * This method should return a list of server-features. * @@ -72,16 +96,17 @@ class PublishPlugin extends ServerPlugin public function propFind(PropFind $propFind, INode $node) { if ($node instanceof Calendar) { - $token = md5(\OC::$server->getConfig()->getSystemValue('secret', '').$node->getResourceId()); - $publishUrl = $this->server->getBaseUri() . 'public-calendars/' . $token; + $token = md5($this->config->getSystemValue('secret', '').$node->getResourceId()); - $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { + $publishUrl = $this->urlGenerator->getAbsoluteURL($this->server->getBaseUri().'public-calendars/').$token; + + $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { if ($node->getPublishStatus()) { return new Publisher($publishUrl, $node->getPublishStatus()); } }); - $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) { + $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) { return new Publisher($publishUrl, false); }); } diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index defaddbd64..a344885fd2 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -114,7 +114,10 @@ class Server { $this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin()); $this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin()); $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest())); - $this->server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin()); + $this->server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin( + \OC::$server->getConfig(), + \OC::$server->getUrlGenerator() + )); // addressbook plugins $this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin()); From bd0aae8636b846cb43a844838ae42d4203dc693a Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 7 Jul 2016 10:19:00 +0200 Subject: [PATCH 09/44] No need to call database twice --- apps/dav/lib/CalDAV/Publishing/PublishPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index c12071e367..704f026323 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -102,7 +102,7 @@ class PublishPlugin extends ServerPlugin $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { if ($node->getPublishStatus()) { - return new Publisher($publishUrl, $node->getPublishStatus()); + return new Publisher($publishUrl, true); } }); From 8da2100e7d5cc7819624a803e10b18f53ccacd9d Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 7 Jul 2016 16:28:30 +0200 Subject: [PATCH 10/44] Start work on returning CalDAV published calendars --- apps/dav/lib/CalDAV/CalDavBackend.php | 28 +++++++++++++++ .../lib/CalDAV/Publishing/PublishPlugin.php | 34 +++++++++++++++++-- apps/dav/lib/Connector/Sabre/FilesPlugin.php | 4 +++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 8c65125110..b1d85e0980 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1513,6 +1513,34 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription return $row; } + /** + * @param string $token + * @param string secret + * @return int | boolean + * + * Function to get the ressource we're insteressed in. Most probably to put somewhere else. + */ + public function getResourceIdFromToken($token, $secret) { + $query = $this->db->getQueryBuilder(); + $result = $query->select('resourceid') + ->from('dav_shares') + ->where($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))) + ->execute(); + + $publications = []; + while($row = $result->fetch()) { + $publications[] = $row['resourceid']; + } + + $i = 0; + $found = false; + while ($i < count($publications) && !$found) { + $found = md5($secret.$publications[$i]) === $token; + if (!$found) $i++; + } + return ($found) ? $publications[$i] : false; + } + /** * @param int $resourceId * @param array $acl diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 704f026323..f1f3540d68 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -59,7 +59,7 @@ class PublishPlugin extends ServerPlugin */ public function getFeatures() { - return ['oc-calendar-publishing']; + return ['oc-calendar-publishing']; // May have to be changed to be detected } /** @@ -91,6 +91,7 @@ class PublishPlugin extends ServerPlugin $this->server->on('method:POST', [$this, 'httpPost']); $this->server->on('propFind', [$this, 'propFind']); + $this->server->on('method:GET', [$this, 'httpGet'], 90); // 90 because it needs to be called before auth } public function propFind(PropFind $propFind, INode $node) @@ -102,12 +103,12 @@ class PublishPlugin extends ServerPlugin $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { if ($node->getPublishStatus()) { - return new Publisher($publishUrl, true); + return new Publisher($publishUrl, true); // We return the publish-url only if the calendar is published. } }); $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) { - return new Publisher($publishUrl, false); + return new Publisher($publishUrl, false); // The pre-publish-url is always returned }); } } @@ -209,4 +210,31 @@ class PublishPlugin extends ServerPlugin } } + + /** + * We intercept the GET requests to provide our shared calendars. + * + * @param Sabre\HTTP\RequestInterface $request + * @param Sabre\HTTP\ResponseInterface $response + */ + public function httpGet(RequestInterface $request, ResponseInterface $response) + { + $path = $request->getPath(); + + // TODO : Find a better way to do this + list($path, $token) = explode('/', $path); + if ($path !== 'public-calendars') { + return; + } + + // This is where the magic happens + // Find a place to put the functions getResourceIdFromToken($token) and getRessource($id) + + $this->server->transactionType = 'access-published-calendar'; + + $response->setStatus(200); + $response->setBody('Success !'); + + return false; + } } diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php index dd5f958ed4..7da49e1313 100644 --- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php @@ -244,6 +244,10 @@ class FilesPlugin extends ServerPlugin { * @param ResponseInterface $response */ function httpGet(RequestInterface $request, ResponseInterface $response) { + // Exclude published calendars + // TODO : Find a better way to do this + if (explode('/', $request->getPath())[0] === 'public-calendars') return; + // Only handle valid files $node = $this->tree->getNodeForPath($request->getPath()); if (!($node instanceof IFile)) return; From 90ab6e4fd9b25a8f031f812d46915e8413483be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 8 Jul 2016 16:13:34 +0200 Subject: [PATCH 11/44] Add new root collection public-calendars which holds all public calendars --- apps/dav/lib/CalDAV/CalDavBackend.php | 58 +++++++++++++++++++++ apps/dav/lib/CalDAV/PublicCalendarRoot.php | 60 ++++++++++++++++++++++ apps/dav/lib/RootCollection.php | 4 ++ 3 files changed, 122 insertions(+) create mode 100644 apps/dav/lib/CalDAV/PublicCalendarRoot.php diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index b1d85e0980..303e97fd30 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -118,6 +118,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** @var IUserManager */ private $userManager; + + /** @var \OCP\IConfig */ + private $config; /** * CalDavBackend constructor. @@ -131,6 +134,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $this->principalBackend = $principalBackend; $this->userManager = $userManager; $this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar'); + // TODO: inject + $this->config = \OC::$server->getConfig(); } /** @@ -283,6 +288,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription return array_values($calendars); } +<<<<<<< HEAD private function getUserDisplayName($uid) { if (!isset($this->userDisplayNames[$uid])) { $user = $this->userManager->get($uid); @@ -295,6 +301,58 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } return $this->userDisplayNames[$uid]; +======= + + public function getPublicCalendars() { + $fields = array_values($this->propertyMap); + $fields[] = 'a.id'; + $fields[] = 'a.uri'; + $fields[] = 'a.synctoken'; + $fields[] = 'a.components'; + $fields[] = 'a.principaluri'; + $fields[] = 'a.transparent'; + $fields[] = 's.access'; + $calendars = []; + $query = $this->db->getQueryBuilder(); + $result = $query->select($fields) + ->from('dav_shares', 's') + ->join('s', 'calendars', 'a', $query->expr()->eq('s.resourceid', 'a.id')) + ->where($query->expr()->in('s.access', $query->createNamedParameter(self::ACCESS_PUBLIC))) + ->andWhere($query->expr()->eq('s.type', $query->createNamedParameter('calendar'))) + ->execute(); + + while($row = $result->fetch()) { + list(, $name) = URLUtil::splitPath($row['principaluri']); + $row['displayname'] = $row['displayname'] . "($name)"; + $components = []; + if ($row['components']) { + $components = explode(',',$row['components']); + } + $uri = md5($this->config->getSystemValue('secret', '') . $row['id']); + $calendar = [ + 'id' => $row['id'], + 'uri' => $uri, + 'principaluri' => $row['principaluri'], + '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'), + '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', + '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), + '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $row['principaluri'], + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ, + ]; + + foreach($this->propertyMap as $xmlName=>$dbName) { + $calendar[$xmlName] = $row[$dbName]; + } + + if (!isset($calendars[$calendar['id']])) { + $calendars[$calendar['id']] = $calendar; + } + } + $result->closeCursor(); + + return array_values($calendars); +>>>>>>> bf223b9... Add new root collection public-calendars which holds all public calendars } /** diff --git a/apps/dav/lib/CalDAV/PublicCalendarRoot.php b/apps/dav/lib/CalDAV/PublicCalendarRoot.php new file mode 100644 index 0000000000..f1ff23ac7e --- /dev/null +++ b/apps/dav/lib/CalDAV/PublicCalendarRoot.php @@ -0,0 +1,60 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OCA\DAV\CalDAV; + +use Sabre\DAV\Collection; + +class PublicCalendarRoot extends Collection { + + /** @var CalDavBackend */ + protected $caldavBackend; + + function __construct(CalDavBackend $caldavBackend) { + $this->caldavBackend = $caldavBackend; + } + + /** + * @inheritdoc + */ + function getName() { + return 'public-calendars'; + } + + function getChild($name) { + // TODO: for performance reason this needs to have a custom implementation + return parent::getChild($name); + } + + /** + * @inheritdoc + */ + function getChildren() { + $l10n = \OC::$server->getL10N('dav'); + $calendars = $this->caldavBackend->getPublicCalendars(); + $children = []; + foreach ($calendars as $calendar) { + // TODO: maybe implement a new class PublicCalendar ??? + $children[] = new Calendar($this->caldavBackend, $calendar, $l10n); + } + + return $children; + } +} diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index 974d08bc34..f7b9c7079a 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -26,6 +26,7 @@ namespace OCA\DAV; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\CalendarRoot; +use OCA\DAV\CalDAV\PublicCalendarRoot; use OCA\DAV\CardDAV\AddressBookRoot; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Connector\Sabre\Principal; @@ -62,6 +63,8 @@ class RootCollection extends SimpleCollection { $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, \OC::$server->getUserManager()); $calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users'); $calendarRoot->disableListing = $disableListing; + $publicCalendarRoot = new PublicCalendarRoot($caldavBackend); + $publicCalendarRoot->disableListing = $disableListing; $systemTagCollection = new SystemTag\SystemTagsByIdCollection( \OC::$server->getSystemTagManager(), @@ -101,6 +104,7 @@ class RootCollection extends SimpleCollection { $systemPrincipals]), $filesCollection, $calendarRoot, + $publicCalendarRoot, new SimpleCollection('addressbooks', [ $usersAddressBookRoot, $systemAddressBookRoot]), From e7085aab387c90f6b5a7f8352864cc0d04bb96d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 8 Jul 2016 16:52:20 +0200 Subject: [PATCH 12/44] Allow not-authenticated access to specific urls --- apps/dav/lib/CalDAV/CalDavBackend.php | 1 + apps/dav/lib/CalDAV/Calendar.php | 13 +++- apps/dav/lib/DAV/PublicAuth.php | 86 +++++++++++++++++++++ apps/dav/lib/DAV/SystemPrincipalBackend.php | 11 +++ apps/dav/lib/Server.php | 3 + 5 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 apps/dav/lib/DAV/PublicAuth.php diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 303e97fd30..a134cba348 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -339,6 +339,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $row['principaluri'], '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ, + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, ]; foreach($this->propertyMap as $xmlName=>$dbName) { diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index 6a811149e2..bda671dfa4 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -90,7 +90,7 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { } /** - * @return str + * @return string */ public function getPrincipalURI() { return $this->calendarInfo['principaluri']; @@ -124,6 +124,13 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { ]; } } + if ($this->isPublic()) { + $acl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => 'principals/system/public', + 'protected' => true, + ]; + } /** @var CalDavBackend $calDavBackend */ $calDavBackend = $this->caldavBackend; @@ -264,6 +271,10 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { return true; } + private function isPublic() { + return isset($this->calendarInfo['{http://owncloud.org/ns}public']); + } + private function isShared() { return isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']); } diff --git a/apps/dav/lib/DAV/PublicAuth.php b/apps/dav/lib/DAV/PublicAuth.php new file mode 100644 index 0000000000..65defe5883 --- /dev/null +++ b/apps/dav/lib/DAV/PublicAuth.php @@ -0,0 +1,86 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OCA\DAV\DAV; + +use Sabre\DAV\Auth\Backend\BackendInterface; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; + +class PublicAuth implements BackendInterface { + + /** @var string[] */ + private $publicURLs; + + /** + * @param string[] $publicURLs + */ + public function __construct() { + $this->publicURLs = [ + 'public-calendars/' + ]; + } + + /** + * When this method is called, the backend must check if authentication was + * successful. + * + * The returned value must be one of the following + * + * [true, "principals/username"] + * [false, "reason for failure"] + * + * If authentication was successful, it's expected that the authentication + * backend returns a so-called principal url. + * + * Examples of a principal url: + * + * principals/admin + * principals/user1 + * principals/users/joe + * principals/uid/123457 + * + * If you don't use WebDAV ACL (RFC3744) we recommend that you simply + * return a string such as: + * + * principals/users/[username] + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return array + */ + function check(RequestInterface $request, ResponseInterface $response) { + $url = $request->getPath(); + $matchingUrls = array_filter($this->publicURLs, function ($publicUrl) use ($url) { + return strpos($url, $publicUrl, 0) === 0; + }); + + if ($matchingUrls) { + return [true, "principals/system/public"]; + } + return [false, "No public access to this resource."]; + } + + /** + * @inheritdoc + */ + function challenge(RequestInterface $request, ResponseInterface $response) { + } +} diff --git a/apps/dav/lib/DAV/SystemPrincipalBackend.php b/apps/dav/lib/DAV/SystemPrincipalBackend.php index ba7e73f165..6a71909c6f 100644 --- a/apps/dav/lib/DAV/SystemPrincipalBackend.php +++ b/apps/dav/lib/DAV/SystemPrincipalBackend.php @@ -51,6 +51,10 @@ class SystemPrincipalBackend extends AbstractBackend { 'uri' => 'principals/system/system', '{DAV:}displayname' => 'system', ]; + $principals[] = [ + 'uri' => 'principals/system/public', + '{DAV:}displayname' => 'public', + ]; } return $principals; @@ -73,6 +77,13 @@ class SystemPrincipalBackend extends AbstractBackend { ]; return $principal; } + if ($path === 'principals/system/public') { + $principal = [ + 'uri' => 'principals/system/public', + '{DAV:}displayname' => 'public', + ]; + return $principal; + } return null; } diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index a344885fd2..d67417a10d 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -35,6 +35,7 @@ use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin; use OCA\DAV\Connector\Sabre\DavAclPlugin; use OCA\DAV\Connector\Sabre\DummyGetResponsePlugin; use OCA\DAV\Connector\Sabre\FilesPlugin; +use OCA\DAV\DAV\PublicAuth; use OCA\DAV\Files\BrowserErrorPagePlugin; use OCA\DAV\Files\CustomPropertiesBackend; use OCP\IRequest; @@ -78,6 +79,8 @@ class Server { $this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig())); $authPlugin = new Plugin(); + $authPlugin->addBackend($authBackend); + $authPlugin->addBackend(new PublicAuth()); $this->server->addPlugin($authPlugin); // allow setup of additional auth backends From 00dc157b19834cfe558bc25a105cc509f47d7ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Mon, 11 Jul 2016 14:26:09 +0200 Subject: [PATCH 13/44] Fix requests for browser plugin as well as for the public calendar root folder --- .../lib/CalDAV/Publishing/PublishPlugin.php | 28 ------------------- apps/dav/lib/DAV/PublicAuth.php | 24 ++++++++++++---- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index f1f3540d68..1d45aef5a2 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -91,7 +91,6 @@ class PublishPlugin extends ServerPlugin $this->server->on('method:POST', [$this, 'httpPost']); $this->server->on('propFind', [$this, 'propFind']); - $this->server->on('method:GET', [$this, 'httpGet'], 90); // 90 because it needs to be called before auth } public function propFind(PropFind $propFind, INode $node) @@ -210,31 +209,4 @@ class PublishPlugin extends ServerPlugin } } - - /** - * We intercept the GET requests to provide our shared calendars. - * - * @param Sabre\HTTP\RequestInterface $request - * @param Sabre\HTTP\ResponseInterface $response - */ - public function httpGet(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - // TODO : Find a better way to do this - list($path, $token) = explode('/', $path); - if ($path !== 'public-calendars') { - return; - } - - // This is where the magic happens - // Find a place to put the functions getResourceIdFromToken($token) and getRessource($id) - - $this->server->transactionType = 'access-published-calendar'; - - $response->setStatus(200); - $response->setBody('Success !'); - - return false; - } } diff --git a/apps/dav/lib/DAV/PublicAuth.php b/apps/dav/lib/DAV/PublicAuth.php index 65defe5883..41fab614c3 100644 --- a/apps/dav/lib/DAV/PublicAuth.php +++ b/apps/dav/lib/DAV/PublicAuth.php @@ -34,7 +34,7 @@ class PublicAuth implements BackendInterface { */ public function __construct() { $this->publicURLs = [ - 'public-calendars/' + 'public-calendars' ]; } @@ -67,12 +67,8 @@ class PublicAuth implements BackendInterface { * @return array */ function check(RequestInterface $request, ResponseInterface $response) { - $url = $request->getPath(); - $matchingUrls = array_filter($this->publicURLs, function ($publicUrl) use ($url) { - return strpos($url, $publicUrl, 0) === 0; - }); - if ($matchingUrls) { + if ($this->isRequestPublic($request)) { return [true, "principals/system/public"]; } return [false, "No public access to this resource."]; @@ -83,4 +79,20 @@ class PublicAuth implements BackendInterface { */ function challenge(RequestInterface $request, ResponseInterface $response) { } + + /** + * @param RequestInterface $request + * @return array + */ + private function isRequestPublic(RequestInterface $request) { + $params = $request->getQueryParameters(); + if (isset($params['sabreAction']) && $params['sabreAction'] == 'asset') { + return true; + } + $url = $request->getPath(); + $matchingUrls = array_filter($this->publicURLs, function ($publicUrl) use ($url) { + return strpos($url, $publicUrl, 0) === 0; + }); + return $matchingUrls; + } } From 994001c4804f214a340922467a8ea96ec96a227e Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 11 Jul 2016 16:10:25 +0200 Subject: [PATCH 14/44] Dirty hack to disable dav plugins on public calendar urls --- .../lib/CalDAV/Publishing/PublishPlugin.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 1d45aef5a2..109e115855 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -91,6 +91,7 @@ class PublishPlugin extends ServerPlugin $this->server->on('method:POST', [$this, 'httpPost']); $this->server->on('propFind', [$this, 'propFind']); + $this->server->on('method:OPTIONS', [$this, 'httpOptions'], 5); } public function propFind(PropFind $propFind, INode $node) @@ -209,4 +210,23 @@ class PublishPlugin extends ServerPlugin } } + + public function httpOptions(RequestInterface $request, ResponseInterface $response) { + if ($request->getPath() == 'public-calendars') { + $methods = $this->server->getAllowedMethods($request->getPath()); + + $response->setHeader('Allow', strtoupper(implode(', ', $methods))); + $features = ['1', '3', 'extended-mkcol']; + + $response->setHeader('DAV', implode(', ', $features)); + $response->setHeader('MS-Author-Via', 'DAV'); + $response->setHeader('Accept-Ranges', 'bytes'); + $response->setHeader('Content-Length', '0'); + $response->setStatus(200); + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + } + } } From aca305332ad3fdd2a10cb94c1a952eb1e2720a10 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 12 Jul 2016 14:18:11 +0200 Subject: [PATCH 15/44] Fix DB call for MySQL databases --- apps/dav/lib/CalDAV/CalDavBackend.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index a134cba348..62f5213e34 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1560,7 +1560,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription */ public function getPublishStatus($calendar) { $query = $this->db->getQueryBuilder(); - $result = $query->select('count(id)') + $result = $query->select($query->createFunction('COUNT(*)')) ->from('dav_shares') ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))) From 2df69ec7f4b049807901cff0f650b9debca76965 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 12 Jul 2016 16:19:21 +0200 Subject: [PATCH 16/44] correct get published status and minor fixes --- apps/dav/lib/CalDAV/CalDavBackend.php | 30 +------------------ .../lib/CalDAV/Publishing/PublishPlugin.php | 13 ++++---- 2 files changed, 8 insertions(+), 35 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 62f5213e34..276aa20dd6 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1569,37 +1569,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row = $result->fetch(); $result->closeCursor(); - return $row; + return $row[0] > 0; } - /** - * @param string $token - * @param string secret - * @return int | boolean - * - * Function to get the ressource we're insteressed in. Most probably to put somewhere else. - */ - public function getResourceIdFromToken($token, $secret) { - $query = $this->db->getQueryBuilder(); - $result = $query->select('resourceid') - ->from('dav_shares') - ->where($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))) - ->execute(); - - $publications = []; - while($row = $result->fetch()) { - $publications[] = $row['resourceid']; - } - - $i = 0; - $found = false; - while ($i < count($publications) && !$found) { - $found = md5($secret.$publications[$i]) === $token; - if (!$found) $i++; - } - return ($found) ? $publications[$i] : false; - } - /** * @param int $resourceId * @param array $acl diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 109e115855..938510f1cc 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -6,6 +6,7 @@ use Sabre\DAV\PropFind; use Sabre\DAV\INode; use Sabre\DAV\Server; use Sabre\DAV\ServerPlugin; +use Sabre\DAV\Exception\NotFound; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; use OCA\DAV\CalDAV\Publishing\Xml\Publisher; @@ -102,14 +103,14 @@ class PublishPlugin extends ServerPlugin $publishUrl = $this->urlGenerator->getAbsoluteURL($this->server->getBaseUri().'public-calendars/').$token; $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { - if ($node->getPublishStatus()) { - return new Publisher($publishUrl, true); // We return the publish-url only if the calendar is published. - } - }); + if ($node->getPublishStatus()) { + return new Publisher($publishUrl, true); // We return the publish-url only if the calendar is published. + } + }); $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) { return new Publisher($publishUrl, false); // The pre-publish-url is always returned - }); + }); } } @@ -134,7 +135,7 @@ class PublishPlugin extends ServerPlugin // Making sure the node exists try { $node = $this->server->tree->getNodeForPath($path); - } catch (DAV\Exception\NotFound $e) { + } catch (NotFound $e) { return; } From f09c46d166f11149a5e778a6d69877a6b871b7a3 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 12 Jul 2016 16:35:27 +0200 Subject: [PATCH 17/44] Fix some tests --- apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php | 4 ++-- apps/dav/tests/unit/DAV/SystemPrincipalBackendTest.php | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php index e2d63868af..07a55fef63 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php @@ -471,7 +471,7 @@ class FilesPluginTest extends TestCase { $node = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Node') ->disableOriginalConstructor() ->getMock(); - $node->expects($this->once()) + $node->expects($this->at(0)) ->method('getFileInfo') ->willReturn($fileInfoFolderATestTXT); @@ -545,7 +545,7 @@ class FilesPluginTest extends TestCase { ->getMock(); $request - ->expects($this->once()) + ->expects($this->at(1)) ->method('getPath') ->will($this->returnValue('test/somefile.xml')); diff --git a/apps/dav/tests/unit/DAV/SystemPrincipalBackendTest.php b/apps/dav/tests/unit/DAV/SystemPrincipalBackendTest.php index 3a5566e8f7..71bdfb3b2b 100644 --- a/apps/dav/tests/unit/DAV/SystemPrincipalBackendTest.php +++ b/apps/dav/tests/unit/DAV/SystemPrincipalBackendTest.php @@ -45,7 +45,12 @@ class SystemPrincipalBackendTest extends TestCase { [[[ 'uri' => 'principals/system/system', '{DAV:}displayname' => 'system', - ]], 'principals/system'], + ], + [ + 'uri' => 'principals/system/public', + '{DAV:}displayname' => 'public', + ] + ], 'principals/system'], ]; } From aadb56dfcceda6981eedcedb2182a101a8b8a43a Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 18 Jul 2016 15:38:16 +0200 Subject: [PATCH 18/44] Fix wrong way to get publish status --- apps/dav/lib/CalDAV/CalDavBackend.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 276aa20dd6..7075ccc460 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1568,8 +1568,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row = $result->fetch(); $result->closeCursor(); - - return $row[0] > 0; + return reset($row) > 0; } /** From e783d01da7b5209a4d3bfdb255573b4fc7fbe73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 19 Jul 2016 08:31:41 +0200 Subject: [PATCH 19/44] Allow public access to the principals/system/public --- apps/dav/lib/DAV/PublicAuth.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/dav/lib/DAV/PublicAuth.php b/apps/dav/lib/DAV/PublicAuth.php index 41fab614c3..3f5d37f1a6 100644 --- a/apps/dav/lib/DAV/PublicAuth.php +++ b/apps/dav/lib/DAV/PublicAuth.php @@ -34,7 +34,8 @@ class PublicAuth implements BackendInterface { */ public function __construct() { $this->publicURLs = [ - 'public-calendars' + 'public-calendars', + 'principals/system/public' ]; } @@ -82,7 +83,7 @@ class PublicAuth implements BackendInterface { /** * @param RequestInterface $request - * @return array + * @return bool */ private function isRequestPublic(RequestInterface $request) { $params = $request->getQueryParameters(); @@ -93,6 +94,6 @@ class PublicAuth implements BackendInterface { $matchingUrls = array_filter($this->publicURLs, function ($publicUrl) use ($url) { return strpos($url, $publicUrl, 0) === 0; }); - return $matchingUrls; + return !empty($matchingUrls); } } From d0ec6b9c15bcae0226fb46ab99d70897b0b96c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 19 Jul 2016 08:34:12 +0200 Subject: [PATCH 20/44] Disable OPTIONS handling - done by sabre --- apps/dav/lib/CalDAV/Publishing/PublishPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 938510f1cc..4e82d166fc 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -92,7 +92,7 @@ class PublishPlugin extends ServerPlugin $this->server->on('method:POST', [$this, 'httpPost']); $this->server->on('propFind', [$this, 'propFind']); - $this->server->on('method:OPTIONS', [$this, 'httpOptions'], 5); +// $this->server->on('method:OPTIONS', [$this, 'httpOptions'], 5); } public function propFind(PropFind $propFind, INode $node) From 77216e7ca97e763ab12d30c471d0a73b44faeeba Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 20 Jul 2016 14:08:45 +0200 Subject: [PATCH 21/44] a few tests --- .../tests/unit/CalDAV/CalDavBackendTest.php | 18 +++++ .../unit/CalDAV/Publishing/PublishingTest.php | 71 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php diff --git a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php index 1a5673161d..a597b47633 100644 --- a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php @@ -334,6 +334,24 @@ EOD; $this->assertEquals($event, $changes['added'][0]); } + public function testPublications() { + $this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', []); + + $calendarInfo = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER)[0]; + + $l10n = $this->getMockBuilder('\OCP\IL10N') + ->disableOriginalConstructor()->getMock(); + + $calendar = new Calendar($this->backend, $calendarInfo, $l10n); + $this->backend->setPublishStatus(true, $calendar); + $this->assertEquals(true, $this->backend->getPublishStatus($calendar)); + + $publicCalendars = $this->backend->getPublicCalendars(); + $this->assertEquals(1, count($publicCalendars)); + $this->assertEquals(true, $publicCalendars[0]['{http://owncloud.org/ns}public']); + + } + public function testSubscriptions() { $id = $this->backend->createSubscription(self::UNIT_TEST_USER, 'Subscription', [ '{http://calendarserver.org/ns/}source' => new Href('test-source'), diff --git a/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php new file mode 100644 index 0000000000..00e4f04930 --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php @@ -0,0 +1,71 @@ +getMockBuilder('OCA\DAV\DAV\PublicAuth')->disableOriginalConstructor()->getMock(); + $authBackend->method('isDavAuthenticated')->willReturn(true); + + /** @var IRequest $request */ + $request = $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(); + $this->plugin = new PublishPlugin($authBackend, $request); + + $root = new SimpleCollection('calendars'); + $this->server = new Server($root); + /** @var SimpleCollection $node */ + $this->book = $this->getMockBuilder('OCA\DAV\CalDAV\Calendar')-> + disableOriginalConstructor()-> + getMock(); + $this->book->method('getName')->willReturn('cal1'); + $root->addChild($this->book); + $this->plugin->initialize($this->server); + } + + public function testPublishing() { + + $this->book->expects($this->once())->method('setPublishStatus')->with(true); + + // setup request + $request = new Request(); + $request->addHeader('Content-Type', 'application/xml'); + $request->setUrl('cal1'); + $request->setBody(''); + $response = new Response(); + $this->plugin->httpPost($request, $response); + } + + public function testUnPublishing() { + + $this->book->expects($this->once())->method('setPublishStatus')->with(true); + + // setup request + $request = new Request(); + $request->addHeader('Content-Type', 'application/xml'); + $request->setUrl('cal1'); + $request->setBody(''); + $response = new Response(); + $this->plugin->httpPost($request, $response); + } +} From de5e21269462957894e62b677d389862bb647d09 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 20 Jul 2016 14:26:24 +0200 Subject: [PATCH 22/44] fix plugin test --- .../unit/CalDAV/Publishing/PublishingTest.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php index 00e4f04930..43345a3488 100644 --- a/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php +++ b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php @@ -6,6 +6,8 @@ use OCA\DAV\CalDAV\Calendar; use OCA\DAV\CalDAV\Publishing\PublishPlugin; use OCA\DAV\Connector\Sabre\Auth; use OCP\IRequest; +use OCP\IURLGenerator; +use OCP\IConfig; use Sabre\DAV\Server; use Sabre\DAV\SimpleCollection; use Sabre\HTTP\Request; @@ -14,12 +16,16 @@ use Test\TestCase; class PluginTest extends TestCase { - /** @var Plugin */ + /** @var PublishPlugin */ private $plugin; /** @var Server */ private $server; /** @var Calendar | \PHPUnit_Framework_MockObject_MockObject */ private $book; + /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */ + private $config; + /** @var IURLGenerator | \PHPUnit_Framework_MockObject_MockObject */ + private $urlGenerator; public function setUp() { parent::setUp(); @@ -28,9 +34,15 @@ class PluginTest extends TestCase { $authBackend = $this->getMockBuilder('OCA\DAV\DAV\PublicAuth')->disableOriginalConstructor()->getMock(); $authBackend->method('isDavAuthenticated')->willReturn(true); + $this->config = $this->getMock('\OCP\IConfig'); + $this->config->expects($this->any())->method('getSystemValue') + ->with($this->equalTo('secret')) + ->willReturn('mysecret'); + + $this->urlGenerator = $this->getMock('OCP\IURLGenerator'); + /** @var IRequest $request */ - $request = $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(); - $this->plugin = new PublishPlugin($authBackend, $request); + $this->plugin = new PublishPlugin($this->config, $this->urlGenerator); $root = new SimpleCollection('calendars'); $this->server = new Server($root); From ebf23778f5a71b421021165627738e6e7ed5216f Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 20 Jul 2016 16:08:21 +0200 Subject: [PATCH 23/44] fix unpublishing test --- apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php index 43345a3488..b3ff36fc4e 100644 --- a/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php +++ b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php @@ -70,7 +70,7 @@ class PluginTest extends TestCase { public function testUnPublishing() { - $this->book->expects($this->once())->method('setPublishStatus')->with(true); + $this->book->expects($this->once())->method('setPublishStatus')->with(false); // setup request $request = new Request(); From 3921385ed3994c26674ec31606a41899fa8648ee Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 31 Jul 2016 20:18:35 +0200 Subject: [PATCH 24/44] fix things (indentation, tests, comments, backend custom implementation --- apps/dav/appinfo/v1/caldav.php | 3 +- apps/dav/lib/AppInfo/Application.php | 83 +++++++- apps/dav/lib/CalDAV/CalDavBackend.php | 49 ++--- apps/dav/lib/CalDAV/PublicCalendarRoot.php | 20 +- .../lib/CalDAV/Publishing/PublishPlugin.php | 199 ++++++++---------- .../lib/CalDAV/Publishing/Xml/Publisher.php | 99 ++++----- apps/dav/lib/Command/CreateCalendar.php | 4 +- apps/dav/lib/Connector/Sabre/FilesPlugin.php | 4 - apps/dav/lib/RootCollection.php | 2 +- .../unit/CalDAV/AbstractCalDavBackendTest.php | 3 +- .../unit/CalDAV/Publishing/PublishingTest.php | 17 +- .../unit/Connector/Sabre/FilesPluginTest.php | 4 +- 12 files changed, 281 insertions(+), 206 deletions(-) diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index 13b4d3119c..d9606f20b7 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -46,7 +46,8 @@ $principalBackend = new Principal( 'principals/' ); $db = \OC::$server->getDatabaseConnection(); -$calDavBackend = new CalDavBackend($db, $principalBackend, \OC::$server->getUserManager()); +$config = \OC::$server->getConfig(); +$calDavBackend = new CalDavBackend($db, $principalBackend, \OC::$server->getUserManager(), $config); $debugging = \OC::$server->getConfig()->getSystemValue('debug', false); diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php index dc3ce7e8bb..8bc43da564 100644 --- a/apps/dav/lib/AppInfo/Application.php +++ b/apps/dav/lib/AppInfo/Application.php @@ -37,8 +37,87 @@ class Application extends App { /** * Application constructor. */ - public function __construct() { - parent::__construct('dav'); + public function __construct (array $urlParams=array()) { + parent::__construct('dav', $urlParams); + + $container = $this->getContainer(); + $container->registerService('ContactsManager', function($c) { + /** @var IAppContainer $c */ + return new ContactsManager( + $c->query('CardDavBackend') + ); + }); + + $container->registerService('HookManager', function($c) { + /** @var IAppContainer $c */ + return new HookManager( + $c->getServer()->getUserManager(), + $c->query('SyncService'), + $c->query('CalDavBackend'), + $c->query('CardDavBackend') + ); + }); + + $container->registerService('SyncService', function($c) { + /** @var IAppContainer $c */ + return new SyncService( + $c->query('CardDavBackend'), + $c->getServer()->getUserManager(), + $c->getServer()->getLogger() + ); + }); + + $container->registerService('CardDavBackend', function($c) { + /** @var IAppContainer $c */ + $db = $c->getServer()->getDatabaseConnection(); + $dispatcher = $c->getServer()->getEventDispatcher(); + $principal = new Principal( + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager() + ); + return new CardDavBackend($db, $principal, $c->getServer()->getUserManager(), $dispatcher); + }); + + $container->registerService('CalDavBackend', function($c) { + /** @var IAppContainer $c */ + $db = $c->getServer()->getDatabaseConnection(); + $config = $c->getServer()->getConfig(); + $principal = new Principal( + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager() + ); + return new CalDavBackend($db, $principal, $c->getServer()->getUserManager(), $config); + }); + + $container->registerService('BirthdayService', function($c) { + /** @var IAppContainer $c */ + $g = new GroupPrincipalBackend( + $c->getServer()->getGroupManager() + ); + return new BirthdayService( + $c->query('CalDavBackend'), + $c->query('CardDavBackend'), + $g + ); + }); + + $container->registerService('OCA\DAV\Migration\Classification', function ($c) { + /** @var IAppContainer $c */ + return new Classification( + $c->query('CalDavBackend'), + $c->getServer()->getUserManager() + ); + }); + + $container->registerService('OCA\DAV\Migration\GenerateBirthdays', function ($c) { + /** @var IAppContainer $c */ + /** @var BirthdayService $b */ + $b = $c->query('BirthdayService'); + return new GenerateBirthdays( + $b, + $c->getServer()->getUserManager() + ); + }); } /** diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 7075ccc460..cdab20f541 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -29,6 +29,7 @@ use OCA\DAV\DAV\Sharing\IShareable; use OCP\DB\QueryBuilder\IQueryBuilder; use OCA\DAV\Connector\Sabre\Principal; use OCA\DAV\DAV\Sharing\Backend; +use OCP\IConfig; use OCP\IDBConnection; use OCP\IUser; use OCP\IUserManager; @@ -119,7 +120,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** @var IUserManager */ private $userManager; - /** @var \OCP\IConfig */ + /** @var IConfig */ private $config; /** @@ -128,14 +129,14 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @param IDBConnection $db * @param Principal $principalBackend * @param IUserManager $userManager + * @param IConfig $config */ - public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager) { + public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager, IConfig $config) { $this->db = $db; $this->principalBackend = $principalBackend; $this->userManager = $userManager; $this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar'); - // TODO: inject - $this->config = \OC::$server->getConfig(); + $this->config = $config; } /** @@ -1533,26 +1534,26 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } /** - * @param boolean $value - * @param \OCA\DAV\CalDAV\Calendar $calendar - */ - public function setPublishStatus($value, $calendar) { - $query = $this->db->getQueryBuilder(); - if ($value) { - $query->insert('dav_shares') - ->values([ - 'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()), - 'type' => $query->createNamedParameter('calendar'), - 'access' => $query->createNamedParameter(self::ACCESS_PUBLIC), - 'resourceid' => $query->createNamedParameter($calendar->getResourceId()) - ]); - } else { - $query->delete('dav_shares') - ->Where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) - ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))); - } - $query->execute(); - } + * @param boolean $value + * @param \OCA\DAV\CalDAV\Calendar $calendar + */ + public function setPublishStatus($value, $calendar) { + $query = $this->db->getQueryBuilder(); + if ($value) { + $query->insert('dav_shares') + ->values([ + 'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()), + 'type' => $query->createNamedParameter('calendar'), + 'access' => $query->createNamedParameter(self::ACCESS_PUBLIC), + 'resourceid' => $query->createNamedParameter($calendar->getResourceId()) + ]); + } else { + $query->delete('dav_shares') + ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) + ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))); + } + $query->execute(); + } /** * @param \OCA\DAV\CalDAV\Calendar $calendar diff --git a/apps/dav/lib/CalDAV/PublicCalendarRoot.php b/apps/dav/lib/CalDAV/PublicCalendarRoot.php index f1ff23ac7e..797074f7e5 100644 --- a/apps/dav/lib/CalDAV/PublicCalendarRoot.php +++ b/apps/dav/lib/CalDAV/PublicCalendarRoot.php @@ -21,14 +21,19 @@ namespace OCA\DAV\CalDAV; use Sabre\DAV\Collection; +use Sabre\DAV\Exception\NotFound; class PublicCalendarRoot extends Collection { /** @var CalDavBackend */ protected $caldavBackend; + /** @var \OCP\IL10N */ + protected $l10n; + function __construct(CalDavBackend $caldavBackend) { $this->caldavBackend = $caldavBackend; + $this->l10n = \OC::$server->getL10N('dav'); } /** @@ -38,21 +43,28 @@ class PublicCalendarRoot extends Collection { return 'public-calendars'; } + /** + * @inheritdoc + */ function getChild($name) { - // TODO: for performance reason this needs to have a custom implementation - return parent::getChild($name); + foreach ($this->caldavBackend->getPublicCalendars() as $calendar) { + if ($calendar['uri'] === $name) { + // TODO: maybe implement a new class PublicCalendar ??? + return new Calendar($this->caldavBackend, $calendar, $this->l10n); + } + } + throw new NotFound('Node with name \'' . $name . '\' could not be found'); } /** * @inheritdoc */ function getChildren() { - $l10n = \OC::$server->getL10N('dav'); $calendars = $this->caldavBackend->getPublicCalendars(); $children = []; foreach ($calendars as $calendar) { // TODO: maybe implement a new class PublicCalendar ??? - $children[] = new Calendar($this->caldavBackend, $calendar, $l10n); + $children[] = new Calendar($this->caldavBackend, $calendar, $this->l10n); } return $children; diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 4e82d166fc..e0bcfb7ef6 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -16,9 +16,9 @@ use OCP\IConfig; class PublishPlugin extends ServerPlugin { - const NS_CALENDARSERVER = 'http://calendarserver.org/ns/'; + const NS_CALENDARSERVER = 'http://calendarserver.org/ns/'; - /** + /** * Reference to SabreDAV server object. * * @var \Sabre\DAV\Server @@ -28,29 +28,30 @@ class PublishPlugin extends ServerPlugin /** * Config instance to get instance secret. * - * @var OCP\IConfig + * @var IConfig */ protected $config; /** * URL Generator for absolute URLs. * - * @var OCP\IURLGenerator + * @var IURLGenerator */ protected $urlGenerator; - /** - * PublishPlugin constructor. - * - * @param IURLGenerator $urlGenerator - */ + /** + * PublishPlugin constructor. + * + * @param IConfig $config + * @param IURLGenerator $urlGenerator + */ public function __construct(IConfig $config, IURLGenerator $urlGenerator) { $this->config = $config; $this->urlGenerator = $urlGenerator; } - /** + /** * This method should return a list of server-features. * * This is for example 'versioning' and is added to the DAV: header @@ -58,7 +59,7 @@ class PublishPlugin extends ServerPlugin * * @return string[] */ - public function getFeatures() + public function getFeatures() { return ['oc-calendar-publishing']; // May have to be changed to be detected } @@ -92,10 +93,9 @@ class PublishPlugin extends ServerPlugin $this->server->on('method:POST', [$this, 'httpPost']); $this->server->on('propFind', [$this, 'propFind']); -// $this->server->on('method:OPTIONS', [$this, 'httpOptions'], 5); } - public function propFind(PropFind $propFind, INode $node) + public function propFind(PropFind $propFind, INode $node) { if ($node instanceof Calendar) { $token = md5($this->config->getSystemValue('secret', '').$node->getResourceId()); @@ -104,130 +104,113 @@ class PublishPlugin extends ServerPlugin $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { if ($node->getPublishStatus()) { - return new Publisher($publishUrl, true); // We return the publish-url only if the calendar is published. + // We return the publish-url only if the calendar is published. + return new Publisher($publishUrl, true); } }); $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) { - return new Publisher($publishUrl, false); // The pre-publish-url is always returned + // The pre-publish-url is always returned + return new Publisher($publishUrl, false); }); } } - /** - * We intercept this to handle POST requests on calendars. - * - * @param RequestInterface $request - * @param ResponseInterface $response - * - * @return null|bool - */ - public function httpPost(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); + /** + * We intercept this to handle POST requests on calendars. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * + * @return null|bool + */ + public function httpPost(RequestInterface $request, ResponseInterface $response) + { + $path = $request->getPath(); - // Only handling xml - $contentType = $request->getHeader('Content-Type'); - if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) { - return; - } + // Only handling xml + $contentType = $request->getHeader('Content-Type'); + if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) { + return; + } - // Making sure the node exists - try { - $node = $this->server->tree->getNodeForPath($path); - } catch (NotFound $e) { - return; - } + // Making sure the node exists + try { + $node = $this->server->tree->getNodeForPath($path); + } catch (NotFound $e) { + return; + } - $requestBody = $request->getBodyAsString(); + $requestBody = $request->getBodyAsString(); - // If this request handler could not deal with this POST request, it - // will return 'null' and other plugins get a chance to handle the - // request. - // - // However, we already requested the full body. This is a problem, - // because a body can only be read once. This is why we preemptively - // re-populated the request body with the existing data. - $request->setBody($requestBody); + // If this request handler could not deal with this POST request, it + // will return 'null' and other plugins get a chance to handle the + // request. + // + // However, we already requested the full body. This is a problem, + // because a body can only be read once. This is why we preemptively + // re-populated the request body with the existing data. + $request->setBody($requestBody); - $message = $this->server->xml->parse($requestBody, $request->getUrl(), $documentType); + $this->server->xml->parse($requestBody, $request->getUrl(), $documentType); - switch ($documentType) { + switch ($documentType) { - case '{'.self::NS_CALENDARSERVER.'}publish-calendar' : + case '{'.self::NS_CALENDARSERVER.'}publish-calendar' : - // We can only deal with IShareableCalendar objects - if (!$node instanceof Calendar) { - return; - } - $this->server->transactionType = 'post-publish-calendar'; + // We can only deal with IShareableCalendar objects + if (!$node instanceof Calendar) { + return; + } + $this->server->transactionType = 'post-publish-calendar'; - // Getting ACL info - $acl = $this->server->getPlugin('acl'); + // Getting ACL info + $acl = $this->server->getPlugin('acl'); - // If there's no ACL support, we allow everything - if ($acl) { - $acl->checkPrivileges($path, '{DAV:}write'); - } + // If there's no ACL support, we allow everything + if ($acl) { + $acl->checkPrivileges($path, '{DAV:}write'); + } - $node->setPublishStatus(true); + $node->setPublishStatus(true); - // iCloud sends back the 202, so we will too. - $response->setStatus(202); + // iCloud sends back the 202, so we will too. + $response->setStatus(202); - // 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'); + // 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; + // Breaking the event chain + return false; - case '{'.self::NS_CALENDARSERVER.'}unpublish-calendar' : + case '{'.self::NS_CALENDARSERVER.'}unpublish-calendar' : - // We can only deal with IShareableCalendar objects - if (!$node instanceof Calendar) { - return; - } - $this->server->transactionType = 'post-unpublish-calendar'; + // We can only deal with IShareableCalendar objects + if (!$node instanceof Calendar) { + return; + } + $this->server->transactionType = 'post-unpublish-calendar'; - // Getting ACL info - $acl = $this->server->getPlugin('acl'); + // Getting ACL info + $acl = $this->server->getPlugin('acl'); - // If there's no ACL support, we allow everything - if ($acl) { - $acl->checkPrivileges($path, '{DAV:}write'); - } + // If there's no ACL support, we allow everything + if ($acl) { + $acl->checkPrivileges($path, '{DAV:}write'); + } - $node->setPublishStatus(false); + $node->setPublishStatus(false); - $response->setStatus(200); + $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'); + // 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; + // Breaking the event chain + return false; - } - } - - public function httpOptions(RequestInterface $request, ResponseInterface $response) { - if ($request->getPath() == 'public-calendars') { - $methods = $this->server->getAllowedMethods($request->getPath()); - - $response->setHeader('Allow', strtoupper(implode(', ', $methods))); - $features = ['1', '3', 'extended-mkcol']; - - $response->setHeader('DAV', implode(', ', $features)); - $response->setHeader('MS-Author-Via', 'DAV'); - $response->setHeader('Accept-Ranges', 'bytes'); - $response->setHeader('Content-Length', '0'); - $response->setStatus(200); - - // Sending back false will interupt the event chain and tell the server - // we've handled this method. - return false; - } - } + } + } } diff --git a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php index 45a7fe0257..375954ffaf 100644 --- a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php +++ b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php @@ -8,57 +8,58 @@ use Sabre\Xml\XmlSerializable; class Publisher implements XmlSerializable { - /** - * @var string $publishUrl - */ - protected $publishUrl; + /** + * @var string $publishUrl + */ + protected $publishUrl; - /** - * @var boolean $isPublished - */ - protected $isPublished; + /** + * @var boolean $isPublished + */ + protected $isPublished; - /** - * @param string $publishUrl - * @param boolean $isPublished - */ - function __construct($publishUrl, $isPublished) { - $this->publishUrl = $publishUrl; - $this->isPublished = $isPublished; - } + /** + * @param string $publishUrl + * @param boolean $isPublished + */ + function __construct($publishUrl, $isPublished) { + $this->publishUrl = $publishUrl; + $this->isPublished = $isPublished; + } - /** - * @return string - */ - function getValue() { - return $this->publishUrl; - } + /** + * @return string + */ + function getValue() { + return $this->publishUrl; + } - /** - * The xmlSerialize metod is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializble should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - * - * @param Writer $writer - * @return void - */ - function xmlSerialize(Writer $writer) { - if (!$this->isPublished) { - $writer->write($this->publishUrl); // for pre-publish-url - } else { - $writer->writeElement('{DAV:}href', $this->publishUrl); // for publish-url - } - - } + /** + * The xmlSerialize metod is called during xml writing. + * + * Use the $writer argument to write its own xml serialization. + * + * An important note: do _not_ create a parent element. Any element + * implementing XmlSerializble should only ever write what's considered + * its 'inner xml'. + * + * The parent of the current element is responsible for writing a + * containing element. + * + * This allows serializers to be re-used for different element names. + * + * If you are opening new elements, you must also close them again. + * + * @param Writer $writer + * @return void + */ + function xmlSerialize(Writer $writer) { + if (!$this->isPublished) { + // for pre-publish-url + $writer->write($this->publishUrl); + } else { + // for publish-url + $writer->writeElement('{DAV:}href', $this->publishUrl); + } + } } diff --git a/apps/dav/lib/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php index 0bc6398250..54cb06db66 100644 --- a/apps/dav/lib/Command/CreateCalendar.php +++ b/apps/dav/lib/Command/CreateCalendar.php @@ -44,6 +44,7 @@ class CreateCalendar extends Command { /** * @param IUserManager $userManager + * @param IGroupManager $groupManager * @param IDBConnection $dbConnection */ function __construct(IUserManager $userManager, IGroupManager $groupManager, IDBConnection $dbConnection) { @@ -74,9 +75,10 @@ class CreateCalendar extends Command { $this->userManager, $this->groupManager ); + $config = \OC::$server->getConfig(); $name = $input->getArgument('name'); - $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager); + $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $config); $caldav->createCalendar("principals/users/$user", $name, []); } } diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php index 7da49e1313..dd5f958ed4 100644 --- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php @@ -244,10 +244,6 @@ class FilesPlugin extends ServerPlugin { * @param ResponseInterface $response */ function httpGet(RequestInterface $request, ResponseInterface $response) { - // Exclude published calendars - // TODO : Find a better way to do this - if (explode('/', $request->getPath())[0] === 'public-calendars') return; - // Only handle valid files $node = $this->tree->getNodeForPath($request->getPath()); if (!($node instanceof IFile)) return; diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index f7b9c7079a..f99d585021 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -60,7 +60,7 @@ class RootCollection extends SimpleCollection { $systemPrincipals->disableListing = $disableListing; $filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users'); $filesCollection->disableListing = $disableListing; - $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, \OC::$server->getUserManager()); + $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, \OC::$server->getUserManager(), $config); $calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users'); $calendarRoot->disableListing = $disableListing; $publicCalendarRoot = new PublicCalendarRoot($caldavBackend); diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php index 0e2e1b0ee5..ebdd4d9f94 100644 --- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php @@ -75,7 +75,8 @@ abstract class AbstractCalDavBackendTest extends TestCase { ->willReturn([self::UNIT_TEST_GROUP]); $db = \OC::$server->getDatabaseConnection(); - $this->backend = new CalDavBackend($db, $this->principal, $this->userManager); + $config = \OC::$server->getConfig(); + $this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $config); $this->tearDown(); } diff --git a/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php index b3ff36fc4e..69de507dac 100644 --- a/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php +++ b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php @@ -4,7 +4,6 @@ namespace OCA\DAV\Tests\unit\CalDAV\Publishing; use OCA\DAV\CalDAV\Calendar; use OCA\DAV\CalDAV\Publishing\PublishPlugin; -use OCA\DAV\Connector\Sabre\Auth; use OCP\IRequest; use OCP\IURLGenerator; use OCP\IConfig; @@ -30,16 +29,16 @@ class PluginTest extends TestCase { public function setUp() { parent::setUp(); - /** @var Auth | \PHPUnit_Framework_MockObject_MockObject $authBackend */ - $authBackend = $this->getMockBuilder('OCA\DAV\DAV\PublicAuth')->disableOriginalConstructor()->getMock(); - $authBackend->method('isDavAuthenticated')->willReturn(true); - - $this->config = $this->getMock('\OCP\IConfig'); + $this->config = $this->getMockBuilder('\OCP\IConfig')-> + disableOriginalConstructor()-> + getMock(); $this->config->expects($this->any())->method('getSystemValue') ->with($this->equalTo('secret')) ->willReturn('mysecret'); - $this->urlGenerator = $this->getMock('OCP\IURLGenerator'); + $this->urlGenerator = $this->getMockBuilder('OCP\IURLGenerator')-> + disableOriginalConstructor()-> + getMock(); /** @var IRequest $request */ $this->plugin = new PublishPlugin($this->config, $this->urlGenerator); @@ -48,8 +47,8 @@ class PluginTest extends TestCase { $this->server = new Server($root); /** @var SimpleCollection $node */ $this->book = $this->getMockBuilder('OCA\DAV\CalDAV\Calendar')-> - disableOriginalConstructor()-> - getMock(); + disableOriginalConstructor()-> + getMock(); $this->book->method('getName')->willReturn('cal1'); $root->addChild($this->book); $this->plugin->initialize($this->server); diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php index 07a55fef63..e2d63868af 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php @@ -471,7 +471,7 @@ class FilesPluginTest extends TestCase { $node = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Node') ->disableOriginalConstructor() ->getMock(); - $node->expects($this->at(0)) + $node->expects($this->once()) ->method('getFileInfo') ->willReturn($fileInfoFolderATestTXT); @@ -545,7 +545,7 @@ class FilesPluginTest extends TestCase { ->getMock(); $request - ->expects($this->at(1)) + ->expects($this->once()) ->method('getPath') ->will($this->returnValue('test/somefile.xml')); From 762726d988e12986b88e19766fb5b3a6c9fe6edc Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 1 Aug 2016 10:51:11 +0200 Subject: [PATCH 25/44] fix indent once and for all --- apps/dav/lib/CalDAV/CalDavBackend.php | 6 +- .../lib/CalDAV/Publishing/PublishPlugin.php | 149 +++++++++--------- 2 files changed, 78 insertions(+), 77 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index cdab20f541..e6a023bda6 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1534,9 +1534,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } /** - * @param boolean $value - * @param \OCA\DAV\CalDAV\Calendar $calendar - */ + * @param boolean $value + * @param \OCA\DAV\CalDAV\Calendar $calendar + */ public function setPublishStatus($value, $calendar) { $query = $this->db->getQueryBuilder(); if ($value) { diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index e0bcfb7ef6..99353253b0 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -19,25 +19,25 @@ class PublishPlugin extends ServerPlugin const NS_CALENDARSERVER = 'http://calendarserver.org/ns/'; /** - * Reference to SabreDAV server object. - * - * @var \Sabre\DAV\Server - */ - protected $server; + * Reference to SabreDAV server object. + * + * @var \Sabre\DAV\Server + */ + protected $server; - /** - * Config instance to get instance secret. - * - * @var IConfig - */ - protected $config; + /** + * Config instance to get instance secret. + * + * @var IConfig + */ + protected $config; - /** - * URL Generator for absolute URLs. - * - * @var IURLGenerator - */ - protected $urlGenerator; + /** + * URL Generator for absolute URLs. + * + * @var IURLGenerator + */ + protected $urlGenerator; /** * PublishPlugin constructor. @@ -45,76 +45,77 @@ class PublishPlugin extends ServerPlugin * @param IConfig $config * @param IURLGenerator $urlGenerator */ - public function __construct(IConfig $config, IURLGenerator $urlGenerator) - { - $this->config = $config; - $this->urlGenerator = $urlGenerator; - } + public function __construct(IConfig $config, IURLGenerator $urlGenerator) + { + $this->config = $config; + $this->urlGenerator = $urlGenerator; + } /** - * 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 string[] - */ + * 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 string[] + */ public function getFeatures() - { - return ['oc-calendar-publishing']; // May have to be changed to be detected - } + { + // May have to be changed to be detected + return ['oc-calendar-publishing']; + } - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using Sabre\DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'oc-calendar-publishing'; - } + /** + * Returns a plugin name. + * + * Using this name other plugins will be able to access other plugins + * using Sabre\DAV\Server::getPlugin + * + * @return string + */ + public function getPluginName() + { + return 'oc-calendar-publishing'; + } - /** - * 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 - */ - public function initialize(Server $server) - { - $this->server = $server; + /** + * 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 + */ + public function initialize(Server $server) + { + $this->server = $server; - $this->server->on('method:POST', [$this, 'httpPost']); - $this->server->on('propFind', [$this, 'propFind']); - } + $this->server->on('method:POST', [$this, 'httpPost']); + $this->server->on('propFind', [$this, 'propFind']); + } public function propFind(PropFind $propFind, INode $node) - { - if ($node instanceof Calendar) { - $token = md5($this->config->getSystemValue('secret', '').$node->getResourceId()); + { + if ($node instanceof Calendar) { + $token = md5($this->config->getSystemValue('secret', '').$node->getResourceId()); - $publishUrl = $this->urlGenerator->getAbsoluteURL($this->server->getBaseUri().'public-calendars/').$token; + $publishUrl = $this->urlGenerator->getAbsoluteURL($this->server->getBaseUri().'public-calendars/').$token; - $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { - if ($node->getPublishStatus()) { + $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { + if ($node->getPublishStatus()) { // We return the publish-url only if the calendar is published. - return new Publisher($publishUrl, true); - } - }); + return new Publisher($publishUrl, true); + } + }); - $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) { + $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) { // The pre-publish-url is always returned - return new Publisher($publishUrl, false); - }); - } - } + return new Publisher($publishUrl, false); + }); + } + } /** * We intercept this to handle POST requests on calendars. From 189911650958b2bdca8f733a8f891af373c96ae9 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 1 Aug 2016 15:07:22 +0200 Subject: [PATCH 26/44] move getPublicCalendar inside the caldav backend --- apps/dav/lib/CalDAV/CalDavBackend.php | 26 ++++++++++++++++++---- apps/dav/lib/CalDAV/PublicCalendarRoot.php | 8 +------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index e6a023bda6..1be8db160c 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -42,6 +42,7 @@ use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\DAV; use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\Exception\NotFound; use Sabre\DAV\PropPatch; use Sabre\HTTP\URLUtil; use Sabre\VObject\DateTimeParser; @@ -289,7 +290,6 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription return array_values($calendars); } -<<<<<<< HEAD private function getUserDisplayName($uid) { if (!isset($this->userDisplayNames[$uid])) { $user = $this->userManager->get($uid); @@ -302,8 +302,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } return $this->userDisplayNames[$uid]; -======= - + } + + /** + * @return array + */ public function getPublicCalendars() { $fields = array_values($this->propertyMap); $fields[] = 'a.id'; @@ -354,7 +357,22 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $result->closeCursor(); return array_values($calendars); ->>>>>>> bf223b9... Add new root collection public-calendars which holds all public calendars + } + + /** + * @param string $uri + * @return Calendar + * @throws NotFound + */ + public function getPublicCalendar($uri) { + $l10n = \OC::$server->getL10N('dav'); + foreach ($this->getPublicCalendars() as $calendar) { + if ($calendar['uri'] === $uri) { + // TODO: maybe implement a new class PublicCalendar ??? + return new Calendar($this, $calendar, $l10n); + } + } + throw new NotFound('Node with name \'' . $uri . '\' could not be found'); } /** diff --git a/apps/dav/lib/CalDAV/PublicCalendarRoot.php b/apps/dav/lib/CalDAV/PublicCalendarRoot.php index 797074f7e5..b8d209d707 100644 --- a/apps/dav/lib/CalDAV/PublicCalendarRoot.php +++ b/apps/dav/lib/CalDAV/PublicCalendarRoot.php @@ -47,13 +47,7 @@ class PublicCalendarRoot extends Collection { * @inheritdoc */ function getChild($name) { - foreach ($this->caldavBackend->getPublicCalendars() as $calendar) { - if ($calendar['uri'] === $name) { - // TODO: maybe implement a new class PublicCalendar ??? - return new Calendar($this->caldavBackend, $calendar, $this->l10n); - } - } - throw new NotFound('Node with name \'' . $name . '\' could not be found'); + return $this->caldavBackend->getPublicCalendar($name); } /** From dd248caa0984c6d932855aa39fd3025d6f553f82 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 1 Aug 2016 15:10:33 +0200 Subject: [PATCH 27/44] fix some bracket positions --- .../lib/CalDAV/Publishing/PublishPlugin.php | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 99353253b0..56bdc6b6a9 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -14,8 +14,7 @@ use OCA\DAV\CalDAV\Calendar; use OCP\IURLGenerator; use OCP\IConfig; -class PublishPlugin extends ServerPlugin -{ +class PublishPlugin extends ServerPlugin { const NS_CALENDARSERVER = 'http://calendarserver.org/ns/'; /** @@ -45,8 +44,7 @@ class PublishPlugin extends ServerPlugin * @param IConfig $config * @param IURLGenerator $urlGenerator */ - public function __construct(IConfig $config, IURLGenerator $urlGenerator) - { + public function __construct(IConfig $config, IURLGenerator $urlGenerator) { $this->config = $config; $this->urlGenerator = $urlGenerator; } @@ -59,8 +57,7 @@ class PublishPlugin extends ServerPlugin * * @return string[] */ - public function getFeatures() - { + public function getFeatures() { // May have to be changed to be detected return ['oc-calendar-publishing']; } @@ -73,8 +70,7 @@ class PublishPlugin extends ServerPlugin * * @return string */ - public function getPluginName() - { + public function getPluginName() { return 'oc-calendar-publishing'; } @@ -88,16 +84,14 @@ class PublishPlugin extends ServerPlugin * * @param Server $server */ - public function initialize(Server $server) - { + public function initialize(Server $server) { $this->server = $server; $this->server->on('method:POST', [$this, 'httpPost']); $this->server->on('propFind', [$this, 'propFind']); } - public function propFind(PropFind $propFind, INode $node) - { + public function propFind(PropFind $propFind, INode $node) { if ($node instanceof Calendar) { $token = md5($this->config->getSystemValue('secret', '').$node->getResourceId()); @@ -125,8 +119,7 @@ class PublishPlugin extends ServerPlugin * * @return null|bool */ - public function httpPost(RequestInterface $request, ResponseInterface $response) - { + public function httpPost(RequestInterface $request, ResponseInterface $response) { $path = $request->getPath(); // Only handling xml From 691b3ab448907664a7fac29d1e8e795e1c6cd012 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 1 Aug 2016 16:44:28 +0200 Subject: [PATCH 28/44] Add publicuri to oc_dav_shares table and start working with it --- apps/dav/appinfo/database.xml | 8 +++ apps/dav/appinfo/info.xml | 2 +- apps/dav/lib/CalDAV/CalDavBackend.php | 67 ++++++++++++++++++---- apps/dav/lib/CalDAV/PublicCalendarRoot.php | 3 +- 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/apps/dav/appinfo/database.xml b/apps/dav/appinfo/database.xml index 9578526a70..eb8f70e7c9 100644 --- a/apps/dav/appinfo/database.xml +++ b/apps/dav/appinfo/database.xml @@ -703,6 +703,11 @@ CREATE TABLE calendarobjects ( true true + + publicuri + text + 255 + dav_shares_index true @@ -715,6 +720,9 @@ CREATE TABLE calendarobjects ( type + + publicuri + diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index 19b65d8432..33621ce70a 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -5,7 +5,7 @@ WebDAV endpoint AGPL owncloud.org - 1.1.0 + 1.1.1 diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 1be8db160c..2daecc7249 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -316,6 +316,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $fields[] = 'a.principaluri'; $fields[] = 'a.transparent'; $fields[] = 's.access'; + $fields[] = 's.publicuri'; $calendars = []; $query = $this->db->getQueryBuilder(); $result = $query->select($fields) @@ -332,10 +333,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription if ($row['components']) { $components = explode(',',$row['components']); } - $uri = md5($this->config->getSystemValue('secret', '') . $row['id']); $calendar = [ 'id' => $row['id'], - 'uri' => $uri, + 'uri' => $row['publicuri'], 'principaluri' => $row['principaluri'], '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'), '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', @@ -361,18 +361,62 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** * @param string $uri - * @return Calendar + * @return array * @throws NotFound */ public function getPublicCalendar($uri) { - $l10n = \OC::$server->getL10N('dav'); - foreach ($this->getPublicCalendars() as $calendar) { - if ($calendar['uri'] === $uri) { - // TODO: maybe implement a new class PublicCalendar ??? - return new Calendar($this, $calendar, $l10n); - } + $fields = array_values($this->propertyMap); + $fields[] = 'a.id'; + $fields[] = 'a.uri'; + $fields[] = 'a.synctoken'; + $fields[] = 'a.components'; + $fields[] = 'a.principaluri'; + $fields[] = 'a.transparent'; + $fields[] = 's.access'; + $fields[] = 's.publicuri'; + $query = $this->db->getQueryBuilder(); + $result = $query->select($fields) + ->from('dav_shares', 's') + ->join('s', 'calendars', 'a', $query->expr()->eq('s.resourceid', 'a.id')) + ->where($query->expr()->in('s.access', $query->createNamedParameter(self::ACCESS_PUBLIC))) + ->andWhere($query->expr()->eq('s.type', $query->createNamedParameter('calendar'))) + ->andWhere($query->expr()->eq('s.publicuri', $query->createNamedParameter($uri))) + ->execute(); + + $row = $result->fetch(\PDO::FETCH_ASSOC); + + $result->closeCursor(); + + if ($row === false) { + throw new NotFound('Node with name \'' . $uri . '\' could not be found'); } - throw new NotFound('Node with name \'' . $uri . '\' could not be found'); + + list(, $name) = URLUtil::splitPath($row['principaluri']); + $row['displayname'] = $row['displayname'] . "($name)"; + $components = []; + if ($row['components']) { + $components = explode(',',$row['components']); + } + $uri = md5($this->config->getSystemValue('secret', '') . $row['id']); + $calendar = [ + 'id' => $row['id'], + 'uri' => $uri, + 'principaluri' => $row['principaluri'], + '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'), + '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', + '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), + '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $row['principaluri'], + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ, + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, + ]; + + foreach($this->propertyMap as $xmlName=>$dbName) { + $calendar[$xmlName] = $row[$dbName]; + } + + return array_values($calendar); + } /** @@ -1563,7 +1607,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription 'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()), 'type' => $query->createNamedParameter('calendar'), 'access' => $query->createNamedParameter(self::ACCESS_PUBLIC), - 'resourceid' => $query->createNamedParameter($calendar->getResourceId()) + 'resourceid' => $query->createNamedParameter($calendar->getResourceId()), + 'publicuri' => $query->createNamedParameter(md5($this->config->getSystemValue('secret', '') . $calendar->getResourceId())) ]); } else { $query->delete('dav_shares') diff --git a/apps/dav/lib/CalDAV/PublicCalendarRoot.php b/apps/dav/lib/CalDAV/PublicCalendarRoot.php index b8d209d707..6d74b97f96 100644 --- a/apps/dav/lib/CalDAV/PublicCalendarRoot.php +++ b/apps/dav/lib/CalDAV/PublicCalendarRoot.php @@ -47,7 +47,8 @@ class PublicCalendarRoot extends Collection { * @inheritdoc */ function getChild($name) { - return $this->caldavBackend->getPublicCalendar($name); + $calendar = $this->caldavBackend->getPublicCalendar($name); + return new Calendar($this->caldavBackend, $calendar, $this->l10n); } /** From 9af2a9ff4d6984145aed3d3fe1312eee56fa8b74 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 1 Aug 2016 17:16:30 +0200 Subject: [PATCH 29/44] test serializer --- .../unit/CalDAV/Publishing/PublisherTest.php | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.php diff --git a/apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.php b/apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.php new file mode 100644 index 0000000000..b6b1e4381b --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.php @@ -0,0 +1,56 @@ +write([ + '{' . self::NS_CALENDARSERVER . '}publish-url' => $publish, + ]); + + $this->assertEquals('urltopublish', $publish->getValue()); + + $this->assertXmlStringEqualsXmlString( + ' + + urltopublish + ', $xml); + } + + public function testSerializeNotPublished() { + $publish = new Publisher('urltopublish', false); + + $xml = $this->write([ + '{' . self::NS_CALENDARSERVER . '}pre-publish-url' => $publish, + ]); + + $this->assertEquals('urltopublish', $publish->getValue()); + + $this->assertXmlStringEqualsXmlString( + ' + urltopublish', $xml); + } + + + protected $elementMap = []; + protected $namespaceMap = ['DAV:' => 'd']; + protected $contextUri = '/'; + + private function write($input) { + $writer = new Writer(); + $writer->contextUri = $this->contextUri; + $writer->namespaceMap = $this->namespaceMap; + $writer->openMemory(); + $writer->setIndent(true); + $writer->write($input); + return $writer->outputMemory(); + } +} From 8433c3ca3105dc787f8aba49049373b8503a1a40 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 3 Aug 2016 11:09:45 +0200 Subject: [PATCH 30/44] fix getChild() --- apps/dav/lib/CalDAV/CalDavBackend.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 2daecc7249..e3b90a0069 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -415,7 +415,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $calendar[$xmlName] = $row[$dbName]; } - return array_values($calendar); + return $calendar; } From a4fe596a21697e6da4e6c87a8fa06e366050fb5b Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 11 Aug 2016 16:55:57 +0200 Subject: [PATCH 31/44] add space between calendarname and owner name --- apps/dav/lib/CalDAV/CalDavBackend.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index e3b90a0069..5f90340616 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -392,7 +392,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } list(, $name) = URLUtil::splitPath($row['principaluri']); - $row['displayname'] = $row['displayname'] . "($name)"; + $row['displayname'] = $row['displayname'] . ' ' . "($name)"; $components = []; if ($row['components']) { $components = explode(',',$row['components']); From f16ea48e96885e8bdff8fc66f6923232b32a407c Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 12 Aug 2016 10:25:26 +0200 Subject: [PATCH 32/44] add can-be-published property --- apps/dav/lib/CalDAV/Publishing/PublishPlugin.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 56bdc6b6a9..124901fd68 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -108,6 +108,10 @@ class PublishPlugin extends ServerPlugin { // The pre-publish-url is always returned return new Publisher($publishUrl, false); }); + + $propFind->handle('{'.self::NS_CALENDARSERVER.'}can-be-published', function() use ($node) { + return !$node->getPublishStatus(); + }); } } From f0421e1f75179a42e76973a4b11d8474ee571d08 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 14 Aug 2016 19:08:01 +0200 Subject: [PATCH 33/44] add missing tests --- .../unit/CalDAV/AbstractCalDavBackendTest.php | 6 +++++- apps/dav/tests/unit/CalDAV/CalDavBackendTest.php | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php index ebdd4d9f94..ca5000f3f4 100644 --- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php @@ -28,6 +28,7 @@ use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; use OCA\DAV\Connector\Sabre\Principal; use OCP\IL10N; +use OCP\IConfig; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\DAV\PropPatch; use Sabre\DAV\Xml\Property\Href; @@ -51,6 +52,9 @@ abstract class AbstractCalDavBackendTest extends TestCase { /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */ protected $userManager; + + /** var OCP\IConfig */ + protected $config; const UNIT_TEST_USER = 'principals/users/caldav-unit-test'; const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1'; @@ -75,7 +79,7 @@ abstract class AbstractCalDavBackendTest extends TestCase { ->willReturn([self::UNIT_TEST_GROUP]); $db = \OC::$server->getDatabaseConnection(); - $config = \OC::$server->getConfig(); + $this->config = \OC::$server->getConfig(); $this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $config); $this->tearDown(); diff --git a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php index a597b47633..0c07ed7c29 100644 --- a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php @@ -343,13 +343,24 @@ EOD; ->disableOriginalConstructor()->getMock(); $calendar = new Calendar($this->backend, $calendarInfo, $l10n); - $this->backend->setPublishStatus(true, $calendar); - $this->assertEquals(true, $this->backend->getPublishStatus($calendar)); + $calendar->setPublishStatus(true); + $this->assertEquals(true, $calendar->getPublishStatus()); $publicCalendars = $this->backend->getPublicCalendars(); $this->assertEquals(1, count($publicCalendars)); $this->assertEquals(true, $publicCalendars[0]['{http://owncloud.org/ns}public']); + $publicCalendarURI = md5($this->config->getSystemValue('secret', '') . $calendar->getResourceId()); + $publicCalendar = $this->backend->getPublicCalendar($publicCalendarURI); + $this->assertEquals(true, $publicCalendar['{http://owncloud.org/ns}public']); + + $calendar->setPublishStatus(false); + $this->assertEquals(false, $calendar->getPublishStatus()); + + $publicCalendarURI = md5($this->config->getSystemValue('secret', '') . $calendar->getResourceId()); + $this->setExpectedException('Sabre\DAV\Exception\NotFound'); + $publicCalendar = $this->backend->getPublicCalendar($publicCalendarURI); + } public function testSubscriptions() { From 6378dbca7e1559def51b9f80174f559174aeb2e8 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 14 Aug 2016 19:18:21 +0200 Subject: [PATCH 34/44] fix can-be-published --- apps/dav/lib/CalDAV/Calendar.php | 4 ++++ apps/dav/lib/CalDAV/Publishing/PublishPlugin.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index bda671dfa4..d6799d1827 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -279,4 +279,8 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { return isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']); } + public function isSubscription() { + return isset($this->calendarInfo['{http://calendarserver.org/ns/}source']); + } + } diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 124901fd68..1b89578e3c 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -110,7 +110,7 @@ class PublishPlugin extends ServerPlugin { }); $propFind->handle('{'.self::NS_CALENDARSERVER.'}can-be-published', function() use ($node) { - return !$node->getPublishStatus(); + return !$node->getPublishStatus() && !$node->isSubscription(); }); } } From ad0eeaaf1c9adfdb7875ea2e18ad11470228e284 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 15 Aug 2016 17:53:58 +0200 Subject: [PATCH 35/44] use AllowedSharingModes for can-be-published & can-be-shared --- apps/dav/lib/CalDAV/Publishing/PublishPlugin.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 1b89578e3c..79dc84b148 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -9,6 +9,7 @@ use Sabre\DAV\ServerPlugin; use Sabre\DAV\Exception\NotFound; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; +use Sabre\CalDAV\Xml\Property\AllowedSharingModes; use OCA\DAV\CalDAV\Publishing\Xml\Publisher; use OCA\DAV\CalDAV\Calendar; use OCP\IURLGenerator; @@ -109,8 +110,8 @@ class PublishPlugin extends ServerPlugin { return new Publisher($publishUrl, false); }); - $propFind->handle('{'.self::NS_CALENDARSERVER.'}can-be-published', function() use ($node) { - return !$node->getPublishStatus() && !$node->isSubscription(); + $propFind->handle('{'.self::NS_CALENDARSERVER.'}allowed-sharing-modes', function() use ($node) { + return new AllowedSharingModes(!$node->isSubscription(), !$node->isSubscription()); }); } } From 3e9a3462235cc3d69e54615c193e80a90001ae5a Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 16 Aug 2016 10:03:24 +0200 Subject: [PATCH 36/44] add calendarserver-sharing to the list of advertised features --- apps/dav/lib/CalDAV/Publishing/PublishPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 79dc84b148..7434da6b62 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -60,7 +60,7 @@ class PublishPlugin extends ServerPlugin { */ public function getFeatures() { // May have to be changed to be detected - return ['oc-calendar-publishing']; + return ['oc-calendar-publishing', 'calendarserver-sharing']; } /** From ff67cbc6af144c92d4b1e69d6c606c1fdbf177d4 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 18 Aug 2016 17:04:04 +0200 Subject: [PATCH 37/44] Add test for PublicCalendarRoot --- .../unit/CalDAV/PublicCalendarRootTest.php | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php diff --git a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php new file mode 100644 index 0000000000..9ce558ad34 --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php @@ -0,0 +1,103 @@ +getDatabaseConnection(); + $this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal') + ->disableOriginalConstructor() + ->getMock(); + $this->config = \OC::$server->getConfig(); + + $this->backend = new CalDavBackend($db, $this->principal, $this->config); + + $this->publicCalendarRoot = new PublicCalendarRoot($this->backend); + + $this->l10n = $this->getMockBuilder('\OCP\IL10N') + ->disableOriginalConstructor()->getMock(); + } + + public function testGetName() { + $name = $this->publicCalendarRoot->getName(); + $this->assertEquals('public-calendars', $name); + } + + public function testGetChild() { + + $calendar = $this->createPublicCalendar(); + + $publicCalendarURI = md5($this->config->getSystemValue('secret', '') . $calendar->getResourceId()); + + $calendarResult = $this->publicCalendarRoot->getChild($publicCalendarURI); + $this->assertEquals($calendar, $calendarResult); + } + + public function testGetChildren() { + + $publicCalendars = $this->backend->getPublicCalendars(); + + $calendarResults = $this->publicCalendarRoot->getChildren(); + + $this->assertEquals(1, count($calendarResults)); + $this->assertEquals(new Calendar($this->backend, $publicCalendars[0], $this->l10n), $calendarResults[0]); + + } + + /** + * @return Calendar + */ + protected function createPublicCalendar() { + $this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', []); + + $calendarInfo = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER)[0]; + + $calendarInfo['uri'] = md5($this->config->getSystemValue('secret', '') . $calendarInfo['id']); + list(, $name) = Uri\split($calendarInfo['principaluri']); + $calendarInfo['{DAV:}displayname'] = $calendarInfo['{DAV:}displayname'] . ' (' . $name . ')'; + $calendarInfo['{http://owncloud.org/ns}owner-principal'] = $calendarInfo['principaluri']; + $calendarInfo['{http://owncloud.org/ns}read-only'] = false; + $calendarInfo['{http://owncloud.org/ns}public'] = true; + + $calendar = new Calendar($this->backend, $calendarInfo, $this->l10n); + $calendar->setPublishStatus(true); + + return $calendar; + } + + +} From 2fff203c598e8f71ee0aea4265efe7f952864d06 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 30 Aug 2016 19:10:50 +0200 Subject: [PATCH 38/44] Add missing constructor argument --- apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php index ca5000f3f4..589c00c377 100644 --- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php @@ -79,8 +79,8 @@ abstract class AbstractCalDavBackendTest extends TestCase { ->willReturn([self::UNIT_TEST_GROUP]); $db = \OC::$server->getDatabaseConnection(); - $this->config = \OC::$server->getConfig(); - $this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $config); + $this->config = \OC::$server->getConfig(); + $this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->config); $this->tearDown(); } From 4659e3ab599f18069765cb2414a8ace8bdf30ca8 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 30 Aug 2016 19:21:32 +0200 Subject: [PATCH 39/44] Add new constructor args --- apps/dav/lib/CalDAV/CalDavBackend.php | 7 +++++-- .../unit/CalDAV/PublicCalendarRootTest.php | 18 +++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 5f90340616..0cdfcd6957 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -130,9 +130,12 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @param IDBConnection $db * @param Principal $principalBackend * @param IUserManager $userManager - * @param IConfig $config + * @param IConfig $config */ - public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager, IConfig $config) { + public function __construct(IDBConnection $db, + Principal $principalBackend, + IUserManager $userManager, + IConfig $config) { $this->db = $db; $this->principalBackend = $principalBackend; $this->userManager = $userManager; diff --git a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php index 9ce558ad34..85aad24d36 100644 --- a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php +++ b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php @@ -3,10 +3,12 @@ namespace OCA\DAV\Tests\unit\CalDAV; use OCA\DAV\CalDAV\Calendar; +use OCA\DAV\Connector\Sabre\Principal; use OCP\IL10N; use OCP\IConfig; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\PublicCalendarRoot; +use OCP\IUserManager; use Test\TestCase; use Sabre\Uri; @@ -29,12 +31,13 @@ class PublicCalendarRootTest extends TestCase { /** @var IL10N */ private $l10n; - + /** @var IUserManager */ + private $userManager; + /** @var Principal */ + private $principal; /** var IConfig */ protected $config; - private $principal; - public function setUp() { parent::setUp(); @@ -43,8 +46,14 @@ class PublicCalendarRootTest extends TestCase { ->disableOriginalConstructor() ->getMock(); $this->config = \OC::$server->getConfig(); + $this->userManager = $this->getMockBuilder('\OCP\IUserManager')->getMock(); - $this->backend = new CalDavBackend($db, $this->principal, $this->config); + $this->backend = new CalDavBackend( + $db, + $this->principal, + $this->userManager, + $this->config + ); $this->publicCalendarRoot = new PublicCalendarRoot($this->backend); @@ -99,5 +108,4 @@ class PublicCalendarRootTest extends TestCase { return $calendar; } - } From d884370844c7f807b10aa09e63cb814927011572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sat, 3 Sep 2016 10:52:05 +0200 Subject: [PATCH 40/44] Use true random string as uri for public calendars - as a result we can no longer return the pre-publish-url --- apps/dav/appinfo/v1/caldav.php | 4 +- apps/dav/lib/AppInfo/Application.php | 5 ++- apps/dav/lib/CalDAV/CalDavBackend.php | 26 +++++++---- apps/dav/lib/CalDAV/Calendar.php | 5 ++- .../lib/CalDAV/Publishing/PublishPlugin.php | 14 ++---- apps/dav/lib/Command/CreateCalendar.php | 3 +- apps/dav/lib/DAV/PublicAuth.php | 4 -- apps/dav/lib/RootCollection.php | 6 ++- .../unit/CalDAV/AbstractCalDavBackendTest.php | 8 +++- .../tests/unit/CalDAV/CalDavBackendTest.php | 2 +- .../unit/CalDAV/PublicCalendarRootTest.php | 45 ++++++++++++------- 11 files changed, 74 insertions(+), 48 deletions(-) diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index d9606f20b7..d18e93dd7a 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -47,7 +47,9 @@ $principalBackend = new Principal( ); $db = \OC::$server->getDatabaseConnection(); $config = \OC::$server->getConfig(); -$calDavBackend = new CalDavBackend($db, $principalBackend, \OC::$server->getUserManager(), $config); +$userManager = \OC::$server->getUserManager(); +$random = \OC::$server->getSecureRandom(); +$calDavBackend = new CalDavBackend($db, $principalBackend, $userManager, $config, $random); $debugging = \OC::$server->getConfig()->getSystemValue('debug', false); diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php index 8bc43da564..69a5e336bb 100644 --- a/apps/dav/lib/AppInfo/Application.php +++ b/apps/dav/lib/AppInfo/Application.php @@ -81,12 +81,15 @@ class Application extends App { $container->registerService('CalDavBackend', function($c) { /** @var IAppContainer $c */ $db = $c->getServer()->getDatabaseConnection(); + $userManager = $c->getServer()->getUserManager(); $config = $c->getServer()->getConfig(); + $random = $c->getServer()->getSecureRandom(); + $principal = new Principal( $c->getServer()->getUserManager(), $c->getServer()->getGroupManager() ); - return new CalDavBackend($db, $principal, $c->getServer()->getUserManager(), $config); + return new CalDavBackend($db, $principal, $userManager, $config, $random); }); $container->registerService('BirthdayService', function($c) { diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 0cdfcd6957..7b8c1be51f 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -33,6 +33,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\IUser; use OCP\IUserManager; +use OCP\Security\ISecureRandom; use Sabre\CalDAV\Backend\AbstractBackend; use Sabre\CalDAV\Backend\SchedulingSupport; use Sabre\CalDAV\Backend\SubscriptionSupport; @@ -124,6 +125,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** @var IConfig */ private $config; + /** @var ISecureRandom */ + private $random; + /** * CalDavBackend constructor. * @@ -131,16 +135,19 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @param Principal $principalBackend * @param IUserManager $userManager * @param IConfig $config + * @param ISecureRandom $random */ public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager, - IConfig $config) { + IConfig $config, + ISecureRandom $random) { $this->db = $db; $this->principalBackend = $principalBackend; $this->userManager = $userManager; $this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar'); $this->config = $config; + $this->random = $random; } /** @@ -400,10 +407,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription if ($row['components']) { $components = explode(',',$row['components']); } - $uri = md5($this->config->getSystemValue('secret', '') . $row['id']); $calendar = [ 'id' => $row['id'], - 'uri' => $uri, + 'uri' => $row['publicuri'], 'principaluri' => $row['principaluri'], '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'), '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', @@ -1601,24 +1607,28 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** * @param boolean $value * @param \OCA\DAV\CalDAV\Calendar $calendar + * @return string|null */ public function setPublishStatus($value, $calendar) { $query = $this->db->getQueryBuilder(); if ($value) { + $publicUri = $this->random->generate(16, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS); $query->insert('dav_shares') ->values([ 'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()), 'type' => $query->createNamedParameter('calendar'), 'access' => $query->createNamedParameter(self::ACCESS_PUBLIC), 'resourceid' => $query->createNamedParameter($calendar->getResourceId()), - 'publicuri' => $query->createNamedParameter(md5($this->config->getSystemValue('secret', '') . $calendar->getResourceId())) + 'publicuri' => $query->createNamedParameter($publicUri) ]); - } else { - $query->delete('dav_shares') - ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) - ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))); + $query->execute(); + return $publicUri; } + $query->delete('dav_shares') + ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) + ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))); $query->execute(); + return null; } /** diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index d6799d1827..5fe9be8957 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -252,9 +252,12 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { /** * @param boolean $value + * @return string|null */ function setPublishStatus($value) { - $this->caldavBackend->setPublishStatus($value, $this); + $publicUri = $this->caldavBackend->setPublishStatus($value, $this); + $this->calendarInfo['publicuri'] = $publicUri; + return $publicUri; } /** diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 7434da6b62..0e5377d30c 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -94,22 +94,16 @@ class PublishPlugin extends ServerPlugin { public function propFind(PropFind $propFind, INode $node) { if ($node instanceof Calendar) { - $token = md5($this->config->getSystemValue('secret', '').$node->getResourceId()); - - $publishUrl = $this->urlGenerator->getAbsoluteURL($this->server->getBaseUri().'public-calendars/').$token; - - $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) { + $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node) { if ($node->getPublishStatus()) { // We return the publish-url only if the calendar is published. + $token = $node->getName(); + $publishUrl = $this->urlGenerator->getAbsoluteURL($this->server->getBaseUri().'public-calendars/').$token; + return new Publisher($publishUrl, true); } }); - $propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) { - // The pre-publish-url is always returned - return new Publisher($publishUrl, false); - }); - $propFind->handle('{'.self::NS_CALENDARSERVER.'}allowed-sharing-modes', function() use ($node) { return new AllowedSharingModes(!$node->isSubscription(), !$node->isSubscription()); }); diff --git a/apps/dav/lib/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php index 54cb06db66..da1f706a8b 100644 --- a/apps/dav/lib/Command/CreateCalendar.php +++ b/apps/dav/lib/Command/CreateCalendar.php @@ -76,9 +76,10 @@ class CreateCalendar extends Command { $this->groupManager ); $config = \OC::$server->getConfig(); + $random = \OC::$server->getSecureRandom(); $name = $input->getArgument('name'); - $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $config); + $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $config, $random); $caldav->createCalendar("principals/users/$user", $name, []); } } diff --git a/apps/dav/lib/DAV/PublicAuth.php b/apps/dav/lib/DAV/PublicAuth.php index 3f5d37f1a6..33588fc0ad 100644 --- a/apps/dav/lib/DAV/PublicAuth.php +++ b/apps/dav/lib/DAV/PublicAuth.php @@ -86,10 +86,6 @@ class PublicAuth implements BackendInterface { * @return bool */ private function isRequestPublic(RequestInterface $request) { - $params = $request->getQueryParameters(); - if (isset($params['sabreAction']) && $params['sabreAction'] == 'asset') { - return true; - } $url = $request->getPath(); $matchingUrls = array_filter($this->publicURLs, function ($publicUrl) use ($url) { return strpos($url, $publicUrl, 0) === 0; diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index f99d585021..4c76dc30c3 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -39,10 +39,12 @@ class RootCollection extends SimpleCollection { public function __construct() { $config = \OC::$server->getConfig(); + $random = \OC::$server->getSecureRandom(); + $userManager = \OC::$server->getUserManager(); $db = \OC::$server->getDatabaseConnection(); $dispatcher = \OC::$server->getEventDispatcher(); $userPrincipalBackend = new Principal( - \OC::$server->getUserManager(), + $userManager, \OC::$server->getGroupManager() ); $groupPrincipalBackend = new GroupPrincipalBackend( @@ -60,7 +62,7 @@ class RootCollection extends SimpleCollection { $systemPrincipals->disableListing = $disableListing; $filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users'); $filesCollection->disableListing = $disableListing; - $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, \OC::$server->getUserManager(), $config); + $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $config, $random); $calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users'); $calendarRoot->disableListing = $disableListing; $publicCalendarRoot = new PublicCalendarRoot($caldavBackend); diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php index 589c00c377..2559ecbbf8 100644 --- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php @@ -29,6 +29,7 @@ use OCA\DAV\CalDAV\Calendar; use OCA\DAV\Connector\Sabre\Principal; use OCP\IL10N; use OCP\IConfig; +use OCP\Security\ISecureRandom; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\DAV\PropPatch; use Sabre\DAV\Xml\Property\Href; @@ -56,6 +57,9 @@ abstract class AbstractCalDavBackendTest extends TestCase { /** var OCP\IConfig */ protected $config; + /** @var ISecureRandom */ + private $random; + const UNIT_TEST_USER = 'principals/users/caldav-unit-test'; const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1'; const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group'; @@ -80,8 +84,8 @@ abstract class AbstractCalDavBackendTest extends TestCase { $db = \OC::$server->getDatabaseConnection(); $this->config = \OC::$server->getConfig(); - $this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->config); - + $this->random = \OC::$server->getSecureRandom(); + $this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->config, $this->random); $this->tearDown(); } diff --git a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php index 0c07ed7c29..6f846515d8 100644 --- a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php @@ -350,7 +350,7 @@ EOD; $this->assertEquals(1, count($publicCalendars)); $this->assertEquals(true, $publicCalendars[0]['{http://owncloud.org/ns}public']); - $publicCalendarURI = md5($this->config->getSystemValue('secret', '') . $calendar->getResourceId()); + $publicCalendarURI = $publicCalendars[0]['uri']; $publicCalendar = $this->backend->getPublicCalendar($publicCalendarURI); $this->assertEquals(true, $publicCalendar['{http://owncloud.org/ns}public']); diff --git a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php index 85aad24d36..6dfec6d7e1 100644 --- a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php +++ b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php @@ -5,12 +5,11 @@ namespace OCA\DAV\Tests\unit\CalDAV; use OCA\DAV\CalDAV\Calendar; use OCA\DAV\Connector\Sabre\Principal; use OCP\IL10N; -use OCP\IConfig; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\PublicCalendarRoot; use OCP\IUserManager; +use OCP\Security\ISecureRandom; use Test\TestCase; -use Sabre\Uri; /** * Class PublicCalendarRootTest @@ -22,13 +21,10 @@ use Sabre\Uri; class PublicCalendarRootTest extends TestCase { const UNIT_TEST_USER = 'principals/users/caldav-unit-test'; - /** @var CalDavBackend */ private $backend; - /** @var PublicCalendarRoot */ private $publicCalendarRoot; - /** @var IL10N */ private $l10n; /** @var IUserManager */ @@ -37,6 +33,8 @@ class PublicCalendarRootTest extends TestCase { private $principal; /** var IConfig */ protected $config; + /** @var ISecureRandom */ + private $random; public function setUp() { parent::setUp(); @@ -47,12 +45,14 @@ class PublicCalendarRootTest extends TestCase { ->getMock(); $this->config = \OC::$server->getConfig(); $this->userManager = $this->getMockBuilder('\OCP\IUserManager')->getMock(); + $this->random = \OC::$server->getSecureRandom(); $this->backend = new CalDavBackend( $db, $this->principal, $this->userManager, - $this->config + $this->config, + $this->random ); $this->publicCalendarRoot = new PublicCalendarRoot($this->backend); @@ -61,6 +61,18 @@ class PublicCalendarRootTest extends TestCase { ->disableOriginalConstructor()->getMock(); } + public function tearDown() { + parent::tearDown(); + + if (is_null($this->backend)) { + return; + } + $books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER); + foreach ($books as $book) { + $this->backend->deleteCalendar($book['id']); + } + } + public function testGetName() { $name = $this->publicCalendarRoot->getName(); $this->assertEquals('public-calendars', $name); @@ -70,13 +82,18 @@ class PublicCalendarRootTest extends TestCase { $calendar = $this->createPublicCalendar(); - $publicCalendarURI = md5($this->config->getSystemValue('secret', '') . $calendar->getResourceId()); + $publicCalendars = $this->backend->getPublicCalendars(); + $this->assertEquals(1, count($publicCalendars)); + $this->assertEquals(true, $publicCalendars[0]['{http://owncloud.org/ns}public']); + + $publicCalendarURI = $publicCalendars[0]['uri']; $calendarResult = $this->publicCalendarRoot->getChild($publicCalendarURI); $this->assertEquals($calendar, $calendarResult); } public function testGetChildren() { + $this->createPublicCalendar(); $publicCalendars = $this->backend->getPublicCalendars(); @@ -84,7 +101,6 @@ class PublicCalendarRootTest extends TestCase { $this->assertEquals(1, count($calendarResults)); $this->assertEquals(new Calendar($this->backend, $publicCalendars[0], $this->l10n), $calendarResults[0]); - } /** @@ -94,16 +110,11 @@ class PublicCalendarRootTest extends TestCase { $this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', []); $calendarInfo = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER)[0]; - - $calendarInfo['uri'] = md5($this->config->getSystemValue('secret', '') . $calendarInfo['id']); - list(, $name) = Uri\split($calendarInfo['principaluri']); - $calendarInfo['{DAV:}displayname'] = $calendarInfo['{DAV:}displayname'] . ' (' . $name . ')'; - $calendarInfo['{http://owncloud.org/ns}owner-principal'] = $calendarInfo['principaluri']; - $calendarInfo['{http://owncloud.org/ns}read-only'] = false; - $calendarInfo['{http://owncloud.org/ns}public'] = true; - $calendar = new Calendar($this->backend, $calendarInfo, $this->l10n); - $calendar->setPublishStatus(true); + $publicUri = $calendar->setPublishStatus(true); + + $calendarInfo = $this->backend->getPublicCalendar($publicUri); + $calendar = new Calendar($this->backend, $calendarInfo, $this->l10n); return $calendar; } From 83602225549d1df67403a333ed4a53e8a02d1619 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 14 Sep 2016 11:34:21 +0200 Subject: [PATCH 41/44] fix public calendars --- apps/dav/lib/CalDAV/CalDavBackend.php | 17 +++++++++++++++++ apps/dav/lib/CalDAV/Calendar.php | 4 ++++ .../dav/lib/CalDAV/Publishing/PublishPlugin.php | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 7b8c1be51f..34bc0b3c8b 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1648,6 +1648,23 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription return reset($row) > 0; } + /** + * @param \OCA\DAV\CalDAV\Calendar $calendar + * @return string + */ + public function getPublishToken($calendar) { + $query = $this->db->getQueryBuilder(); + $result = $query->select('publicuri') + ->from('dav_shares') + ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) + ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))) + ->execute(); + + $row = $result->fetch(); + $result->closeCursor(); + return reset($row); + } + /** * @param int $resourceId * @param array $acl diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index 5fe9be8957..17cc4780f7 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -267,6 +267,10 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { return $this->caldavBackend->getPublishStatus($this); } + function getPublishToken() { + return $this->caldavBackend->getPublishToken($this); + } + private function canWrite() { if (isset($this->calendarInfo['{http://owncloud.org/ns}read-only'])) { return !$this->calendarInfo['{http://owncloud.org/ns}read-only']; diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 0e5377d30c..aaa2868a86 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -97,7 +97,7 @@ class PublishPlugin extends ServerPlugin { $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node) { if ($node->getPublishStatus()) { // We return the publish-url only if the calendar is published. - $token = $node->getName(); + $token = $node->getPublishToken(); $publishUrl = $this->urlGenerator->getAbsoluteURL($this->server->getBaseUri().'public-calendars/').$token; return new Publisher($publishUrl, true); From 17d5dfdeb159bb940a1e3d45479ad2c5f99d8225 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 15 Sep 2016 17:01:35 +0200 Subject: [PATCH 42/44] add in same request --- apps/dav/lib/CalDAV/CalDavBackend.php | 21 ++----------------- apps/dav/lib/CalDAV/Calendar.php | 6 +----- .../lib/CalDAV/Publishing/PublishPlugin.php | 2 +- 3 files changed, 4 insertions(+), 25 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 34bc0b3c8b..440188c13c 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1633,26 +1633,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** * @param \OCA\DAV\CalDAV\Calendar $calendar - * @return boolean + * @return mixed */ public function getPublishStatus($calendar) { - $query = $this->db->getQueryBuilder(); - $result = $query->select($query->createFunction('COUNT(*)')) - ->from('dav_shares') - ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) - ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))) - ->execute(); - - $row = $result->fetch(); - $result->closeCursor(); - return reset($row) > 0; - } - - /** - * @param \OCA\DAV\CalDAV\Calendar $calendar - * @return string - */ - public function getPublishToken($calendar) { $query = $this->db->getQueryBuilder(); $result = $query->select('publicuri') ->from('dav_shares') @@ -1662,7 +1645,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row = $result->fetch(); $result->closeCursor(); - return reset($row); + return $row ? reset($row) : false; } /** diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index 17cc4780f7..3fbcd87acc 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -261,16 +261,12 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { } /** - * @return boolean $value + * @return mixed $value */ function getPublishStatus() { return $this->caldavBackend->getPublishStatus($this); } - function getPublishToken() { - return $this->caldavBackend->getPublishToken($this); - } - private function canWrite() { if (isset($this->calendarInfo['{http://owncloud.org/ns}read-only'])) { return !$this->calendarInfo['{http://owncloud.org/ns}read-only']; diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index aaa2868a86..241e5260c7 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -97,7 +97,7 @@ class PublishPlugin extends ServerPlugin { $propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node) { if ($node->getPublishStatus()) { // We return the publish-url only if the calendar is published. - $token = $node->getPublishToken(); + $token = $node->getPublishStatus(); $publishUrl = $this->urlGenerator->getAbsoluteURL($this->server->getBaseUri().'public-calendars/').$token; return new Publisher($publishUrl, true); From 9c75b00850f940993fc5f6e5bb52bccf58b43023 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 15 Sep 2016 17:09:24 +0200 Subject: [PATCH 43/44] fix tests --- apps/dav/tests/unit/CalDAV/CalDavBackendTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php index 6f846515d8..8349d98cd9 100644 --- a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php @@ -344,7 +344,7 @@ EOD; $calendar = new Calendar($this->backend, $calendarInfo, $l10n); $calendar->setPublishStatus(true); - $this->assertEquals(true, $calendar->getPublishStatus()); + $this->assertNotEquals(false, $calendar->getPublishStatus()); $publicCalendars = $this->backend->getPublicCalendars(); $this->assertEquals(1, count($publicCalendars)); From dcc23114e9328d822539782644bedcf5cba7e72d Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 23 Sep 2016 18:20:04 +0200 Subject: [PATCH 44/44] fix annotations & copyright headers --- apps/dav/lib/AppInfo/Application.php | 86 +------------------ .../lib/CalDAV/Publishing/PublishPlugin.php | 22 ++++- .../lib/CalDAV/Publishing/Xml/Publisher.php | 20 ++++- apps/dav/lib/DAV/PublicAuth.php | 3 - 4 files changed, 41 insertions(+), 90 deletions(-) diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php index 69a5e336bb..dc3ce7e8bb 100644 --- a/apps/dav/lib/AppInfo/Application.php +++ b/apps/dav/lib/AppInfo/Application.php @@ -37,90 +37,8 @@ class Application extends App { /** * Application constructor. */ - public function __construct (array $urlParams=array()) { - parent::__construct('dav', $urlParams); - - $container = $this->getContainer(); - $container->registerService('ContactsManager', function($c) { - /** @var IAppContainer $c */ - return new ContactsManager( - $c->query('CardDavBackend') - ); - }); - - $container->registerService('HookManager', function($c) { - /** @var IAppContainer $c */ - return new HookManager( - $c->getServer()->getUserManager(), - $c->query('SyncService'), - $c->query('CalDavBackend'), - $c->query('CardDavBackend') - ); - }); - - $container->registerService('SyncService', function($c) { - /** @var IAppContainer $c */ - return new SyncService( - $c->query('CardDavBackend'), - $c->getServer()->getUserManager(), - $c->getServer()->getLogger() - ); - }); - - $container->registerService('CardDavBackend', function($c) { - /** @var IAppContainer $c */ - $db = $c->getServer()->getDatabaseConnection(); - $dispatcher = $c->getServer()->getEventDispatcher(); - $principal = new Principal( - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager() - ); - return new CardDavBackend($db, $principal, $c->getServer()->getUserManager(), $dispatcher); - }); - - $container->registerService('CalDavBackend', function($c) { - /** @var IAppContainer $c */ - $db = $c->getServer()->getDatabaseConnection(); - $userManager = $c->getServer()->getUserManager(); - $config = $c->getServer()->getConfig(); - $random = $c->getServer()->getSecureRandom(); - - $principal = new Principal( - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager() - ); - return new CalDavBackend($db, $principal, $userManager, $config, $random); - }); - - $container->registerService('BirthdayService', function($c) { - /** @var IAppContainer $c */ - $g = new GroupPrincipalBackend( - $c->getServer()->getGroupManager() - ); - return new BirthdayService( - $c->query('CalDavBackend'), - $c->query('CardDavBackend'), - $g - ); - }); - - $container->registerService('OCA\DAV\Migration\Classification', function ($c) { - /** @var IAppContainer $c */ - return new Classification( - $c->query('CalDavBackend'), - $c->getServer()->getUserManager() - ); - }); - - $container->registerService('OCA\DAV\Migration\GenerateBirthdays', function ($c) { - /** @var IAppContainer $c */ - /** @var BirthdayService $b */ - $b = $c->query('BirthdayService'); - return new GenerateBirthdays( - $b, - $c->getServer()->getUserManager() - ); - }); + public function __construct() { + parent::__construct('dav'); } /** diff --git a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php index 241e5260c7..199bc67e61 100644 --- a/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php +++ b/apps/dav/lib/CalDAV/Publishing/PublishPlugin.php @@ -1,5 +1,23 @@ + * + * @copyright Copyright (c) 2016 Thomas Citharel + * @license GNU AGPL version 3 or any later version + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ namespace OCA\DAV\CalDAV\Publishing; use Sabre\DAV\PropFind; @@ -116,7 +134,7 @@ class PublishPlugin extends ServerPlugin { * @param RequestInterface $request * @param ResponseInterface $response * - * @return null|bool + * @return void|bool */ public function httpPost(RequestInterface $request, ResponseInterface $response) { $path = $request->getPath(); diff --git a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php index 375954ffaf..1fdba22e9e 100644 --- a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php +++ b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php @@ -1,5 +1,23 @@ + * + * @copyright Copyright (c) 2016 Thomas Citharel + * @license GNU AGPL version 3 or any later version + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ namespace OCA\DAV\CalDAV\Publishing\Xml; use OCA\DAV\CalDAV\Publishing\PublishPlugin as Plugin; diff --git a/apps/dav/lib/DAV/PublicAuth.php b/apps/dav/lib/DAV/PublicAuth.php index 33588fc0ad..ffc588c4a5 100644 --- a/apps/dav/lib/DAV/PublicAuth.php +++ b/apps/dav/lib/DAV/PublicAuth.php @@ -29,9 +29,6 @@ class PublicAuth implements BackendInterface { /** @var string[] */ private $publicURLs; - /** - * @param string[] $publicURLs - */ public function __construct() { $this->publicURLs = [ 'public-calendars',