Merge pull request #1197 from nextcloud/oc-public-sharing
CalDAV calendar public sharing
This commit is contained in:
commit
06e969cb74
18 changed files with 1033 additions and 8 deletions
|
@ -703,6 +703,11 @@ CREATE TABLE calendarobjects (
|
|||
<notnull>true</notnull>
|
||||
<unsigned>true</unsigned>
|
||||
</field>
|
||||
<field>
|
||||
<name>publicuri</name>
|
||||
<type>text</type>
|
||||
<length>255</length>
|
||||
</field>
|
||||
<index>
|
||||
<name>dav_shares_index</name>
|
||||
<unique>true</unique>
|
||||
|
@ -715,6 +720,9 @@ CREATE TABLE calendarobjects (
|
|||
<field>
|
||||
<name>type</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>publicuri</name>
|
||||
</field>
|
||||
</index>
|
||||
</declaration>
|
||||
</table>
|
||||
|
|
|
@ -46,7 +46,10 @@ $principalBackend = new Principal(
|
|||
'principals/'
|
||||
);
|
||||
$db = \OC::$server->getDatabaseConnection();
|
||||
$calDavBackend = new CalDavBackend($db, $principalBackend, \OC::$server->getUserManager());
|
||||
$config = \OC::$server->getConfig();
|
||||
$userManager = \OC::$server->getUserManager();
|
||||
$random = \OC::$server->getSecureRandom();
|
||||
$calDavBackend = new CalDavBackend($db, $principalBackend, $userManager, $config, $random);
|
||||
|
||||
$debugging = \OC::$server->getConfig()->getSystemValue('debug', false);
|
||||
|
||||
|
|
|
@ -29,9 +29,11 @@ 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;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use Sabre\CalDAV\Backend\AbstractBackend;
|
||||
use Sabre\CalDAV\Backend\SchedulingSupport;
|
||||
use Sabre\CalDAV\Backend\SubscriptionSupport;
|
||||
|
@ -41,6 +43,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;
|
||||
|
@ -66,6 +69,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;
|
||||
|
@ -117,6 +121,12 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
|
||||
/** @var ISecureRandom */
|
||||
private $random;
|
||||
|
||||
/**
|
||||
* CalDavBackend constructor.
|
||||
|
@ -124,12 +134,20 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
* @param IDBConnection $db
|
||||
* @param Principal $principalBackend
|
||||
* @param IUserManager $userManager
|
||||
* @param IConfig $config
|
||||
* @param ISecureRandom $random
|
||||
*/
|
||||
public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager) {
|
||||
public function __construct(IDBConnection $db,
|
||||
Principal $principalBackend,
|
||||
IUserManager $userManager,
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -295,6 +313,120 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
|
||||
return $this->userDisplayNames[$uid];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
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';
|
||||
$fields[] = 's.publicuri';
|
||||
$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']);
|
||||
}
|
||||
$calendar = [
|
||||
'id' => $row['id'],
|
||||
'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',
|
||||
'{' . 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];
|
||||
}
|
||||
|
||||
if (!isset($calendars[$calendar['id']])) {
|
||||
$calendars[$calendar['id']] = $calendar;
|
||||
}
|
||||
}
|
||||
$result->closeCursor();
|
||||
|
||||
return array_values($calendars);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return array
|
||||
* @throws NotFound
|
||||
*/
|
||||
public function getPublicCalendar($uri) {
|
||||
$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');
|
||||
}
|
||||
|
||||
list(, $name) = URLUtil::splitPath($row['principaluri']);
|
||||
$row['displayname'] = $row['displayname'] . ' ' . "($name)";
|
||||
$components = [];
|
||||
if ($row['components']) {
|
||||
$components = explode(',',$row['components']);
|
||||
}
|
||||
$calendar = [
|
||||
'id' => $row['id'],
|
||||
'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',
|
||||
'{' . 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 $calendar;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $principal
|
||||
|
@ -1472,6 +1604,50 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
return $this->sharingBackend->getShares($resourceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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($publicUri)
|
||||
]);
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \OCA\DAV\CalDAV\Calendar $calendar
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPublishStatus($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 $row ? reset($row) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $resourceId
|
||||
* @param array $acl
|
||||
|
|
|
@ -89,6 +89,13 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
|
|||
return $this->calendarInfo['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPrincipalURI() {
|
||||
return $this->calendarInfo['principaluri'];
|
||||
}
|
||||
|
||||
function getACL() {
|
||||
$acl = [
|
||||
[
|
||||
|
@ -117,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;
|
||||
|
@ -236,6 +250,23 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
|
|||
return $uris;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $value
|
||||
* @return string|null
|
||||
*/
|
||||
function setPublishStatus($value) {
|
||||
$publicUri = $this->caldavBackend->setPublishStatus($value, $this);
|
||||
$this->calendarInfo['publicuri'] = $publicUri;
|
||||
return $publicUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed $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'];
|
||||
|
@ -243,8 +274,16 @@ 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']);
|
||||
}
|
||||
|
||||
public function isSubscription() {
|
||||
return isset($this->calendarInfo['{http://calendarserver.org/ns/}source']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
67
apps/dav/lib/CalDAV/PublicCalendarRoot.php
Normal file
67
apps/dav/lib/CalDAV/PublicCalendarRoot.php
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
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');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
function getName() {
|
||||
return 'public-calendars';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
function getChild($name) {
|
||||
$calendar = $this->caldavBackend->getPublicCalendar($name);
|
||||
return new Calendar($this->caldavBackend, $calendar, $this->l10n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
function getChildren() {
|
||||
$calendars = $this->caldavBackend->getPublicCalendars();
|
||||
$children = [];
|
||||
foreach ($calendars as $calendar) {
|
||||
// TODO: maybe implement a new class PublicCalendar ???
|
||||
$children[] = new Calendar($this->caldavBackend, $calendar, $this->l10n);
|
||||
}
|
||||
|
||||
return $children;
|
||||
}
|
||||
}
|
227
apps/dav/lib/CalDAV/Publishing/PublishPlugin.php
Normal file
227
apps/dav/lib/CalDAV/Publishing/PublishPlugin.php
Normal file
|
@ -0,0 +1,227 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Citharel <tcit@tcit.fr>
|
||||
*
|
||||
* @copyright Copyright (c) 2016 Thomas Citharel <tcit@tcit.fr>
|
||||
* @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 <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\CalDAV\Publishing;
|
||||
|
||||
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 Sabre\CalDAV\Xml\Property\AllowedSharingModes;
|
||||
use OCA\DAV\CalDAV\Publishing\Xml\Publisher;
|
||||
use OCA\DAV\CalDAV\Calendar;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IConfig;
|
||||
|
||||
class PublishPlugin extends ServerPlugin {
|
||||
const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
|
||||
|
||||
/**
|
||||
* Reference to SabreDAV server object.
|
||||
*
|
||||
* @var \Sabre\DAV\Server
|
||||
*/
|
||||
protected $server;
|
||||
|
||||
/**
|
||||
* Config instance to get instance secret.
|
||||
*
|
||||
* @var IConfig
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* URL Generator for absolute URLs.
|
||||
*
|
||||
* @var IURLGenerator
|
||||
*/
|
||||
protected $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
|
||||
* in an OPTIONS response.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getFeatures() {
|
||||
// May have to be changed to be detected
|
||||
return ['oc-calendar-publishing', 'calendarserver-sharing'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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']);
|
||||
}
|
||||
|
||||
public function propFind(PropFind $propFind, INode $node) {
|
||||
if ($node instanceof Calendar) {
|
||||
$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->getPublishStatus();
|
||||
$publishUrl = $this->urlGenerator->getAbsoluteURL($this->server->getBaseUri().'public-calendars/').$token;
|
||||
|
||||
return new Publisher($publishUrl, true);
|
||||
}
|
||||
});
|
||||
|
||||
$propFind->handle('{'.self::NS_CALENDARSERVER.'}allowed-sharing-modes', function() use ($node) {
|
||||
return new AllowedSharingModes(!$node->isSubscription(), !$node->isSubscription());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We intercept this to handle POST requests on calendars.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @return void|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;
|
||||
}
|
||||
|
||||
// Making sure the node exists
|
||||
try {
|
||||
$node = $this->server->tree->getNodeForPath($path);
|
||||
} catch (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);
|
||||
|
||||
$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 Calendar) {
|
||||
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 Calendar) {
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
83
apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php
Normal file
83
apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Citharel <tcit@tcit.fr>
|
||||
*
|
||||
* @copyright Copyright (c) 2016 Thomas Citharel <tcit@tcit.fr>
|
||||
* @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 <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
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 string $publishUrl
|
||||
*/
|
||||
protected $publishUrl;
|
||||
|
||||
/**
|
||||
* @var boolean $isPublished
|
||||
*/
|
||||
protected $isPublished;
|
||||
|
||||
/**
|
||||
* @param string $publishUrl
|
||||
* @param boolean $isPublished
|
||||
*/
|
||||
function __construct($publishUrl, $isPublished) {
|
||||
$this->publishUrl = $publishUrl;
|
||||
$this->isPublished = $isPublished;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
// for pre-publish-url
|
||||
$writer->write($this->publishUrl);
|
||||
} else {
|
||||
// for publish-url
|
||||
$writer->writeElement('{DAV:}href', $this->publishUrl);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,11 @@ class CreateCalendar extends Command {
|
|||
$this->userManager,
|
||||
$this->groupManager
|
||||
);
|
||||
$config = \OC::$server->getConfig();
|
||||
$random = \OC::$server->getSecureRandom();
|
||||
|
||||
$name = $input->getArgument('name');
|
||||
$caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager);
|
||||
$caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $config, $random);
|
||||
$caldav->createCalendar("principals/users/$user", $name, []);
|
||||
}
|
||||
}
|
||||
|
|
92
apps/dav/lib/DAV/PublicAuth.php
Normal file
92
apps/dav/lib/DAV/PublicAuth.php
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
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;
|
||||
|
||||
public function __construct() {
|
||||
$this->publicURLs = [
|
||||
'public-calendars',
|
||||
'principals/system/public'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
|
||||
if ($this->isRequestPublic($request)) {
|
||||
return [true, "principals/system/public"];
|
||||
}
|
||||
return [false, "No public access to this resource."];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
function challenge(RequestInterface $request, ResponseInterface $response) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @return bool
|
||||
*/
|
||||
private function isRequestPublic(RequestInterface $request) {
|
||||
$url = $request->getPath();
|
||||
$matchingUrls = array_filter($this->publicURLs, function ($publicUrl) use ($url) {
|
||||
return strpos($url, $publicUrl, 0) === 0;
|
||||
});
|
||||
return !empty($matchingUrls);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -38,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(
|
||||
|
@ -59,9 +62,11 @@ 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, $userManager, $config, $random);
|
||||
$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 +106,7 @@ class RootCollection extends SimpleCollection {
|
|||
$systemPrincipals]),
|
||||
$filesCollection,
|
||||
$calendarRoot,
|
||||
$publicCalendarRoot,
|
||||
new SimpleCollection('addressbooks', [
|
||||
$usersAddressBookRoot,
|
||||
$systemAddressBookRoot]),
|
||||
|
|
|
@ -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
|
||||
|
@ -114,6 +117,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(
|
||||
\OC::$server->getConfig(),
|
||||
\OC::$server->getUrlGenerator()
|
||||
));
|
||||
|
||||
// addressbook plugins
|
||||
$this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin());
|
||||
|
|
|
@ -28,6 +28,8 @@ use OCA\DAV\CalDAV\CalDavBackend;
|
|||
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;
|
||||
|
@ -51,6 +53,12 @@ abstract class AbstractCalDavBackendTest extends TestCase {
|
|||
|
||||
/** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $userManager;
|
||||
|
||||
/** 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';
|
||||
|
@ -75,8 +83,9 @@ abstract class AbstractCalDavBackendTest extends TestCase {
|
|||
->willReturn([self::UNIT_TEST_GROUP]);
|
||||
|
||||
$db = \OC::$server->getDatabaseConnection();
|
||||
$this->backend = new CalDavBackend($db, $this->principal, $this->userManager);
|
||||
|
||||
$this->config = \OC::$server->getConfig();
|
||||
$this->random = \OC::$server->getSecureRandom();
|
||||
$this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->config, $this->random);
|
||||
$this->tearDown();
|
||||
}
|
||||
|
||||
|
|
|
@ -334,6 +334,35 @@ 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);
|
||||
$calendar->setPublishStatus(true);
|
||||
$this->assertNotEquals(false, $calendar->getPublishStatus());
|
||||
|
||||
$publicCalendars = $this->backend->getPublicCalendars();
|
||||
$this->assertEquals(1, count($publicCalendars));
|
||||
$this->assertEquals(true, $publicCalendars[0]['{http://owncloud.org/ns}public']);
|
||||
|
||||
$publicCalendarURI = $publicCalendars[0]['uri'];
|
||||
$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() {
|
||||
$id = $this->backend->createSubscription(self::UNIT_TEST_USER, 'Subscription', [
|
||||
'{http://calendarserver.org/ns/}source' => new Href('test-source'),
|
||||
|
|
122
apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php
Normal file
122
apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\DAV\Tests\unit\CalDAV;
|
||||
|
||||
use OCA\DAV\CalDAV\Calendar;
|
||||
use OCA\DAV\Connector\Sabre\Principal;
|
||||
use OCP\IL10N;
|
||||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCA\DAV\CalDAV\PublicCalendarRoot;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use Test\TestCase;
|
||||
|
||||
/**
|
||||
* Class PublicCalendarRootTest
|
||||
*
|
||||
* @group DB
|
||||
*
|
||||
* @package OCA\DAV\Tests\unit\CalDAV
|
||||
*/
|
||||
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 */
|
||||
private $userManager;
|
||||
/** @var Principal */
|
||||
private $principal;
|
||||
/** var IConfig */
|
||||
protected $config;
|
||||
/** @var ISecureRandom */
|
||||
private $random;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$db = \OC::$server->getDatabaseConnection();
|
||||
$this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal')
|
||||
->disableOriginalConstructor()
|
||||
->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->random
|
||||
);
|
||||
|
||||
$this->publicCalendarRoot = new PublicCalendarRoot($this->backend);
|
||||
|
||||
$this->l10n = $this->getMockBuilder('\OCP\IL10N')
|
||||
->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);
|
||||
}
|
||||
|
||||
public function testGetChild() {
|
||||
|
||||
$calendar = $this->createPublicCalendar();
|
||||
|
||||
$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();
|
||||
|
||||
$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];
|
||||
$calendar = new Calendar($this->backend, $calendarInfo, $this->l10n);
|
||||
$publicUri = $calendar->setPublishStatus(true);
|
||||
|
||||
$calendarInfo = $this->backend->getPublicCalendar($publicUri);
|
||||
$calendar = new Calendar($this->backend, $calendarInfo, $this->l10n);
|
||||
|
||||
return $calendar;
|
||||
}
|
||||
|
||||
}
|
56
apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.php
Normal file
56
apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\DAV\Tests\unit\CalDAV\Publishing;
|
||||
|
||||
use OCA\DAV\CalDAV\Publishing\Xml\Publisher;
|
||||
use Sabre\Xml\Writer;
|
||||
|
||||
class PublisherTest extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
|
||||
|
||||
public function testSerializePublished() {
|
||||
$publish = new Publisher('urltopublish', true);
|
||||
|
||||
$xml = $this->write([
|
||||
'{' . self::NS_CALENDARSERVER . '}publish-url' => $publish,
|
||||
]);
|
||||
|
||||
$this->assertEquals('urltopublish', $publish->getValue());
|
||||
|
||||
$this->assertXmlStringEqualsXmlString(
|
||||
'<?xml version="1.0"?>
|
||||
<x1:publish-url xmlns:d="DAV:" xmlns:x1="' . self::NS_CALENDARSERVER . '">
|
||||
<d:href>urltopublish</d:href>
|
||||
</x1:publish-url>', $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(
|
||||
'<?xml version="1.0"?>
|
||||
<x1:pre-publish-url xmlns:d="DAV:" xmlns:x1="' . self::NS_CALENDARSERVER . '">urltopublish</x1:pre-publish-url>', $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();
|
||||
}
|
||||
}
|
82
apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php
Normal file
82
apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\DAV\Tests\unit\CalDAV\Publishing;
|
||||
|
||||
use OCA\DAV\CalDAV\Calendar;
|
||||
use OCA\DAV\CalDAV\Publishing\PublishPlugin;
|
||||
use OCP\IRequest;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IConfig;
|
||||
use Sabre\DAV\Server;
|
||||
use Sabre\DAV\SimpleCollection;
|
||||
use Sabre\HTTP\Request;
|
||||
use Sabre\HTTP\Response;
|
||||
use Test\TestCase;
|
||||
|
||||
class PluginTest extends TestCase {
|
||||
|
||||
/** @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();
|
||||
|
||||
$this->config = $this->getMockBuilder('\OCP\IConfig')->
|
||||
disableOriginalConstructor()->
|
||||
getMock();
|
||||
$this->config->expects($this->any())->method('getSystemValue')
|
||||
->with($this->equalTo('secret'))
|
||||
->willReturn('mysecret');
|
||||
|
||||
$this->urlGenerator = $this->getMockBuilder('OCP\IURLGenerator')->
|
||||
disableOriginalConstructor()->
|
||||
getMock();
|
||||
|
||||
/** @var IRequest $request */
|
||||
$this->plugin = new PublishPlugin($this->config, $this->urlGenerator);
|
||||
|
||||
$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('<o:publish-calendar xmlns:o="http://calendarserver.org/ns/"/>');
|
||||
$response = new Response();
|
||||
$this->plugin->httpPost($request, $response);
|
||||
}
|
||||
|
||||
public function testUnPublishing() {
|
||||
|
||||
$this->book->expects($this->once())->method('setPublishStatus')->with(false);
|
||||
|
||||
// setup request
|
||||
$request = new Request();
|
||||
$request->addHeader('Content-Type', 'application/xml');
|
||||
$request->setUrl('cal1');
|
||||
$request->setBody('<o:unpublish-calendar xmlns:o="http://calendarserver.org/ns/"/>');
|
||||
$response = new Response();
|
||||
$this->plugin->httpPost($request, $response);
|
||||
}
|
||||
}
|
|
@ -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'],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue