committed by
Lukas Reschke
No known key found for this signature in database
GPG Key ID: B9F6980CF6E759B1
6 changed files with 304 additions and 1 deletions
-
1apps/dav/appinfo/v1/caldav.php
-
37apps/dav/lib/CalDAV/CalDavBackend.php
-
24apps/dav/lib/CalDAV/Calendar.php
-
187apps/dav/lib/CalDAV/Publishing/PublishPlugin.php
-
55apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php
-
1apps/dav/lib/Server.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; |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
} |
|||
@ -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); |
|||
|
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue