Browse Source

Proper work on Publishing

pull/1197/head
Thomas Citharel 10 years ago
committed by Lukas Reschke
parent
commit
69d3601dcb
No known key found for this signature in database GPG Key ID: B9F6980CF6E759B1
  1. 1
      apps/dav/appinfo/v1/caldav.php
  2. 37
      apps/dav/lib/CalDAV/CalDavBackend.php
  3. 24
      apps/dav/lib/CalDAV/Calendar.php
  4. 187
      apps/dav/lib/CalDAV/Publishing/PublishPlugin.php
  5. 55
      apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php
  6. 1
      apps/dav/lib/Server.php

1
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) {

37
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

24
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'];

187
apps/dav/lib/CalDAV/Publishing/PublishPlugin.php

@ -0,0 +1,187 @@
<?php
namespace OCA\DAV\CalDAV\Publishing;
//use OCA\DAV\CalDAV\Publishing\Xml;
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;
class PublishPlugin extends ServerPlugin
{
const NS_OWNCLOUD = 'http://owncloud.org/ns';
const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
/**
* Reference to SabreDAV server object.
*
* @var \Sabre\DAV\Server
*/
protected $server;
/**
* This method should return a list of server-features.
*
* This is for example 'versioning' and is added to the DAV: header
* in an OPTIONS response.
*
* @return string[]
*/
public function getFeatures()
{
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->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;
}
}
}

55
apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php

@ -0,0 +1,55 @@
<?php
namespace OCA\DAV\CalDAV\Publishing\Xml;
use OCA\DAV\CalDAV\Publishing\PublishPlugin as Plugin;
use Sabre\Xml\Writer;
use Sabre\Xml\XmlSerializable;
class Publisher implements XmlSerializable {
/**
* @var $publishUrl
*/
protected $publishUrl;
/**
* @param str $publishUrl
*/
function __construct($publishUrl) {
$this->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);
}
}

1
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());

Loading…
Cancel
Save