@@ -14,7 +14,9 @@ | |||
<files>appinfo/v1/webdav.php</files> | |||
<webdav>appinfo/v1/webdav.php</webdav> | |||
<dav>appinfo/v2/remote.php</dav> | |||
</remote> | |||
<!-- carddav endpoints as used before ownCloud 9.0--> | |||
<contacts>appinfo/v1/carddav.php</contacts> | |||
<carddav>appinfo/v1/carddav.php</carddav> </remote> | |||
<public> | |||
<webdav>appinfo/v1/publicwebdav.php</webdav> | |||
</public> |
@@ -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 | |||
$authBackend = new \OCA\DAV\Connector\Sabre\Auth( | |||
\OC::$server->getSession(), | |||
\OC::$server->getUserSession() | |||
\OC::$server->getUserSession(), | |||
'principals/' | |||
); | |||
$requestUri = \OC::$server->getRequest()->getRequestUri(); | |||
@@ -40,6 +40,9 @@ class AddressBookRoot extends \Sabre\CardDAV\AddressBookRoot { | |||
function getName() { | |||
if ($this->principalPrefix === 'principals') { | |||
return parent::getName(); | |||
} | |||
// Grabbing all the components of the principal path. | |||
$parts = explode('/', $this->principalPrefix); | |||
@@ -93,11 +93,11 @@ class CardDavBackend implements BackendInterface, SyncSupport { | |||
* @return array | |||
*/ | |||
function getAddressBooksForUser($principalUri) { | |||
$principalUri = $this->convertPrincipal($principalUri, true); | |||
$query = $this->db->getQueryBuilder(); | |||
$query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken']) | |||
->from('addressbooks') | |||
->where($query->expr()->eq('principaluri', $query->createParameter('principaluri'))) | |||
->setParameter('principaluri', $principalUri); | |||
->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri))); | |||
$addressBooks = []; | |||
@@ -106,7 +106,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { | |||
$addressBooks[$row['id']] = [ | |||
'id' => $row['id'], | |||
'uri' => $row['uri'], | |||
'principaluri' => $row['principaluri'], | |||
'principaluri' => $this->convertPrincipal($row['principaluri'], false), | |||
'{DAV:}displayname' => $row['displayname'], | |||
'{' . Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'], | |||
'{http://calendarserver.org/ns/}getctag' => $row['synctoken'], | |||
@@ -919,4 +919,15 @@ class CardDavBackend implements BackendInterface, SyncSupport { | |||
public function 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 IUserSession $userSession | |||
* @param string $principalPrefix | |||
*/ | |||
public function __construct(ISession $session, | |||
IUserSession $userSession) { | |||
IUserSession $userSession, | |||
$principalPrefix = 'principals/users/') { | |||
$this->session = $session; | |||
$this->userSession = $userSession; | |||
$this->principalPrefix = 'principals/users/'; | |||
$this->principalPrefix = $principalPrefix; | |||
} | |||
/** |
@@ -46,12 +46,20 @@ class Principal implements BackendInterface { | |||
/** @var IGroupManager */ | |||
private $groupManager; | |||
/** @var string */ | |||
private $principalPrefix; | |||
/** | |||
* @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->groupManager = $groupManager; | |||
$this->principalPrefix = trim($principalPrefix, '/'); | |||
} | |||
/** | |||
@@ -70,7 +78,7 @@ class Principal implements BackendInterface { | |||
public function getPrincipalsByPrefix($prefixPath) { | |||
$principals = []; | |||
if ($prefixPath === 'principals/users') { | |||
if ($prefixPath === $this->principalPrefix) { | |||
foreach($this->userManager->search('') as $user) { | |||
$principals[] = $this->userToPrincipal($user); | |||
} | |||
@@ -88,20 +96,15 @@ class Principal implements BackendInterface { | |||
* @return array | |||
*/ | |||
public function getPrincipalByPath($path) { | |||
$elements = explode('/', $path); | |||
if ($elements[0] !== 'principals') { | |||
return null; | |||
} | |||
if ($elements[1] !== 'users') { | |||
return null; | |||
} | |||
$name = $elements[2]; | |||
$user = $this->userManager->get($name); | |||
list($prefix, $name) = URLUtil::splitPath($path); | |||
if (!is_null($user)) { | |||
return $this->userToPrincipal($user); | |||
} | |||
if ($prefix === $this->principalPrefix) { | |||
$user = $this->userManager->get($name); | |||
if (!is_null($user)) { | |||
return $this->userToPrincipal($user); | |||
} | |||
} | |||
return null; | |||
} | |||
@@ -132,7 +135,7 @@ class Principal implements BackendInterface { | |||
public function getGroupMembership($principal) { | |||
list($prefix, $name) = URLUtil::splitPath($principal); | |||
if ($prefix === 'principals/users') { | |||
if ($prefix === $this->principalPrefix) { | |||
$user = $this->userManager->get($name); | |||
if (!$user) { | |||
throw new Exception('Principal not found'); | |||
@@ -141,11 +144,11 @@ class Principal implements BackendInterface { | |||
$groups = $this->groupManager->getUserGroups($user); | |||
$groups = array_map(function($group) { | |||
/** @var IGroup $group */ | |||
return 'principals/groups/' . $group->getGID(); | |||
return $this->principalPrefix . '/' . $group->getGID(); | |||
}, $groups); | |||
$groups[]= 'principals/users/'.$name.'/calendar-proxy-read'; | |||
$groups[]= 'principals/users/'.$name.'/calendar-proxy-write'; | |||
// $groups[]= $this->principalPrefix . '/' . $name . '/calendar-proxy-read'; | |||
// $groups[]= $this->principalPrefix . '/' . $name . '/calendar-proxy-write'; | |||
return $groups; | |||
} | |||
return []; | |||
@@ -200,7 +203,7 @@ class Principal implements BackendInterface { | |||
$userId = $user->getUID(); | |||
$displayName = $user->getDisplayName(); | |||
$principal = [ | |||
'uri' => "principals/users/$userId", | |||
'uri' => $this->principalPrefix . '/' . $userId, | |||
'{DAV:}displayname' => is_null($displayName) ? $userId : $displayName, | |||
]; | |||
@@ -212,4 +215,8 @@ class Principal implements BackendInterface { | |||
return $principal; | |||
} | |||
public function getPrincipalPrefix() { | |||
return $this->principalPrefix; | |||
} | |||
} |