Merge pull request #21817 from owncloud/support-old-carddav-endpoint
Adding pre oc 9.0 CardDAV endpoint for migration of old clients
This commit is contained in:
commit
33eed35ae4
|
@ -14,6 +14,12 @@
|
||||||
<files>appinfo/v1/webdav.php</files>
|
<files>appinfo/v1/webdav.php</files>
|
||||||
<webdav>appinfo/v1/webdav.php</webdav>
|
<webdav>appinfo/v1/webdav.php</webdav>
|
||||||
<dav>appinfo/v2/remote.php</dav>
|
<dav>appinfo/v2/remote.php</dav>
|
||||||
|
<!-- carddav endpoints as used before ownCloud 9.0 -->
|
||||||
|
<contacts>appinfo/v1/carddav.php</contacts>
|
||||||
|
<carddav>appinfo/v1/carddav.php</carddav>
|
||||||
|
<!-- caldav endpoints as used before ownCloud 9.0 -->
|
||||||
|
<calendar>appinfo/v1/caldav.php</calendar>
|
||||||
|
<caldav>appinfo/v1/caldav.php</caldav>
|
||||||
</remote>
|
</remote>
|
||||||
<public>
|
<public>
|
||||||
<webdav>appinfo/v1/publicwebdav.php</webdav>
|
<webdav>appinfo/v1/publicwebdav.php</webdav>
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Backends
|
||||||
|
use OCA\DAV\CalDAV\CalDavBackend;
|
||||||
|
use OCA\DAV\Connector\Sabre\Auth;
|
||||||
|
use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin;
|
||||||
|
use OCA\DAV\Connector\Sabre\MaintenancePlugin;
|
||||||
|
use OCA\DAV\Connector\Sabre\Principal;
|
||||||
|
use Sabre\CalDAV\CalendarRoot;
|
||||||
|
|
||||||
|
$authBackend = new Auth(
|
||||||
|
\OC::$server->getSession(),
|
||||||
|
\OC::$server->getUserSession(),
|
||||||
|
'principals/'
|
||||||
|
);
|
||||||
|
$principalBackend = new Principal(
|
||||||
|
\OC::$server->getUserManager(),
|
||||||
|
\OC::$server->getGroupManager(),
|
||||||
|
'principals/'
|
||||||
|
);
|
||||||
|
$db = \OC::$server->getDatabaseConnection();
|
||||||
|
$calDavBackend = new CalDavBackend($db, $principalBackend);
|
||||||
|
|
||||||
|
// Root nodes
|
||||||
|
$principalCollection = new \Sabre\CalDAV\Principal\Collection($principalBackend);
|
||||||
|
$principalCollection->disableListing = true; // Disable listing
|
||||||
|
|
||||||
|
$addressBookRoot = new CalendarRoot($principalBackend, $calDavBackend);
|
||||||
|
$addressBookRoot->disableListing = true; // Disable listing
|
||||||
|
|
||||||
|
$nodes = array(
|
||||||
|
$principalCollection,
|
||||||
|
$addressBookRoot,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fire up server
|
||||||
|
$server = new \Sabre\DAV\Server($nodes);
|
||||||
|
$server->httpRequest->setUrl(\OC::$server->getRequest()->getRequestUri());
|
||||||
|
$server->setBaseUri($baseuri);
|
||||||
|
|
||||||
|
// Add plugins
|
||||||
|
$server->addPlugin(new MaintenancePlugin());
|
||||||
|
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, 'ownCloud'));
|
||||||
|
$server->addPlugin(new \Sabre\CalDAV\Plugin());
|
||||||
|
$server->addPlugin(new \Sabre\DAVACL\Plugin());
|
||||||
|
$server->addPlugin(new \Sabre\CalDAV\ICSExportPlugin());
|
||||||
|
$server->addPlugin(new ExceptionLoggerPlugin('caldav', \OC::$server->getLogger()));
|
||||||
|
|
||||||
|
// And off we go!
|
||||||
|
$server->exec();
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Backends
|
||||||
|
use OCA\DAV\CardDAV\AddressBookRoot;
|
||||||
|
use OCA\DAV\CardDAV\CardDavBackend;
|
||||||
|
use OCA\DAV\Connector\Sabre\AppEnabledPlugin;
|
||||||
|
use OCA\DAV\Connector\Sabre\Auth;
|
||||||
|
use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin;
|
||||||
|
use OCA\DAV\Connector\Sabre\MaintenancePlugin;
|
||||||
|
use OCA\DAV\Connector\Sabre\Principal;
|
||||||
|
use Sabre\CardDAV\Plugin;
|
||||||
|
|
||||||
|
$authBackend = new Auth(
|
||||||
|
\OC::$server->getSession(),
|
||||||
|
\OC::$server->getUserSession(),
|
||||||
|
'principals/'
|
||||||
|
);
|
||||||
|
$principalBackend = new Principal(
|
||||||
|
\OC::$server->getUserManager(),
|
||||||
|
\OC::$server->getGroupManager(),
|
||||||
|
'principals/'
|
||||||
|
);
|
||||||
|
$db = \OC::$server->getDatabaseConnection();
|
||||||
|
$cardDavBackend = new CardDavBackend($db, $principalBackend);
|
||||||
|
|
||||||
|
// Root nodes
|
||||||
|
$principalCollection = new \Sabre\CalDAV\Principal\Collection($principalBackend);
|
||||||
|
$principalCollection->disableListing = true; // Disable listing
|
||||||
|
|
||||||
|
$addressBookRoot = new AddressBookRoot($principalBackend, $cardDavBackend);
|
||||||
|
$addressBookRoot->disableListing = true; // Disable listing
|
||||||
|
|
||||||
|
$nodes = array(
|
||||||
|
$principalCollection,
|
||||||
|
$addressBookRoot,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fire up server
|
||||||
|
$server = new \Sabre\DAV\Server($nodes);
|
||||||
|
$server->httpRequest->setUrl(\OC::$server->getRequest()->getRequestUri());
|
||||||
|
$server->setBaseUri($baseuri);
|
||||||
|
// Add plugins
|
||||||
|
$server->addPlugin(new MaintenancePlugin());
|
||||||
|
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, 'ownCloud'));
|
||||||
|
$server->addPlugin(new Plugin());
|
||||||
|
$server->addPlugin(new \Sabre\DAVACL\Plugin());
|
||||||
|
$server->addPlugin(new \Sabre\CardDAV\VCFExportPlugin());
|
||||||
|
$server->addPlugin(new ExceptionLoggerPlugin('carddav', \OC::$server->getLogger()));
|
||||||
|
|
||||||
|
// And off we go!
|
||||||
|
$server->exec();
|
|
@ -40,7 +40,8 @@ $serverFactory = new \OCA\DAV\Connector\Sabre\ServerFactory(
|
||||||
// Backends
|
// Backends
|
||||||
$authBackend = new \OCA\DAV\Connector\Sabre\Auth(
|
$authBackend = new \OCA\DAV\Connector\Sabre\Auth(
|
||||||
\OC::$server->getSession(),
|
\OC::$server->getSession(),
|
||||||
\OC::$server->getUserSession()
|
\OC::$server->getUserSession(),
|
||||||
|
'principals/'
|
||||||
);
|
);
|
||||||
$requestUri = \OC::$server->getRequest()->getRequestUri();
|
$requestUri = \OC::$server->getRequest()->getRequestUri();
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,9 @@ class AddressBookRoot extends \Sabre\CardDAV\AddressBookRoot {
|
||||||
|
|
||||||
function getName() {
|
function getName() {
|
||||||
|
|
||||||
|
if ($this->principalPrefix === 'principals') {
|
||||||
|
return parent::getName();
|
||||||
|
}
|
||||||
// Grabbing all the components of the principal path.
|
// Grabbing all the components of the principal path.
|
||||||
$parts = explode('/', $this->principalPrefix);
|
$parts = explode('/', $this->principalPrefix);
|
||||||
|
|
||||||
|
|
|
@ -93,11 +93,11 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function getAddressBooksForUser($principalUri) {
|
function getAddressBooksForUser($principalUri) {
|
||||||
|
$principalUri = $this->convertPrincipal($principalUri, true);
|
||||||
$query = $this->db->getQueryBuilder();
|
$query = $this->db->getQueryBuilder();
|
||||||
$query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken'])
|
$query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken'])
|
||||||
->from('addressbooks')
|
->from('addressbooks')
|
||||||
->where($query->expr()->eq('principaluri', $query->createParameter('principaluri')))
|
->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)));
|
||||||
->setParameter('principaluri', $principalUri);
|
|
||||||
|
|
||||||
$addressBooks = [];
|
$addressBooks = [];
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
||||||
$addressBooks[$row['id']] = [
|
$addressBooks[$row['id']] = [
|
||||||
'id' => $row['id'],
|
'id' => $row['id'],
|
||||||
'uri' => $row['uri'],
|
'uri' => $row['uri'],
|
||||||
'principaluri' => $row['principaluri'],
|
'principaluri' => $this->convertPrincipal($row['principaluri'], false),
|
||||||
'{DAV:}displayname' => $row['displayname'],
|
'{DAV:}displayname' => $row['displayname'],
|
||||||
'{' . Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'],
|
'{' . Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'],
|
||||||
'{http://calendarserver.org/ns/}getctag' => $row['synctoken'],
|
'{http://calendarserver.org/ns/}getctag' => $row['synctoken'],
|
||||||
|
@ -921,4 +921,15 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
||||||
public function applyShareAcl($addressBookId, $acl) {
|
public function applyShareAcl($addressBookId, $acl) {
|
||||||
return $this->sharingBackend->applyShareAcl($addressBookId, $acl);
|
return $this->sharingBackend->applyShareAcl($addressBookId, $acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function convertPrincipal($principalUri, $toV2) {
|
||||||
|
if ($this->principalBackend->getPrincipalPrefix() === 'principals') {
|
||||||
|
list(, $name) = URLUtil::splitPath($principalUri);
|
||||||
|
if ($toV2 === true) {
|
||||||
|
return "principals/users/$name";
|
||||||
|
}
|
||||||
|
return "principals/$name";
|
||||||
|
}
|
||||||
|
return $principalUri;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,12 +49,14 @@ class Auth extends AbstractBasic {
|
||||||
/**
|
/**
|
||||||
* @param ISession $session
|
* @param ISession $session
|
||||||
* @param IUserSession $userSession
|
* @param IUserSession $userSession
|
||||||
|
* @param string $principalPrefix
|
||||||
*/
|
*/
|
||||||
public function __construct(ISession $session,
|
public function __construct(ISession $session,
|
||||||
IUserSession $userSession) {
|
IUserSession $userSession,
|
||||||
|
$principalPrefix = 'principals/users/') {
|
||||||
$this->session = $session;
|
$this->session = $session;
|
||||||
$this->userSession = $userSession;
|
$this->userSession = $userSession;
|
||||||
$this->principalPrefix = 'principals/users/';
|
$this->principalPrefix = $principalPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -46,12 +46,20 @@ class Principal implements BackendInterface {
|
||||||
/** @var IGroupManager */
|
/** @var IGroupManager */
|
||||||
private $groupManager;
|
private $groupManager;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $principalPrefix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param IUserManager $userManager
|
* @param IUserManager $userManager
|
||||||
|
* @param IGroupManager $groupManager
|
||||||
|
* @param string $principalPrefix
|
||||||
*/
|
*/
|
||||||
public function __construct(IUserManager $userManager, IGroupManager $groupManager) {
|
public function __construct(IUserManager $userManager,
|
||||||
|
IGroupManager $groupManager,
|
||||||
|
$principalPrefix = 'principals/users/') {
|
||||||
$this->userManager = $userManager;
|
$this->userManager = $userManager;
|
||||||
$this->groupManager = $groupManager;
|
$this->groupManager = $groupManager;
|
||||||
|
$this->principalPrefix = trim($principalPrefix, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +78,7 @@ class Principal implements BackendInterface {
|
||||||
public function getPrincipalsByPrefix($prefixPath) {
|
public function getPrincipalsByPrefix($prefixPath) {
|
||||||
$principals = [];
|
$principals = [];
|
||||||
|
|
||||||
if ($prefixPath === 'principals/users') {
|
if ($prefixPath === $this->principalPrefix) {
|
||||||
foreach($this->userManager->search('') as $user) {
|
foreach($this->userManager->search('') as $user) {
|
||||||
$principals[] = $this->userToPrincipal($user);
|
$principals[] = $this->userToPrincipal($user);
|
||||||
}
|
}
|
||||||
|
@ -88,20 +96,15 @@ class Principal implements BackendInterface {
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getPrincipalByPath($path) {
|
public function getPrincipalByPath($path) {
|
||||||
$elements = explode('/', $path);
|
list($prefix, $name) = URLUtil::splitPath($path);
|
||||||
if ($elements[0] !== 'principals') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if ($elements[1] !== 'users') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$name = $elements[2];
|
|
||||||
$user = $this->userManager->get($name);
|
|
||||||
|
|
||||||
if (!is_null($user)) {
|
if ($prefix === $this->principalPrefix) {
|
||||||
return $this->userToPrincipal($user);
|
$user = $this->userManager->get($name);
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!is_null($user)) {
|
||||||
|
return $this->userToPrincipal($user);
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +135,7 @@ class Principal implements BackendInterface {
|
||||||
public function getGroupMembership($principal) {
|
public function getGroupMembership($principal) {
|
||||||
list($prefix, $name) = URLUtil::splitPath($principal);
|
list($prefix, $name) = URLUtil::splitPath($principal);
|
||||||
|
|
||||||
if ($prefix === 'principals/users') {
|
if ($prefix === $this->principalPrefix) {
|
||||||
$user = $this->userManager->get($name);
|
$user = $this->userManager->get($name);
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
throw new Exception('Principal not found');
|
throw new Exception('Principal not found');
|
||||||
|
@ -141,11 +144,9 @@ class Principal implements BackendInterface {
|
||||||
$groups = $this->groupManager->getUserGroups($user);
|
$groups = $this->groupManager->getUserGroups($user);
|
||||||
$groups = array_map(function($group) {
|
$groups = array_map(function($group) {
|
||||||
/** @var IGroup $group */
|
/** @var IGroup $group */
|
||||||
return 'principals/groups/' . $group->getGID();
|
return $this->principalPrefix . '/' . $group->getGID();
|
||||||
}, $groups);
|
}, $groups);
|
||||||
|
|
||||||
$groups[]= 'principals/users/'.$name.'/calendar-proxy-read';
|
|
||||||
$groups[]= 'principals/users/'.$name.'/calendar-proxy-write';
|
|
||||||
return $groups;
|
return $groups;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
|
@ -200,7 +201,7 @@ class Principal implements BackendInterface {
|
||||||
$userId = $user->getUID();
|
$userId = $user->getUID();
|
||||||
$displayName = $user->getDisplayName();
|
$displayName = $user->getDisplayName();
|
||||||
$principal = [
|
$principal = [
|
||||||
'uri' => "principals/users/$userId",
|
'uri' => $this->principalPrefix . '/' . $userId,
|
||||||
'{DAV:}displayname' => is_null($displayName) ? $userId : $displayName,
|
'{DAV:}displayname' => is_null($displayName) ? $userId : $displayName,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -212,4 +213,8 @@ class Principal implements BackendInterface {
|
||||||
return $principal;
|
return $principal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPrincipalPrefix() {
|
||||||
|
return $this->principalPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,10 +211,7 @@ class Principal extends TestCase {
|
||||||
->method('getUserGroups')
|
->method('getUserGroups')
|
||||||
->willReturn([]);
|
->willReturn([]);
|
||||||
|
|
||||||
$expectedResponse = [
|
$expectedResponse = [];
|
||||||
'principals/users/foo/calendar-proxy-read',
|
|
||||||
'principals/users/foo/calendar-proxy-write'
|
|
||||||
];
|
|
||||||
$response = $this->connector->getGroupMembership('principals/users/foo');
|
$response = $this->connector->getGroupMembership('principals/users/foo');
|
||||||
$this->assertSame($expectedResponse, $response);
|
$this->assertSame($expectedResponse, $response);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue