Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
69d3601
Proper work on Publishing
tcitworld Jul 6, 2016
5824c24
Make little corrections
tcitworld Jul 6, 2016
981c38f
Remove unnecessary implementation
tcitworld Jul 6, 2016
1652a74
Fix publish-url property & getPublishStatus() fct
tcitworld Jul 6, 2016
4a0e6e2
Remove unnecessary line
tcitworld Jul 7, 2016
f89961d
Fix annotations
tcitworld Jul 7, 2016
72f35f8
Use ressource ID instead of name
tcitworld Jul 7, 2016
7e5a82b
Use urlgenerator to generate an absolute url
tcitworld Jul 7, 2016
bd0aae8
No need to call database twice
tcitworld Jul 7, 2016
8da2100
Start work on returning CalDAV published calendars
tcitworld Jul 7, 2016
90ab6e4
Add new root collection public-calendars which holds all public calen…
DeepDiver1975 Jul 8, 2016
e7085aa
Allow not-authenticated access to specific urls
DeepDiver1975 Jul 8, 2016
00dc157
Fix requests for browser plugin as well as for the public calendar ro…
DeepDiver1975 Jul 11, 2016
994001c
Dirty hack to disable dav plugins on public calendar urls
tcitworld Jul 11, 2016
aca3053
Fix DB call for MySQL databases
tcitworld Jul 12, 2016
2df69ec
correct get published status and minor fixes
tcitworld Jul 12, 2016
f09c46d
Fix some tests
tcitworld Jul 12, 2016
aadb56d
Fix wrong way to get publish status
tcitworld Jul 18, 2016
e783d01
Allow public access to the principals/system/public
DeepDiver1975 Jul 19, 2016
d0ec6b9
Disable OPTIONS handling - done by sabre
DeepDiver1975 Jul 19, 2016
77216e7
a few tests
tcitworld Jul 20, 2016
de5e212
fix plugin test
tcitworld Jul 20, 2016
ebf2377
fix unpublishing test
tcitworld Jul 20, 2016
3921385
fix things (indentation, tests, comments, backend custom implementation
tcitworld Jul 31, 2016
762726d
fix indent once and for all
tcitworld Aug 1, 2016
1899116
move getPublicCalendar inside the caldav backend
tcitworld Aug 1, 2016
dd248ca
fix some bracket positions
tcitworld Aug 1, 2016
691b3ab
Add publicuri to oc_dav_shares table and start working with it
tcitworld Aug 1, 2016
9af2a9f
test serializer
tcitworld Aug 1, 2016
8433c3c
fix getChild()
tcitworld Aug 3, 2016
a4fe596
add space between calendarname and owner name
tcitworld Aug 11, 2016
f16ea48
add can-be-published property
tcitworld Aug 12, 2016
f0421e1
add missing tests
tcitworld Aug 14, 2016
6378dbc
fix can-be-published
tcitworld Aug 14, 2016
ad0eeaa
use AllowedSharingModes for can-be-published & can-be-shared
tcitworld Aug 15, 2016
3e9a346
add calendarserver-sharing to the list of advertised features
tcitworld Aug 16, 2016
ff67cbc
Add test for PublicCalendarRoot
tcitworld Aug 18, 2016
2fff203
Add missing constructor argument
LukasReschke Aug 30, 2016
4659e3a
Add new constructor args
LukasReschke Aug 30, 2016
d884370
Use true random string as uri for public calendars - as a result we c…
DeepDiver1975 Sep 3, 2016
8360222
fix public calendars
tcitworld Sep 14, 2016
17d5dfd
add in same request
tcitworld Sep 15, 2016
9c75b00
fix tests
tcitworld Sep 15, 2016
dcc2311
fix annotations & copyright headers
tcitworld Sep 23, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Proper work on Publishing
  • Loading branch information
tcitworld authored and LukasReschke committed Sep 26, 2016
commit 69d3601dcbb17ea9e2d868144159867a79d8e25c
1 change: 1 addition & 0 deletions apps/dav/appinfo/v1/caldav.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
$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) {
Expand Down
37 changes: 37 additions & 0 deletions apps/dav/lib/CalDAV/CalDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -1472,6 +1472,43 @@ public function getShares($resourceId) {
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
Expand Down
24 changes: 23 additions & 1 deletion apps/dav/lib/CalDAV/Calendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -89,6 +90,13 @@ public function getResourceId() {
return $this->calendarInfo['id'];
}

/**
* @return str
*/
public function getPrincipalURI() {
return $this->calendarInfo['principaluri'];
}

function getACL() {
$acl = [
[
Expand Down Expand Up @@ -236,6 +244,20 @@ function calendarQuery(array $filters) {
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'];
Expand Down
187 changes: 187 additions & 0 deletions apps/dav/lib/CalDAV/Publishing/PublishPlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<?php

namespace OCA\DAV\CalDAV\Publishing;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing copyright


//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 changes: 55 additions & 0 deletions apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace OCA\DAV\CalDAV\Publishing\Xml;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing header


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 change: 1 addition & 0 deletions apps/dav/lib/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public function __construct(IRequest $request, $baseUri) {
$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());
Expand Down