Skip to content

Commit

Permalink
move disableFreeBusy check from User principal backend to Scheduling …
Browse files Browse the repository at this point in the history
…Outbox collection. This allows to keep local delivery of scheduling messages while prohibiting FreeBusy requests

Signed-off-by: Georg Ehrke <developer@georgehrke.com>
  • Loading branch information
georgehrke committed Oct 23, 2018
1 parent e3a2b9e commit aa94064
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 108 deletions.
2 changes: 1 addition & 1 deletion apps/dav/composer/composer/ClassLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ private function findFileWithExtension($class, $ext)
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
'OCA\\DAV\\CalDAV\\CalendarManager' => $baseDir . '/../lib/CalDAV/CalendarManager.php',
'OCA\\DAV\\CalDAV\\CalendarObject' => $baseDir . '/../lib/CalDAV/CalendarObject.php',
'OCA\\DAV\\CalDAV\\CalendarRoot' => $baseDir . '/../lib/CalDAV/CalendarRoot.php',
'OCA\\DAV\\CalDAV\\Outbox' => $baseDir . '/../lib/CalDAV/Outbox.php',
'OCA\\DAV\\CalDAV\\Plugin' => $baseDir . '/../lib/CalDAV/Plugin.php',
'OCA\\DAV\\CalDAV\\Principal\\Collection' => $baseDir . '/../lib/CalDAV/Principal/Collection.php',
'OCA\\DAV\\CalDAV\\Principal\\User' => $baseDir . '/../lib/CalDAV/Principal/User.php',
Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\CalDAV\\CalendarManager' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarManager.php',
'OCA\\DAV\\CalDAV\\CalendarObject' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarObject.php',
'OCA\\DAV\\CalDAV\\CalendarRoot' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarRoot.php',
'OCA\\DAV\\CalDAV\\Outbox' => __DIR__ . '/..' . '/../lib/CalDAV/Outbox.php',
'OCA\\DAV\\CalDAV\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/Plugin.php',
'OCA\\DAV\\CalDAV\\Principal\\Collection' => __DIR__ . '/..' . '/../lib/CalDAV/Principal/Collection.php',
'OCA\\DAV\\CalDAV\\Principal\\User' => __DIR__ . '/..' . '/../lib/CalDAV/Principal/User.php',
Expand Down
5 changes: 2 additions & 3 deletions apps/dav/lib/CalDAV/CalendarHome.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
use Sabre\CalDAV\Backend\SchedulingSupport;
use Sabre\CalDAV\Backend\SubscriptionSupport;
use Sabre\CalDAV\Schedule\Inbox;
use Sabre\CalDAV\Schedule\Outbox;
use Sabre\CalDAV\Subscriptions\Subscription;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\Exception\MethodNotAllowed;
Expand Down Expand Up @@ -81,7 +80,7 @@ function getChildren() {

if ($this->caldavBackend instanceof SchedulingSupport) {
$objects[] = new Inbox($this->caldavBackend, $this->principalInfo['uri']);
$objects[] = new Outbox($this->principalInfo['uri']);
$objects[] = new Outbox($this->config, $this->principalInfo['uri']);
}

// We're adding a notifications node, if it's supported by the backend.
Expand All @@ -108,7 +107,7 @@ function getChild($name) {
return new Inbox($this->caldavBackend, $this->principalInfo['uri']);
}
if ($name === 'outbox' && $this->caldavBackend instanceof SchedulingSupport) {
return new Outbox($this->principalInfo['uri']);
return new Outbox($this->config, $this->principalInfo['uri']);
}
if ($name === 'notifications' && $this->caldavBackend instanceof NotificationSupport) {
return new \Sabre\CalDAv\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
Expand Down
132 changes: 132 additions & 0 deletions apps/dav/lib/CalDAV/Outbox.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?php
/**
* @copyright Copyright (c) 2018, Georg Ehrke
*
* @author Georg Ehrke <oc.list@georgehrke.com>
*
* @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 OCP\IConfig;
use Sabre\CalDAV\Plugin as CalDAVPlugin;

/**
* Class Outbox
*
* @package OCA\DAV\CalDAV
*/
class Outbox extends \Sabre\CalDAV\Schedule\Outbox {

/** @var IConfig */
private $config;

/** @var null|bool */
private $disableFreeBusy = null;

/**
* Outbox constructor.
*
* @param IConfig $config
* @param string $principalUri
*/
public function __construct(IConfig $config, $principalUri) {
parent::__construct($principalUri);
$this->config = $config;
}

/**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
* * 'protected' (optional), indicating that this ACE is not allowed to
* be updated.
*
* @return array
*/
function getACL() {
// getACL is called so frequently that we cache the config result
if ($this->disableFreeBusy === null) {
$this->disableFreeBusy = ($this->config->getAppValue('dav', 'disableFreeBusy', 'no') === 'yes');
}

$commonAcl = [
[
'privilege' => '{DAV:}read',
'principal' => $this->getOwner(),
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => $this->getOwner() . '/calendar-proxy-read',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => $this->getOwner() . '/calendar-proxy-write',
'protected' => true,
],
];

// schedule-send is an aggregate privilege for:
// - schedule-send-invite
// - schedule-send-reply
// - schedule-send-freebusy
//
// If FreeBusy is disabled, we have to remove the latter privilege

if ($this->disableFreeBusy) {
return array_merge($commonAcl, [
[
'privilege' => '{' . CalDAVPlugin::NS_CALDAV . '}schedule-send-invite',
'principal' => $this->getOwner(),
'protected' => true,
],
[
'privilege' => '{' . CalDAVPlugin::NS_CALDAV . '}schedule-send-invite',
'principal' => $this->getOwner() . '/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{' . CalDAVPlugin::NS_CALDAV . '}schedule-send-reply',
'principal' => $this->getOwner(),
'protected' => true,
],
[
'privilege' => '{' . CalDAVPlugin::NS_CALDAV . '}schedule-send-reply',
'principal' => $this->getOwner() . '/calendar-proxy-write',
'protected' => true,
],
]);
}

return array_merge($commonAcl, [
[
'privilege' => '{' . CalDAVPlugin::NS_CALDAV . '}schedule-send',
'principal' => $this->getOwner(),
'protected' => true,
],
[
'privilege' => '{' . CalDAVPlugin::NS_CALDAV . '}schedule-send',
'principal' => $this->getOwner() . '/calendar-proxy-write',
'protected' => true,
],
]);
}
}
10 changes: 4 additions & 6 deletions apps/dav/lib/Connector/Sabre/Principal.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,9 @@ function updatePrincipal($path, PropPatch $propPatch) {
protected function searchUserPrincipals(array $searchProperties, $test = 'allof') {
$results = [];

// If sharing is disabled (or FreeBusy was disabled on purpose), return the empty array
// If sharing is disabled, return the empty array
$shareAPIEnabled = $this->shareManager->shareApiEnabled();
$disableFreeBusy = $this->config->getAppValue('dav', 'disableFreeBusy', $shareAPIEnabled ? 'no' : 'yes');
if ($disableFreeBusy === 'yes') {
if (!$shareAPIEnabled) {
return [];
}

Expand Down Expand Up @@ -299,10 +298,9 @@ function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof')
* @return string
*/
function findByUri($uri, $principalPrefix) {
// If sharing is disabled (or FreeBusy was disabled on purpose), return the empty array
// If sharing is disabled, return the empty array
$shareAPIEnabled = $this->shareManager->shareApiEnabled();
$disableFreeBusy = $this->config->getAppValue('dav', 'disableFreeBusy', $shareAPIEnabled ? 'no' : 'yes');
if ($disableFreeBusy === 'yes') {
if (!$shareAPIEnabled) {
return null;
}

Expand Down
123 changes: 123 additions & 0 deletions apps/dav/tests/unit/CalDAV/OutboxTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php
/**
* @copyright Copyright (c) 2018, Georg Ehrke
*
* @author Georg Ehrke <oc.list@georgehrke.com>
*
* @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\Tests\unit\CalDAV;

use OCA\DAV\CalDAV\Outbox;
use OCP\IConfig;
use Test\TestCase;

class OutboxTest extends TestCase {

/** @var IConfig */
private $config;

/** @var Outbox */
private $outbox;

protected function setUp() {
parent::setUp();

$this->config = $this->createMock(IConfig::class);
$this->outbox = new Outbox($this->config, 'user-principal-123');
}

public function testGetACLFreeBusyEnabled() {
$this->config->expects($this->once())
->method('getAppValue')
->with('dav', 'disableFreeBusy', 'no')
->will($this->returnValue('no'));

$this->assertEquals([
[
'privilege' => '{DAV:}read',
'principal' => 'user-principal-123',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'user-principal-123/calendar-proxy-read',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'user-principal-123/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{urn:ietf:params:xml:ns:caldav}schedule-send',
'principal' => 'user-principal-123',
'protected' => true,
],
[
'privilege' => '{urn:ietf:params:xml:ns:caldav}schedule-send',
'principal' => 'user-principal-123/calendar-proxy-write',
'protected' => true,
],
], $this->outbox->getACL());
}

public function testGetACLFreeBusyDisabled() {
$this->config->expects($this->once())
->method('getAppValue')
->with('dav', 'disableFreeBusy', 'no')
->will($this->returnValue('yes'));

$this->assertEquals([
[
'privilege' => '{DAV:}read',
'principal' => 'user-principal-123',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'user-principal-123/calendar-proxy-read',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'user-principal-123/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{urn:ietf:params:xml:ns:caldav}schedule-send-invite',
'principal' => 'user-principal-123',
'protected' => true,
],
[
'privilege' => '{urn:ietf:params:xml:ns:caldav}schedule-send-invite',
'principal' => 'user-principal-123/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{urn:ietf:params:xml:ns:caldav}schedule-send-reply',
'principal' => 'user-principal-123',
'protected' => true,
],
[
'privilege' => '{urn:ietf:params:xml:ns:caldav}schedule-send-reply',
'principal' => 'user-principal-123/calendar-proxy-write',
'protected' => true,
],
], $this->outbox->getACL());
}
}
Loading

0 comments on commit aa94064

Please sign in to comment.