summaryrefslogtreecommitdiffstats
path: root/apps/dav
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dav')
-rw-r--r--apps/dav/appinfo/info.xml2
-rw-r--r--apps/dav/appinfo/v1/caldav.php2
-rw-r--r--apps/dav/appinfo/v1/carddav.php2
-rw-r--r--apps/dav/composer/composer/autoload_classmap.php4
-rw-r--r--apps/dav/composer/composer/autoload_static.php4
-rw-r--r--apps/dav/lib/CalDAV/Calendar.php50
-rw-r--r--apps/dav/lib/CalDAV/Proxy/Proxy.php51
-rw-r--r--apps/dav/lib/CalDAV/Proxy/ProxyMapper.php78
-rw-r--r--apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php42
-rw-r--r--apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php14
-rw-r--r--apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php14
-rw-r--r--apps/dav/lib/Command/CreateCalendar.php5
-rw-r--r--apps/dav/lib/Connector/Sabre/Principal.php100
-rw-r--r--apps/dav/lib/Migration/Version1011Date20190806104428.php55
-rw-r--r--apps/dav/lib/RootCollection.php11
-rw-r--r--apps/dav/lib/Server.php3
-rw-r--r--apps/dav/lib/Traits/PrincipalProxyTrait.php223
-rw-r--r--apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php3
-rw-r--r--apps/dav/tests/unit/CalDAV/CalendarTest.php37
-rw-r--r--apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php114
-rw-r--r--apps/dav/tests/unit/CalDAV/ResourceBooking/ResourcePrincipalBackendTest.php2
-rw-r--r--apps/dav/tests/unit/CalDAV/ResourceBooking/RoomPrincipalBackendTest.php2
-rw-r--r--apps/dav/tests/unit/CardDAV/CardDavBackendTest.php3
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php154
24 files changed, 841 insertions, 134 deletions
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index 71b3699b1ec..dc90ac58188 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -5,7 +5,7 @@
<name>WebDAV</name>
<summary>WebDAV endpoint</summary>
<description>WebDAV endpoint</description>
- <version>1.11.0</version>
+ <version>1.11.1</version>
<licence>agpl</licence>
<author>owncloud.org</author>
<namespace>DAV</namespace>
diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php
index c2634a595a3..8116453b11d 100644
--- a/apps/dav/appinfo/v1/caldav.php
+++ b/apps/dav/appinfo/v1/caldav.php
@@ -46,8 +46,8 @@ $principalBackend = new Principal(
\OC::$server->getGroupManager(),
\OC::$server->getShareManager(),
\OC::$server->getUserSession(),
- \OC::$server->getConfig(),
\OC::$server->getAppManager(),
+ \OC::$server->query(\OCA\DAV\CalDAV\Proxy\ProxyMapper::class),
'principals/'
);
$db = \OC::$server->getDatabaseConnection();
diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php
index 60669df60ba..40ee12f1944 100644
--- a/apps/dav/appinfo/v1/carddav.php
+++ b/apps/dav/appinfo/v1/carddav.php
@@ -47,8 +47,8 @@ $principalBackend = new Principal(
\OC::$server->getGroupManager(),
\OC::$server->getShareManager(),
\OC::$server->getUserSession(),
- \OC::$server->getConfig(),
\OC::$server->getAppManager(),
+ \OC::$server->query(\OCA\DAV\CalDAV\Proxy\ProxyMapper::class),
'principals/'
);
$db = \OC::$server->getDatabaseConnection();
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php
index 2931a4b1da7..694231eebda 100644
--- a/apps/dav/composer/composer/autoload_classmap.php
+++ b/apps/dav/composer/composer/autoload_classmap.php
@@ -44,6 +44,8 @@ return array(
'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',
+ 'OCA\\DAV\\CalDAV\\Proxy\\Proxy' => $baseDir . '/../lib/CalDAV/Proxy/Proxy.php',
+ 'OCA\\DAV\\CalDAV\\Proxy\\ProxyMapper' => $baseDir . '/../lib/CalDAV/Proxy/ProxyMapper.php',
'OCA\\DAV\\CalDAV\\PublicCalendar' => $baseDir . '/../lib/CalDAV/PublicCalendar.php',
'OCA\\DAV\\CalDAV\\PublicCalendarObject' => $baseDir . '/../lib/CalDAV/PublicCalendarObject.php',
'OCA\\DAV\\CalDAV\\PublicCalendarRoot' => $baseDir . '/../lib/CalDAV/PublicCalendarRoot.php',
@@ -181,6 +183,7 @@ return array(
'OCA\\DAV\\Migration\\Version1008Date20181105112049' => $baseDir . '/../lib/Migration/Version1008Date20181105112049.php',
'OCA\\DAV\\Migration\\Version1008Date20181114084440' => $baseDir . '/../lib/Migration/Version1008Date20181114084440.php',
'OCA\\DAV\\Migration\\Version1011Date20190725113607' => $baseDir . '/../lib/Migration/Version1011Date20190725113607.php',
+ 'OCA\\DAV\\Migration\\Version1011Date20190806104428' => $baseDir . '/../lib/Migration/Version1011Date20190806104428.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
'OCA\\DAV\\RootCollection' => $baseDir . '/../lib/RootCollection.php',
@@ -193,6 +196,7 @@ return array(
'OCA\\DAV\\SystemTag\\SystemTagsObjectMappingCollection' => $baseDir . '/../lib/SystemTag/SystemTagsObjectMappingCollection.php',
'OCA\\DAV\\SystemTag\\SystemTagsObjectTypeCollection' => $baseDir . '/../lib/SystemTag/SystemTagsObjectTypeCollection.php',
'OCA\\DAV\\SystemTag\\SystemTagsRelationsCollection' => $baseDir . '/../lib/SystemTag/SystemTagsRelationsCollection.php',
+ 'OCA\\DAV\\Traits\\PrincipalProxyTrait' => $baseDir . '/../lib/Traits/PrincipalProxyTrait.php',
'OCA\\DAV\\Upload\\AssemblyStream' => $baseDir . '/../lib/Upload/AssemblyStream.php',
'OCA\\DAV\\Upload\\ChunkingPlugin' => $baseDir . '/../lib/Upload/ChunkingPlugin.php',
'OCA\\DAV\\Upload\\CleanupService' => $baseDir . '/../lib/Upload/CleanupService.php',
diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php
index dd759e423df..6f104916077 100644
--- a/apps/dav/composer/composer/autoload_static.php
+++ b/apps/dav/composer/composer/autoload_static.php
@@ -59,6 +59,8 @@ class ComposerStaticInitDAV
'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',
+ 'OCA\\DAV\\CalDAV\\Proxy\\Proxy' => __DIR__ . '/..' . '/../lib/CalDAV/Proxy/Proxy.php',
+ 'OCA\\DAV\\CalDAV\\Proxy\\ProxyMapper' => __DIR__ . '/..' . '/../lib/CalDAV/Proxy/ProxyMapper.php',
'OCA\\DAV\\CalDAV\\PublicCalendar' => __DIR__ . '/..' . '/../lib/CalDAV/PublicCalendar.php',
'OCA\\DAV\\CalDAV\\PublicCalendarObject' => __DIR__ . '/..' . '/../lib/CalDAV/PublicCalendarObject.php',
'OCA\\DAV\\CalDAV\\PublicCalendarRoot' => __DIR__ . '/..' . '/../lib/CalDAV/PublicCalendarRoot.php',
@@ -196,6 +198,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Migration\\Version1008Date20181105112049' => __DIR__ . '/..' . '/../lib/Migration/Version1008Date20181105112049.php',
'OCA\\DAV\\Migration\\Version1008Date20181114084440' => __DIR__ . '/..' . '/../lib/Migration/Version1008Date20181114084440.php',
'OCA\\DAV\\Migration\\Version1011Date20190725113607' => __DIR__ . '/..' . '/../lib/Migration/Version1011Date20190725113607.php',
+ 'OCA\\DAV\\Migration\\Version1011Date20190806104428' => __DIR__ . '/..' . '/../lib/Migration/Version1011Date20190806104428.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
'OCA\\DAV\\RootCollection' => __DIR__ . '/..' . '/../lib/RootCollection.php',
@@ -208,6 +211,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\SystemTag\\SystemTagsObjectMappingCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsObjectMappingCollection.php',
'OCA\\DAV\\SystemTag\\SystemTagsObjectTypeCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsObjectTypeCollection.php',
'OCA\\DAV\\SystemTag\\SystemTagsRelationsCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsRelationsCollection.php',
+ 'OCA\\DAV\\Traits\\PrincipalProxyTrait' => __DIR__ . '/..' . '/../lib/Traits/PrincipalProxyTrait.php',
'OCA\\DAV\\Upload\\AssemblyStream' => __DIR__ . '/..' . '/../lib/Upload/AssemblyStream.php',
'OCA\\DAV\\Upload\\ChunkingPlugin' => __DIR__ . '/..' . '/../lib/Upload/ChunkingPlugin.php',
'OCA\\DAV\\Upload\\CleanupService' => __DIR__ . '/..' . '/../lib/Upload/CleanupService.php',
diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php
index f26913d7ce1..38def19af1d 100644
--- a/apps/dav/lib/CalDAV/Calendar.php
+++ b/apps/dav/lib/CalDAV/Calendar.php
@@ -26,6 +26,7 @@
*/
namespace OCA\DAV\CalDAV;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\DAV\Sharing\IShareable;
use OCA\DAV\Exception\UnsupportedLimitOnInitialSyncException;
use OCP\IConfig;
@@ -46,6 +47,14 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
/** @var IConfig */
private $config;
+ /**
+ * Calendar constructor.
+ *
+ * @param BackendInterface $caldavBackend
+ * @param $calendarInfo
+ * @param IL10N $l10n
+ * @param IConfig $config
+ */
public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n, IConfig $config) {
parent::__construct($caldavBackend, $calendarInfo);
@@ -119,27 +128,58 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
return $this->calendarInfo['principaluri'];
}
+ /**
+ * @return array
+ */
public function getACL() {
$acl = [
[
'privilege' => '{DAV:}read',
'principal' => $this->getOwner(),
'protected' => true,
- ]];
+ ],
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->getOwner() . '/calendar-proxy-write',
+ 'protected' => true,
+ ],
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->getOwner() . '/calendar-proxy-read',
+ 'protected' => true,
+ ],
+ ];
+
if ($this->getName() !== BirthdayService::BIRTHDAY_CALENDAR_URI) {
$acl[] = [
'privilege' => '{DAV:}write',
'principal' => $this->getOwner(),
'protected' => true,
];
+ $acl[] = [
+ 'privilege' => '{DAV:}write',
+ 'principal' => $this->getOwner() . '/calendar-proxy-write',
+ 'protected' => true,
+ ];
} else {
$acl[] = [
'privilege' => '{DAV:}write-properties',
'principal' => $this->getOwner(),
'protected' => true,
];
+ $acl[] = [
+ 'privilege' => '{DAV:}write-properties',
+ 'principal' => $this->getOwner() . '/calendar-proxy-write',
+ 'protected' => true,
+ ];
}
+ $acl[] = [
+ 'privilege' => '{DAV:}write-properties',
+ 'principal' => $this->getOwner() . '/calendar-proxy-read',
+ 'protected' => true,
+ ];
+
if (!$this->isShared()) {
return $acl;
}
@@ -173,7 +213,13 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
}
$acl = $this->caldavBackend->applyShareAcl($this->getResourceId(), $acl);
- $allowedPrincipals = [$this->getOwner(), parent::getOwner(), 'principals/system/public'];
+ $allowedPrincipals = [
+ $this->getOwner(),
+ $this->getOwner(). '/calendar-proxy-read',
+ $this->getOwner(). '/calendar-proxy-write',
+ parent::getOwner(),
+ 'principals/system/public'
+ ];
return array_filter($acl, function($rule) use ($allowedPrincipals) {
return \in_array($rule['principal'], $allowedPrincipals, true);
});
diff --git a/apps/dav/lib/CalDAV/Proxy/Proxy.php b/apps/dav/lib/CalDAV/Proxy/Proxy.php
new file mode 100644
index 00000000000..cb01470ae82
--- /dev/null
+++ b/apps/dav/lib/CalDAV/Proxy/Proxy.php
@@ -0,0 +1,51 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\DAV\CalDAV\Proxy;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method string getOwnerId()
+ * @method void setOwnerId(string $ownerId)
+ * @method string getProxyId()
+ * @method void setProxyId(string $proxyId)
+ * @method int getPermissions()
+ * @method void setPermissions(int $permissions)
+ */
+class Proxy extends Entity {
+
+ /** @var string */
+ protected $ownerId;
+ /** @var string */
+ protected $proxyId;
+ /** @var int */
+ protected $permissions;
+
+ public function __construct() {
+ $this->addType('ownerId', 'string');
+ $this->addType('proxyId', 'string');
+ $this->addType('permissions', 'int');
+ }
+}
diff --git a/apps/dav/lib/CalDAV/Proxy/ProxyMapper.php b/apps/dav/lib/CalDAV/Proxy/ProxyMapper.php
new file mode 100644
index 00000000000..8d8adb811b6
--- /dev/null
+++ b/apps/dav/lib/CalDAV/Proxy/ProxyMapper.php
@@ -0,0 +1,78 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\DAV\CalDAV\Proxy;
+
+use OCP\AppFramework\Db\QBMapper;
+use OCP\IDBConnection;
+
+/**
+ * Class ProxyMapper
+ *
+ * @package OCA\DAV\CalDAV\Proxy
+ */
+class ProxyMapper extends QBMapper {
+
+ const PERMISSION_READ = 1;
+ const PERMISSION_WRITE = 2;
+
+ /**
+ * ProxyMapper constructor.
+ *
+ * @param IDBConnection $db
+ */
+ public function __construct(IDBConnection $db) {
+ parent::__construct($db, 'dav_cal_proxy', Proxy::class);
+ }
+
+ /**
+ * @param string $proxyId The principal uri that can act as a proxy for the resulting calendars
+ *
+ * @return Proxy[]
+ */
+ public function getProxiesFor(string $proxyId): array {
+ $qb = $this->db->getQueryBuilder();
+
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where($qb->expr()->eq('proxy_id', $qb->createNamedParameter($proxyId)));
+
+ return $this->findEntities($qb);
+ }
+
+ /**
+ * @param string $ownerId The principal uri that has the resulting proxies for their calendars
+ *
+ * @return Proxy[]
+ */
+ public function getProxiesOf(string $ownerId): array {
+ $qb = $this->db->getQueryBuilder();
+
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where($qb->expr()->eq('owner_id', $qb->createNamedParameter($ownerId)));
+
+ return $this->findEntities($qb);
+ }
+}
diff --git a/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
index aab5fcab8ad..63ed3381d14 100644
--- a/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
+++ b/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
@@ -22,6 +22,8 @@
*/
namespace OCA\DAV\CalDAV\ResourceBooking;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
+use OCA\DAV\Traits\PrincipalProxyTrait;
use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\ILogger;
@@ -44,6 +46,9 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
/** @var ILogger */
private $logger;
+ /** @var ProxyMapper */
+ private $proxyMapper;
+
/** @var string */
private $principalPrefix;
@@ -72,6 +77,7 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
IUserSession $userSession,
IGroupManager $groupManager,
ILogger $logger,
+ ProxyMapper $proxyMapper,
string $principalPrefix,
string $dbPrefix,
string $cuType) {
@@ -79,6 +85,7 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
$this->userSession = $userSession;
$this->groupManager = $groupManager;
$this->logger = $logger;
+ $this->proxyMapper = $proxyMapper;
$this->principalPrefix = $principalPrefix;
$this->dbTableName = 'calendar_' . $dbPrefix . 's';
$this->dbMetaDataTableName = $this->dbTableName . '_md';
@@ -86,6 +93,8 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
$this->cuType = $cuType;
}
+ use PrincipalProxyTrait;
+
/**
* Returns a list of principals based on a prefix.
*
@@ -216,39 +225,6 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
}
/**
- * Returns the list of members for a group-principal
- *
- * @param string $principal
- * @return string[]
- */
- public function getGroupMemberSet($principal) {
- return [];
- }
-
- /**
- * Returns the list of groups a principal is a member of
- *
- * @param string $principal
- * @return array
- */
- public function getGroupMembership($principal) {
- return [];
- }
-
- /**
- * Updates the list of group members for a group principal.
- *
- * The principals should be passed as a list of uri's.
- *
- * @param string $principal
- * @param string[] $members
- * @throws Exception
- */
- public function setGroupMemberSet($principal, array $members) {
- throw new Exception('Setting members of the group is not supported yet');
- }
-
- /**
* @param string $path
* @param PropPatch $propPatch
* @return int
diff --git a/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php
index 0f6e6e7b4fd..128e6c21fad 100644
--- a/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php
+++ b/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php
@@ -22,24 +22,34 @@
*/
namespace OCA\DAV\CalDAV\ResourceBooking;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\ILogger;
use OCP\IUserSession;
+/**
+ * Class ResourcePrincipalBackend
+ *
+ * @package OCA\DAV\CalDAV\ResourceBooking
+ */
class ResourcePrincipalBackend extends AbstractPrincipalBackend {
/**
+ * ResourcePrincipalBackend constructor.
+ *
* @param IDBConnection $dbConnection
* @param IUserSession $userSession
* @param IGroupManager $groupManager
* @param ILogger $logger
+ * @param ProxyMapper $proxyMapper
*/
public function __construct(IDBConnection $dbConnection,
IUserSession $userSession,
IGroupManager $groupManager,
- ILogger $logger) {
+ ILogger $logger,
+ ProxyMapper $proxyMapper) {
parent::__construct($dbConnection, $userSession, $groupManager, $logger,
- 'principals/calendar-resources', 'resource', 'RESOURCE');
+ $proxyMapper, 'principals/calendar-resources', 'resource', 'RESOURCE');
}
}
diff --git a/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php
index 68a344aa0ca..3e9e8f68852 100644
--- a/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php
+++ b/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php
@@ -22,24 +22,34 @@
*/
namespace OCA\DAV\CalDAV\ResourceBooking;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\ILogger;
use OCP\IUserSession;
+/**
+ * Class RoomPrincipalBackend
+ *
+ * @package OCA\DAV\CalDAV\ResourceBooking
+ */
class RoomPrincipalBackend extends AbstractPrincipalBackend {
/**
+ * RoomPrincipalBackend constructor.
+ *
* @param IDBConnection $dbConnection
* @param IUserSession $userSession
* @param IGroupManager $groupManager
* @param ILogger $logger
+ * @param ProxyMapper $proxyMapper
*/
public function __construct(IDBConnection $dbConnection,
IUserSession $userSession,
IGroupManager $groupManager,
- ILogger $logger) {
+ ILogger $logger,
+ ProxyMapper $proxyMapper) {
parent::__construct($dbConnection, $userSession, $groupManager, $logger,
- 'principals/calendar-rooms', 'room', 'ROOM');
+ $proxyMapper, 'principals/calendar-rooms', 'room', 'ROOM');
}
}
diff --git a/apps/dav/lib/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php
index 8e3a4abf8cf..a40bf48cc8e 100644
--- a/apps/dav/lib/Command/CreateCalendar.php
+++ b/apps/dav/lib/Command/CreateCalendar.php
@@ -24,6 +24,7 @@
namespace OCA\DAV\Command;
use OCA\DAV\CalDAV\CalDavBackend;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\Connector\Sabre\Principal;
use OCP\IDBConnection;
use OCP\IGroupManager;
@@ -78,8 +79,8 @@ class CreateCalendar extends Command {
$this->groupManager,
\OC::$server->getShareManager(),
\OC::$server->getUserSession(),
- \OC::$server->getConfig(),
- \OC::$server->getAppManager()
+ \OC::$server->getAppManager(),
+ \OC::$server->query(ProxyMapper::class)
);
$random = \OC::$server->getSecureRandom();
$logger = \OC::$server->getLogger();
diff --git a/apps/dav/lib/Connector/Sabre/Principal.php b/apps/dav/lib/Connector/Sabre/Principal.php
index 902c70bdaff..5c61b8371f2 100644
--- a/apps/dav/lib/Connector/Sabre/Principal.php
+++ b/apps/dav/lib/Connector/Sabre/Principal.php
@@ -35,9 +35,11 @@
namespace OCA\DAV\Connector\Sabre;
use OCA\Circles\Exceptions\CircleDoesNotExistException;
+use OCA\DAV\CalDAV\Proxy\Proxy;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
+use OCA\DAV\Traits\PrincipalProxyTrait;
use OCP\App\IAppManager;
use OCP\AppFramework\QueryException;
-use OCP\IConfig;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IUser;
@@ -62,9 +64,6 @@ class Principal implements BackendInterface {
/** @var IUserSession */
private $userSession;
- /** @var IConfig */
- private $config;
-
/** @var IAppManager */
private $appManager;
@@ -77,29 +76,39 @@ class Principal implements BackendInterface {
/** @var bool */
private $hasCircles;
+ /** @var ProxyMapper */
+ private $proxyMapper;
+
/**
+ * Principal constructor.
+ *
* @param IUserManager $userManager
* @param IGroupManager $groupManager
* @param IShareManager $shareManager
* @param IUserSession $userSession
- * @param IConfig $config
+ * @param IAppManager $appManager
+ * @param ProxyMapper $proxyMapper
* @param string $principalPrefix
*/
public function __construct(IUserManager $userManager,
IGroupManager $groupManager,
IShareManager $shareManager,
IUserSession $userSession,
- IConfig $config,
IAppManager $appManager,
+ ProxyMapper $proxyMapper,
string $principalPrefix = 'principals/users/') {
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->shareManager = $shareManager;
$this->userSession = $userSession;
- $this->config = $config;
$this->appManager = $appManager;
$this->principalPrefix = trim($principalPrefix, '/');
$this->hasGroups = $this->hasCircles = ($principalPrefix === 'principals/users/');
+ $this->proxyMapper = $proxyMapper;
+ }
+
+ use PrincipalProxyTrait {
+ getGroupMembership as protected traitGetGroupMembership;
}
/**
@@ -138,6 +147,21 @@ class Principal implements BackendInterface {
public function getPrincipalByPath($path) {
list($prefix, $name) = \Sabre\Uri\split($path);
+ if ($name === 'calendar-proxy-write' || $name === 'calendar-proxy-read') {
+ list($prefix2, $name2) = \Sabre\Uri\split($prefix);
+
+ if ($prefix2 === $this->principalPrefix) {
+ $user = $this->userManager->get($name2);
+
+ if ($user !== null) {
+ return [
+ 'uri' => 'principals/users/' . $user->getUID() . '/' . $name,
+ ];
+ }
+ return null;
+ }
+ }
+
if ($prefix === $this->principalPrefix) {
$user = $this->userManager->get($name);
@@ -155,23 +179,6 @@ class Principal implements BackendInterface {
}
/**
- * Returns the list of members for a group-principal
- *
- * @param string $principal
- * @return string[]
- * @throws Exception
- */
- public function getGroupMemberSet($principal) {
- // TODO: for now the group principal has only one member, the user itself
- $principal = $this->getPrincipalByPath($principal);
- if (!$principal) {
- throw new Exception('Principal not found');
- }
-
- return [$principal['uri']];
- }
-
- /**
* Returns the list of groups a principal is a member of
*
* @param string $principal
@@ -182,36 +189,30 @@ class Principal implements BackendInterface {
public function getGroupMembership($principal, $needGroups = false) {
list($prefix, $name) = \Sabre\Uri\split($principal);
- if ($prefix === $this->principalPrefix) {
- $user = $this->userManager->get($name);
- if (!$user) {
- throw new Exception('Principal not found');
- }
+ if ($prefix !== $this->principalPrefix) {
+ return [];
+ }
+
+ $user = $this->userManager->get($name);
+ if (!$user) {
+ throw new Exception('Principal not found');
+ }
- if ($this->hasGroups || $needGroups) {
- $groups = $this->groupManager->getUserGroups($user);
- $groups = array_map(function($group) {
- /** @var IGroup $group */
- return 'principals/groups/' . urlencode($group->getGID());
- }, $groups);
+ $groups = [];
- return $groups;
+ if ($this->hasGroups || $needGroups) {
+ $userGroups = $this->groupManager->getUserGroups($user);
+ foreach($userGroups as $userGroup) {
+ $groups[] = 'principals/groups/' . urlencode($userGroup->getGID());
}
}
- return [];
- }
- /**
- * Updates the list of group members for a group principal.
- *
- * The principals should be passed as a list of uri's.
- *
- * @param string $principal
- * @param string[] $members
- * @throws Exception
- */
- public function setGroupMemberSet($principal, array $members) {
- throw new Exception('Setting members of the group is not supported yet');
+ $groups = array_unique(array_merge(
+ $groups,
+ $this->traitGetGroupMembership($principal, $needGroups)
+ ));
+
+ return $groups;
}
/**
@@ -482,5 +483,4 @@ class Principal implements BackendInterface {
return [];
}
-
}
diff --git a/apps/dav/lib/Migration/Version1011Date20190806104428.php b/apps/dav/lib/Migration/Version1011Date20190806104428.php
new file mode 100644
index 00000000000..c144e62bcde
--- /dev/null
+++ b/apps/dav/lib/Migration/Version1011Date20190806104428.php
@@ -0,0 +1,55 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OCA\DAV\Migration;
+
+use Closure;
+use Doctrine\DBAL\Types\Type;
+use OCP\DB\ISchemaWrapper;
+use OCP\Migration\SimpleMigrationStep;
+use OCP\Migration\IOutput;
+
+/**
+ * Auto-generated migration step: Please modify to your needs!
+ */
+class Version1011Date20190806104428 extends SimpleMigrationStep {
+ /**
+ * @param IOutput $output
+ * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param array $options
+ * @return null|ISchemaWrapper
+ */
+ public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ $table = $schema->createTable('dav_cal_proxy');
+ $table->addColumn('id', Type::BIGINT, [
+ 'autoincrement' => true,
+ 'notnull' => true,
+ 'length' => 11,
+ 'unsigned' => true,
+ ]);
+ $table->addColumn('owner_id', Type::STRING, [
+ 'notnull' => true,
+ 'length' => 64,
+ ]);
+ $table->addColumn('proxy_id', Type::STRING, [
+ 'notnull' => true,
+ 'length' => 64,
+ ]);
+ $table->addColumn('permissions', Type::INTEGER, [
+ 'notnull' => false,
+ 'length' => 4,
+ 'unsigned' => true,
+ ]);
+
+ $table->setPrimaryKey(['id']);
+ $table->addUniqueIndex(['owner_id', 'proxy_id', 'permissions'], 'dav_cal_proxy_uidx');
+ $table->addIndex(['owner_id'], 'dav_cal_proxy_ioid');
+ $table->addIndex(['proxy_id'], 'dav_cal_proxy_ipid');
+
+ return $schema;
+ }
+}
diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php
index 38c8b2f6b47..ed8297783d7 100644
--- a/apps/dav/lib/RootCollection.php
+++ b/apps/dav/lib/RootCollection.php
@@ -26,6 +26,7 @@ namespace OCA\DAV;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\CalendarRoot;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\CalDAV\PublicCalendarRoot;
use OCA\DAV\CalDAV\ResourceBooking\ResourcePrincipalBackend;
use OCA\DAV\CalDAV\ResourceBooking\RoomPrincipalBackend;
@@ -53,17 +54,19 @@ class RootCollection extends SimpleCollection {
$shareManager = \OC::$server->getShareManager();
$db = \OC::$server->getDatabaseConnection();
$dispatcher = \OC::$server->getEventDispatcher();
+ $proxyMapper = \OC::$server->query(ProxyMapper::class);
+
$userPrincipalBackend = new Principal(
$userManager,
$groupManager,
$shareManager,
\OC::$server->getUserSession(),
- $config,
- \OC::$server->getAppManager()
+ \OC::$server->getAppManager(),
+ $proxyMapper
);
$groupPrincipalBackend = new GroupPrincipalBackend($groupManager, $userSession, $shareManager, $l10n);
- $calendarResourcePrincipalBackend = new ResourcePrincipalBackend($db, $userSession, $groupManager, $logger);
- $calendarRoomPrincipalBackend = new RoomPrincipalBackend($db, $userSession, $groupManager, $logger);
+ $calendarResourcePrincipalBackend = new ResourcePrincipalBackend($db, $userSession, $groupManager, $logger, $proxyMapper);
+ $calendarRoomPrincipalBackend = new RoomPrincipalBackend($db, $userSession, $groupManager, $logger, $proxyMapper);
// as soon as debug mode is enabled we allow listing of principals
$disableListing = !$config->getSystemValue('debug', false);
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index 7eb68ce5874..cd67b3995a4 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -137,7 +137,8 @@ class Server {
// acl
$acl = new DavAclPlugin();
$acl->principalCollectionSet = [
- 'principals/users', 'principals/groups',
+ 'principals/users',
+ 'principals/groups',
'principals/calendar-resources',
'principals/calendar-rooms',
];
diff --git a/apps/dav/lib/Traits/PrincipalProxyTrait.php b/apps/dav/lib/Traits/PrincipalProxyTrait.php
new file mode 100644
index 00000000000..5e16d3a2f83
--- /dev/null
+++ b/apps/dav/lib/Traits/PrincipalProxyTrait.php
@@ -0,0 +1,223 @@
+<?php
+/**
+ * @copyright 2019, Georg Ehrke <oc.list@georgehrke.com>
+ *
+ * @author Georg Ehrke <oc.list@georgehrke.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCA\DAV\Traits;
+
+use OCA\DAV\CalDAV\Proxy\Proxy;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
+use Sabre\DAV\Exception;
+
+/**
+ * Trait PrincipalTrait
+ *
+ * @package OCA\DAV\Traits
+ */
+trait PrincipalProxyTrait {
+
+ /**
+ * Returns the list of members for a group-principal
+ *
+ * @param string $principal
+ * @return string[]
+ * @throws Exception
+ */
+ public function getGroupMemberSet($principal) {
+ $members = [];
+
+ if ($this->isProxyPrincipal($principal)) {
+ $realPrincipal = $this->getPrincipalUriFromProxyPrincipal($principal);
+ $principalArray = $this->getPrincipalByPath($realPrincipal);
+ if (!$principalArray) {
+ throw new Exception('Principal not found');
+ }
+
+ $proxies = $this->proxyMapper->getProxiesOf($principalArray['uri']);
+ foreach ($proxies as $proxy) {
+ if ($this->isReadProxyPrincipal($principal) && $proxy->getPermissions() === ProxyMapper::PERMISSION_READ) {
+ $members[] = $proxy->getProxyId();
+ }
+
+ if ($this->isWriteProxyPrincipal($principal) && $proxy->getPermissions() === (ProxyMapper::PERMISSION_READ | ProxyMapper::PERMISSION_WRITE)) {
+ $members[] = $proxy->getProxyId();
+ }
+ }
+ }
+
+ return $members;
+ }
+
+ /**
+ * Returns the list of groups a principal is a member of
+ *
+ * @param string $principal
+ * @param bool $needGroups
+ * @return array
+ * @throws Exception
+ */
+ public function getGroupMembership($principal, $needGroups = false) {
+ list($prefix, $name) = \Sabre\Uri\split($principal);
+
+ if ($prefix !== $this->principalPrefix) {
+ return [];
+ }
+
+ $principalArray = $this->getPrincipalByPath($principal);
+ if (!$principalArray) {
+ throw new Exception('Principal not found');
+ }
+
+ $groups = [];
+ $proxies = $this->proxyMapper->getProxiesFor($principal);
+ foreach ($proxies as $proxy) {
+ if ($proxy->getPermissions() === ProxyMapper::PERMISSION_READ) {
+ $groups[] = $proxy->getOwnerId() . '/calendar-proxy-read';
+ }
+
+ if ($proxy->getPermissions() === (ProxyMapper::PERMISSION_READ | ProxyMapper::PERMISSION_WRITE)) {
+ $groups[] = $proxy->getOwnerId() . '/calendar-proxy-write';
+ }
+ }
+
+ return $groups;
+ }
+
+ /**
+ * Updates the list of group members for a group principal.
+ *
+ * The principals should be passed as a list of uri's.
+ *
+ * @param string $principal
+ * @param string[] $members
+ * @throws Exception
+ */
+ public function setGroupMemberSet($principal, array $members) {
+ list($principalUri, $target) = \Sabre\Uri\split($principal);
+
+ if ($target !== 'calendar-proxy-write' && $target !== 'calendar-proxy-read') {
+ throw new Exception('Setting members of the group is not supported yet');
+ }
+
+ $masterPrincipalArray = $this->getPrincipalByPath($principalUri);
+ if (!$masterPrincipalArray) {
+ throw new Exception('Principal not found');
+ }
+
+ $permission = ProxyMapper::PERMISSION_READ;
+ if ($target === 'calendar-proxy-write') {
+ $permission |= ProxyMapper::PERMISSION_WRITE;
+ }
+
+ list($prefix, $owner) = \Sabre\Uri\split($principalUri);
+ $proxies = $this->proxyMapper->getProxiesOf($principalUri);
+
+ foreach ($members as $member) {
+ list($prefix, $name) = \Sabre\Uri\split($member);
+
+ if ($prefix !== $this->principalPrefix) {
+ throw new Exception('Invalid member group prefix: ' . $prefix);
+ }
+
+ $principalArray = $this->getPrincipalByPath($member);
+ if (!$principalArray) {
+ throw new Exception('Principal not found');
+ }
+
+ $found = false;
+ foreach ($proxies as $proxy) {
+ if ($proxy->getProxyId() === $member) {
+ $found = true;
+ $proxy->setPermissions($proxy->getPermissions() | $permission);
+ $this->proxyMapper->update($proxy);
+
+ $proxies = array_filter($proxies, function(Proxy $p) use ($proxy) {
+ return $p->getId() !== $proxy->getId();
+ });
+ break;
+ }
+ }
+
+ if ($found === false) {
+ $proxy = new Proxy();
+ $proxy->setOwnerId($principalUri);
+ $proxy->setProxyId($member);
+ $proxy->setPermissions($permission);
+ $this->proxyMapper->insert($proxy);
+ }
+ }
+
+ // Delete all remaining proxies
+ foreach ($proxies as $proxy) {
+ // Write and Read Proxies have individual requests,
+ // so only delete proxies of this permission
+ if ($proxy->getPermissions() === $permission) {
+ $this->proxyMapper->delete($proxy);
+ }
+ }
+ }
+
+ /**
+ * @param string $principalUri
+ * @return bool
+ */
+ private function isProxyPrincipal(string $principalUri):bool {
+ list($realPrincipalUri, $proxy) = \Sabre\Uri\split($principalUri);
+ list($prefix, $userId) = \Sabre\Uri\split($realPrincipalUri);
+
+ if (!isset($prefix) || !isset($userId)) {
+ return false;
+ }
+ if ($prefix !== $this->principalPrefix) {
+ return false;
+ }
+
+ return $proxy === 'calendar-proxy-read'
+ || $proxy === 'calendar-proxy-write';
+
+ }
+
+ /**
+ * @param string $principalUri
+ * @return bool
+ */
+ private function isReadProxyPrincipal(string $principalUri):bool {
+ list(, $proxy) = \Sabre\Uri\split($principalUri);
+ return $proxy === 'calendar-proxy-read';
+ }
+
+ /**
+ * @param string $principalUri
+ * @return bool
+ */
+ private function isWriteProxyPrincipal(string $principalUri):bool {
+ list(, $proxy) = \Sabre\Uri\split($principalUri);
+ return $proxy === 'calendar-proxy-write';
+ }
+
+ /**
+ * @param string $principalUri
+ * @return string
+ */
+ private function getPrincipalUriFromProxyPrincipal(string $principalUri):string {
+ list($realPrincipalUri, ) = \Sabre\Uri\split($principalUri);
+ return $realPrincipalUri;
+ }
+}
diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php
index 795a04e2cbf..9f9a7c01337 100644
--- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php
+++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php
@@ -26,6 +26,7 @@
namespace OCA\DAV\Tests\unit\CalDAV;
use OCA\DAV\CalDAV\CalDavBackend;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\Connector\Sabre\Principal;
use OCP\App\IAppManager;
use OCP\IConfig;
@@ -83,8 +84,8 @@ abstract class AbstractCalDavBackend extends TestCase {
$this->groupManager,
$this->createMock(ShareManager::class),
$this->createMock(IUserSession::class),
- $this->createMock(IConfig::class),
$this->createMock(IAppManager::class),
+ $this->createMock(ProxyMapper::class),
])
->setMethods(['getPrincipalByPath', 'getGroupMembership'])
->getMock();
diff --git a/apps/dav/tests/unit/CalDAV/CalendarTest.php b/apps/dav/tests/unit/CalDAV/CalendarTest.php
index f467d46bf60..7ce43f40916 100644
--- a/apps/dav/tests/unit/CalDAV/CalendarTest.php
+++ b/apps/dav/tests/unit/CalDAV/CalendarTest.php
@@ -213,21 +213,44 @@ class CalendarTest extends TestCase {
'principal' => $hasOwnerSet ? 'user1' : 'user2',
'protected' => true
], [
- 'privilege' => '{DAV:}write',
- 'principal' => $hasOwnerSet ? 'user1' : 'user2',
- 'protected' => true
+ 'privilege' => '{DAV:}read',
+ 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-write',
+ 'protected' => true,
+ ], [
+ 'privilege' => '{DAV:}read',
+ 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-read',
+ 'protected' => true,
]];
if ($uri === BirthdayService::BIRTHDAY_CALENDAR_URI) {
- $expectedAcl = [[
- 'privilege' => '{DAV:}read',
+ $expectedAcl[] = [
+ 'privilege' => '{DAV:}write-properties',
'principal' => $hasOwnerSet ? 'user1' : 'user2',
'protected' => true
- ], [
+ ];
+ $expectedAcl[] = [
'privilege' => '{DAV:}write-properties',
+ 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-write',
+ 'protected' => true
+ ];
+ } else {
+ $expectedAcl[] = [
+ 'privilege' => '{DAV:}write',
'principal' => $hasOwnerSet ? 'user1' : 'user2',
'protected' => true
- ]];
+ ];
+ $expectedAcl[] = [
+ 'privilege' => '{DAV:}write',
+ 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-write',
+ 'protected' => true
+ ];
}
+
+ $expectedAcl[] = [
+ 'privilege' => '{DAV:}write-properties',
+ 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-read',
+ 'protected' => true
+ ];
+
if ($hasOwnerSet) {
$expectedAcl[] = [
'privilege' => '{DAV:}read',
diff --git a/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php b/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php
index f4019d86e2b..c6e16e2c484 100644
--- a/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php
+++ b/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php
@@ -21,6 +21,8 @@
*/
namespace OCA\DAV\Tests\unit\CalDAV\ResourceBooking;
+use OCA\DAV\CalDAV\Proxy\Proxy;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IGroupManager;
use OCP\ILogger;
@@ -43,6 +45,9 @@ abstract class AbstractPrincipalBackendTest extends TestCase {
/** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
protected $logger;
+ /** @var ProxyMapper|\PHPUnit_Framework_MockObject_MockObject */
+ protected $proxyMapper;
+
/** @var string */
protected $mainDbTable;
@@ -64,6 +69,7 @@ abstract class AbstractPrincipalBackendTest extends TestCase {
$this->userSession = $this->createMock(IUserSession::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->logger = $this->createMock(ILogger::class);
+ $this->proxyMapper = $this->createMock(ProxyMapper::class);
}
protected function tearDown() {
@@ -152,21 +158,113 @@ abstract class AbstractPrincipalBackendTest extends TestCase {
}
public function testGetGroupMemberSet() {
- $actual = $this->principalBackend->getGroupMemberSet($this->principalPrefix . '/foo-bar');
+ $actual = $this->principalBackend->getGroupMemberSet($this->principalPrefix . '/backend1-res1');
$this->assertEquals([], $actual);
}
+ public function testGetGroupMemberSetProxyRead() {
+ $proxy1 = new Proxy();
+ $proxy1->setProxyId('proxyId1');
+ $proxy1->setPermissions(1);
+
+ $proxy2 = new Proxy();
+ $proxy2->setProxyId('proxyId2');
+ $proxy2->setPermissions(3);
+
+ $proxy3 = new Proxy();
+ $proxy3->setProxyId('proxyId3');
+ $proxy3->setPermissions(3);
+
+ $this->proxyMapper->expects($this->once())
+ ->method('getProxiesOf')
+ ->with($this->principalPrefix . '/backend1-res1')
+ ->willReturn([$proxy1, $proxy2, $proxy3]);
+
+ $actual = $this->principalBackend->getGroupMemberSet($this->principalPrefix . '/backend1-res1/calendar-proxy-read');
+ $this->assertEquals(['proxyId1'], $actual);
+ }
+
+ public function testGetGroupMemberSetProxyWrite() {
+ $proxy1 = new Proxy();
+ $proxy1->setProxyId('proxyId1');
+ $proxy1->setPermissions(1);
+
+ $proxy2 = new Proxy();
+ $proxy2->setProxyId('proxyId2');
+ $proxy2->setPermissions(3);
+
+ $proxy3 = new Proxy();
+ $proxy3->setProxyId('proxyId3');
+ $proxy3->setPermissions(3);
+
+ $this->proxyMapper->expects($this->once())
+ ->method('getProxiesOf')
+ ->with($this->principalPrefix . '/backend1-res1')
+ ->willReturn([$proxy1, $proxy2, $proxy3]);
+
+ $actual = $this->principalBackend->getGroupMemberSet($this->principalPrefix . '/backend1-res1/calendar-proxy-write');
+ $this->assertEquals(['proxyId2', 'proxyId3'], $actual);
+ }
+
public function testGetGroupMembership() {
- $actual = $this->principalBackend->getGroupMembership($this->principalPrefix . '/foo-bar');
- $this->assertEquals([], $actual);
+ $proxy1 = new Proxy();
+ $proxy1->setOwnerId('proxyId1');
+ $proxy1->setPermissions(1);
+
+ $proxy2 = new Proxy();
+ $proxy2->setOwnerId('proxyId2');
+ $proxy2->setPermissions(3);
+
+ $this->proxyMapper->expects($this->once())
+ ->method('getProxiesFor')
+ ->with($this->principalPrefix . '/backend1-res1')
+ ->willReturn([$proxy1, $proxy2]);
+
+ $actual = $this->principalBackend->getGroupMembership($this->principalPrefix . '/backend1-res1');
+
+ $this->assertEquals(['proxyId1/calendar-proxy-read', 'proxyId2/calendar-proxy-write'], $actual);
}
- /**
- * @expectedException \Sabre\DAV\Exception
- * @expectedExceptionMessage Setting members of the group is not supported yet
- */
public function testSetGroupMemberSet() {
- $this->principalBackend->setGroupMemberSet($this->principalPrefix . '/foo-bar', ['foo', 'bar']);
+ $this->proxyMapper->expects($this->at(0))
+ ->method('getProxiesOf')
+ ->with($this->principalPrefix . '/backend1-res1')
+ ->willReturn([]);
+
+ $this->proxyMapper->expects($this->at(1))
+ ->method('insert')
+ ->with($this->callback(function($proxy) {
+ /** @var Proxy $proxy */
+ if ($proxy->getOwnerId() !== $this->principalPrefix . '/backend1-res1') {
+ return false;
+ }
+ if ($proxy->getProxyId() !== $this->principalPrefix . '/backend1-res2') {
+ return false;
+ }
+ if ($proxy->getPermissions() !== 3) {
+ return false;
+ }
+
+ return true;
+ }));
+ $this->proxyMapper->expects($this->at(2))
+ ->method('insert')
+ ->with($this->callback(function($proxy) {
+ /** @var Proxy $proxy */
+ if ($proxy->getOwnerId() !== $this->principalPrefix . '/backend1-res1') {
+ return false;
+ }
+ if ($proxy->getProxyId() !== $this->principalPrefix . '/backend2-res3') {
+ return false;
+ }
+ if ($proxy->getPermissions() !== 3) {
+ return false;
+ }
+
+ return true;
+ }));
+
+ $this->principalBackend->setGroupMemberSet($this->principalPrefix . '/backend1-res1/calendar-proxy-write', [$this->principalPrefix . '/backend1-res2', $this->principalPrefix . '/backend2-res3']);
}
public function testUpdatePrincipal() {
diff --git a/apps/dav/tests/unit/CalDAV/ResourceBooking/ResourcePrincipalBackendTest.php b/apps/dav/tests/unit/CalDAV/ResourceBooking/ResourcePrincipalBackendTest.php
index 3787e4df951..461246dd51d 100644
--- a/apps/dav/tests/unit/CalDAV/ResourceBooking/ResourcePrincipalBackendTest.php
+++ b/apps/dav/tests/unit/CalDAV/ResourceBooking/ResourcePrincipalBackendTest.php
@@ -28,7 +28,7 @@ Class ResourcePrincipalBackendTest extends AbstractPrincipalBackendTest {
parent::setUp();
$this->principalBackend = new ResourcePrincipalBackend(self::$realDatabase,
- $this->userSession, $this->groupManager, $this->logger);
+ $this->userSession, $this->groupManager, $this->logger, $this->proxyMapper);
$this->mainDbTable = 'calendar_resources';
$this->metadataDbTable = 'calendar_resources_md';
diff --git a/apps/dav/tests/unit/CalDAV/ResourceBooking/RoomPrincipalBackendTest.php b/apps/dav/tests/unit/CalDAV/ResourceBooking/RoomPrincipalBackendTest.php
index 9b259c30adf..6b691400cd1 100644
--- a/apps/dav/tests/unit/CalDAV/ResourceBooking/RoomPrincipalBackendTest.php
+++ b/apps/dav/tests/unit/CalDAV/ResourceBooking/RoomPrincipalBackendTest.php
@@ -28,7 +28,7 @@ Class RoomPrincipalBackendTest extends AbstractPrincipalBackendTest {
parent::setUp();
$this->principalBackend = new RoomPrincipalBackend(self::$realDatabase,
- $this->userSession, $this->groupManager, $this->logger);
+ $this->userSession, $this->groupManager, $this->logger, $this->proxyMapper);
$this->mainDbTable = 'calendar_rooms';
$this->metadataDbTable = 'calendar_rooms_md';
diff --git a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php
index 531f50e96c2..aa18ef63a5c 100644
--- a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php
+++ b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php
@@ -32,6 +32,7 @@
namespace OCA\DAV\Tests\unit\CardDAV;
use InvalidArgumentException;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\CardDAV\AddressBook;
use OCA\DAV\CardDAV\CardDavBackend;
use OCA\DAV\Connector\Sabre\Principal;
@@ -131,8 +132,8 @@ class CardDavBackendTest extends TestCase {
$this->groupManager,
$this->createMock(ShareManager::class),
$this->createMock(IUserSession::class),
- $this->createMock(IConfig::class),
$this->createMock(IAppManager::class),
+ $this->createMock(ProxyMapper::class),
])
->setMethods(['getPrincipalByPath', 'getGroupMembership'])
->getMock();
diff --git a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php
index 225189e7d01..2a5c122ce9e 100644
--- a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php
+++ b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php
@@ -29,6 +29,8 @@
namespace OCA\DAV\Tests\unit\Connector\Sabre;
use OC\User\User;
+use OCA\DAV\CalDAV\Proxy\Proxy;
+use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCP\App\IAppManager;
use OCP\IConfig;
use OCP\IGroup;
@@ -57,27 +59,27 @@ class PrincipalTest extends TestCase {
/** @var IUserSession | \PHPUnit_Framework_MockObject_MockObject */
private $userSession;
- /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */
- private $config;
-
/** @var IAppManager | \PHPUnit_Framework_MockObject_MockObject */
private $appManager;
+ /** @var ProxyMapper | \PHPUnit_Framework_MockObject_MockObject */
+ private $proxyMapper;
+
public function setUp() {
$this->userManager = $this->createMock(IUserManager::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->shareManager = $this->createMock(IManager::class);
$this->userSession = $this->createMock(IUserSession::class);
- $this->config = $this->createMock(IConfig::class);
$this->appManager = $this->createMock(IAppManager::class);
+ $this->proxyMapper = $this->createMock(ProxyMapper::class);
$this->connector = new \OCA\DAV\Connector\Sabre\Principal(
$this->userManager,
$this->groupManager,
$this->shareManager,
$this->userSession,
- $this->config,
- $this->appManager
+ $this->appManager,
+ $this->proxyMapper
);
parent::setUp();
}
@@ -203,6 +205,25 @@ class PrincipalTest extends TestCase {
}
public function testGetGroupMemberSet() {
+ $response = $this->connector->getGroupMemberSet('principals/users/foo');
+ $this->assertSame([], $response);
+ }
+
+ /**
+ * @expectedException \Sabre\DAV\Exception
+ * @expectedExceptionMessage Principal not found
+ */
+ public function testGetGroupMemberSetEmpty() {
+ $this->userManager
+ ->expects($this->once())
+ ->method('get')
+ ->with('foo')
+ ->will($this->returnValue(null));
+
+ $this->connector->getGroupMemberSet('principals/users/foo/calendar-proxy-read');
+ }
+
+ public function testGetGroupMemberSetProxyRead() {
$fooUser = $this->createMock(User::class);
$fooUser
->expects($this->exactly(1))
@@ -214,22 +235,56 @@ class PrincipalTest extends TestCase {
->with('foo')
->will($this->returnValue($fooUser));
- $response = $this->connector->getGroupMemberSet('principals/users/foo');
- $this->assertSame(['principals/users/foo'], $response);
+ $proxy1 = new Proxy();
+ $proxy1->setProxyId('proxyId1');
+ $proxy1->setPermissions(1);
+
+ $proxy2 = new Proxy();
+ $proxy2->setProxyId('proxyId2');
+ $proxy2->setPermissions(3);
+
+ $proxy3 = new Proxy();
+ $proxy3->setProxyId('proxyId3');
+ $proxy3->setPermissions(3);
+
+ $this->proxyMapper->expects($this->once())
+ ->method('getProxiesOf')
+ ->with('principals/users/foo')
+ ->willReturn([$proxy1, $proxy2, $proxy3]);
+
+ $this->assertEquals(['proxyId1'], $this->connector->getGroupMemberSet('principals/users/foo/calendar-proxy-read'));
}
- /**
- * @expectedException \Sabre\DAV\Exception
- * @expectedExceptionMessage Principal not found
- */
- public function testGetGroupMemberSetEmpty() {
+ public function testGetGroupMemberSetProxyWrite() {
+ $fooUser = $this->createMock(User::class);
+ $fooUser
+ ->expects($this->exactly(1))
+ ->method('getUID')
+ ->will($this->returnValue('foo'));
$this->userManager
->expects($this->once())
->method('get')
->with('foo')
- ->will($this->returnValue(null));
+ ->will($this->returnValue($fooUser));
+
+ $proxy1 = new Proxy();
+ $proxy1->setProxyId('proxyId1');
+ $proxy1->setPermissions(1);
+
+ $proxy2 = new Proxy();
+ $proxy2->setProxyId('proxyId2');
+ $proxy2->setPermissions(3);
+
+ $proxy3 = new Proxy();
+ $proxy3->setProxyId('proxyId3');
+ $proxy3->setPermissions(3);
- $this->connector->getGroupMemberSet('principals/users/foo');
+ $this->proxyMapper->expects($this->once())
+ ->method('getProxiesOf')
+ ->with('principals/users/foo')
+ ->willReturn([$proxy1, $proxy2, $proxy3]);
+
+ $this->assertEquals(['proxyId2', 'proxyId3'], $this->connector->getGroupMemberSet('principals/users/foo/calendar-proxy-write'));
}
public function testGetGroupMembership() {
@@ -243,7 +298,7 @@ class PrincipalTest extends TestCase {
->method('getGID')
->willReturn('foo/bar');
$this->userManager
- ->expects($this->once())
+ ->expects($this->exactly(2))
->method('get')
->with('foo')
->willReturn($fooUser);
@@ -256,9 +311,24 @@ class PrincipalTest extends TestCase {
$group2,
]);
+ $proxy1 = new Proxy();
+ $proxy1->setOwnerId('proxyId1');
+ $proxy1->setPermissions(1);
+
+ $proxy2 = new Proxy();
+ $proxy2->setOwnerId('proxyId2');
+ $proxy2->setPermissions(3);
+
+ $this->proxyMapper->expects($this->once())
+ ->method('getProxiesFor')
+ ->with('principals/users/foo')
+ ->willReturn([$proxy1, $proxy2]);
+
$expectedResponse = [
'principals/groups/group1',
'principals/groups/foo%2Fbar',
+ 'proxyId1/calendar-proxy-read',
+ 'proxyId2/calendar-proxy-write',
];
$response = $this->connector->getGroupMembership('principals/users/foo');
$this->assertSame($expectedResponse, $response);
@@ -286,6 +356,58 @@ class PrincipalTest extends TestCase {
$this->connector->setGroupMemberSet('principals/users/foo', ['foo']);
}
+ public function testSetGroupMembershipProxy() {
+ $fooUser = $this->createMock(User::class);
+ $fooUser
+ ->expects($this->exactly(1))
+ ->method('getUID')
+ ->will($this->returnValue('foo'));
+ $barUser = $this->createMock(User::class);
+ $barUser
+ ->expects($this->exactly(1))
+ ->method('getUID')
+ ->will($this->returnValue('bar'));
+ $this->userManager
+ ->expects($this->at(0))
+ ->method('get')
+ ->with('foo')
+ ->will($this->returnValue($fooUser));
+ $this->userManager
+ ->expects($this->at(1))
+ ->method('get')
+ ->with('bar')
+ ->will($this->returnValue($barUser));
+
+ $this->proxyMapper->expects($this->at(0))
+ ->method('getProxiesOf')
+ ->with('principals/users/foo')
+ ->willReturn([]);
+
+ $this->proxyMapper->expects($this->at(1))
+ ->method('insert')
+ ->with($this->callback(function($proxy) {
+ /** @var Proxy $proxy */
+ if ($proxy->getOwnerId() !== 'principals/users/foo') {
+ return false;
+ }
+ if ($proxy->getProxyId() !== 'principals/users/bar') {
+ return false;
+ }
+ if ($proxy->getPermissions() !== 3) {
+ return false;
+ }
+
+ return true;
+ }));
+
+ $this->connector->setGroupMemberSet('principals/users/foo/calendar-proxy-write', ['principals/users/bar']);
+ }
+
+
+
+
+
+
public function testUpdatePrincipal() {
$this->assertSame(0, $this->connector->updatePrincipal('foo', new PropPatch(array())));
}