Merge pull request #16666 from nextcloud/feature/calendar/delegation
Feature/calendar/delegation
This commit is contained in:
commit
f452e23a7d
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*
|
||||
|
@ -215,39 +224,6 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
|
|||
return $this->rowToPrincipal($row, $metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -154,23 +178,6 @@ class Principal implements BackendInterface {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
||||
if ($this->hasGroups || $needGroups) {
|
||||
$groups = $this->groupManager->getUserGroups($user);
|
||||
$groups = array_map(function($group) {
|
||||
/** @var IGroup $group */
|
||||
return 'principals/groups/' . urlencode($group->getGID());
|
||||
}, $groups);
|
||||
$user = $this->userManager->get($name);
|
||||
if (!$user) {
|
||||
throw new Exception('Principal not found');
|
||||
}
|
||||
|
||||
return $groups;
|
||||
$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 [];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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',
|
||||
];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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',
|
||||
'principal' => $hasOwnerSet ? 'user1' : 'user2',
|
||||
'protected' => true
|
||||
], [
|
||||
$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',
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,19 +205,8 @@ class PrincipalTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetGroupMemberSet() {
|
||||
$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($fooUser));
|
||||
|
||||
$response = $this->connector->getGroupMemberSet('principals/users/foo');
|
||||
$this->assertSame(['principals/users/foo'], $response);
|
||||
$this->assertSame([], $response);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,7 +220,71 @@ class PrincipalTest extends TestCase {
|
|||
->with('foo')
|
||||
->will($this->returnValue(null));
|
||||
|
||||
$this->connector->getGroupMemberSet('principals/users/foo');
|
||||
$this->connector->getGroupMemberSet('principals/users/foo/calendar-proxy-read');
|
||||
}
|
||||
|
||||
public function testGetGroupMemberSetProxyRead() {
|
||||
$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($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->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'));
|
||||
}
|
||||
|
||||
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($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->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())));
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace OCA\Files_Trashbin\AppInfo;
|
||||
|
||||
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
|
||||
use OCA\DAV\Connector\Sabre\Principal;
|
||||
use OCA\Files_Trashbin\Trash\ITrashManager;
|
||||
use OCA\Files_Trashbin\Trash\TrashManager;
|
||||
|
@ -61,8 +62,8 @@ class Application extends App {
|
|||
\OC::$server->getGroupManager(),
|
||||
\OC::$server->getShareManager(),
|
||||
\OC::$server->getUserSession(),
|
||||
\OC::$server->getConfig(),
|
||||
\OC::$server->getAppManager()
|
||||
\OC::$server->getAppManager(),
|
||||
\OC::$server->query(ProxyMapper::class)
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace OCA\Files_Versions\AppInfo;
|
||||
|
||||
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
|
||||
use OCA\DAV\Connector\Sabre\Principal;
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCA\Files_Versions\Versions\VersionManager;
|
||||
|
@ -51,8 +52,8 @@ class Application extends App {
|
|||
$server->getGroupManager(),
|
||||
$server->getShareManager(),
|
||||
$server->getUserSession(),
|
||||
$server->getConfig(),
|
||||
$server->getAppManager()
|
||||
$server->getAppManager(),
|
||||
$server->query(ProxyMapper::class)
|
||||
);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue