diff options
-rw-r--r-- | apps/dav/appinfo/app.php | 12 | ||||
-rw-r--r-- | apps/dav/appinfo/application.php | 29 | ||||
-rw-r--r-- | apps/dav/command/syncsystemaddressbook.php | 73 | ||||
-rw-r--r-- | apps/dav/lib/carddav/syncservice.php | 85 | ||||
-rw-r--r-- | apps/dav/lib/hookmanager.php | 74 | ||||
-rw-r--r-- | apps/dav/tests/unit/carddav/syncservicetest.php | 3 |
6 files changed, 199 insertions, 77 deletions
diff --git a/apps/dav/appinfo/app.php b/apps/dav/appinfo/app.php index 5ba7278e88e..5cccab98f17 100644 --- a/apps/dav/appinfo/app.php +++ b/apps/dav/appinfo/app.php @@ -22,18 +22,16 @@ use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\CardDAV\SyncService; -\OC::$server->registerService('CardDAVSyncService', function() { +$app = new \OCA\Dav\AppInfo\Application(); +$app->registerHooks(); - $app = new \OCA\Dav\AppInfo\Application(); - /** @var CardDavBackend */ - $backend = $app->getContainer()->query('CardDavBackend'); +\OC::$server->registerService('CardDAVSyncService', function() use ($app) { - return new SyncService($backend); + return $app->getSyncService(); }); $cm = \OC::$server->getContactsManager(); -$cm->register(function() use ($cm) { +$cm->register(function() use ($cm, $app) { $userId = \OC::$server->getUserSession()->getUser()->getUID(); - $app = new \OCA\Dav\AppInfo\Application(); $app->setupContactsProvider($cm, $userId); }); diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index 71236a3325e..3fce53b48bb 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -20,7 +20,10 @@ */ namespace OCA\Dav\AppInfo; +use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\CardDAV\ContactsManager; +use OCA\DAV\CardDAV\SyncService; +use OCA\DAV\HookManager; use \OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; use OCP\Contacts\IManager; @@ -43,6 +46,22 @@ class Application extends App { ); }); + $container->registerService('HookManager', function($c) { + /** @var IAppContainer $c */ + return new HookManager( + $c->getServer()->getUserManager(), + $c->query('SyncService') + ); + }); + + $container->registerService('SyncService', function($c) { + /** @var IAppContainer $c */ + return new SyncService( + $c->query('CardDavBackend'), + $c->getServer()->getUserManager() + ); + }); + $container->registerService('CardDavBackend', function($c) { /** @var IAppContainer $c */ $db = $c->getServer()->getDatabaseConnection(); @@ -65,4 +84,14 @@ class Application extends App { $cm->setupContactsProvider($contactsManager, $userID); } + public function registerHooks() { + /** @var HookManager $hm */ + $hm = $this->getContainer()->query('HookManager'); + $hm->setup(); + } + + public function getSyncService() { + return $this->getContainer()->query('SyncService'); + } + } diff --git a/apps/dav/command/syncsystemaddressbook.php b/apps/dav/command/syncsystemaddressbook.php index 338529c1952..c7401107480 100644 --- a/apps/dav/command/syncsystemaddressbook.php +++ b/apps/dav/command/syncsystemaddressbook.php @@ -22,6 +22,7 @@ namespace OCA\DAV\Command; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\CardDAV\Converter; +use OCA\DAV\CardDAV\SyncService; use OCA\DAV\Connector\Sabre\Principal; use OCP\IConfig; use OCP\IDBConnection; @@ -39,28 +40,16 @@ use Symfony\Component\Console\Output\OutputInterface; class SyncSystemAddressBook extends Command { - /** @var IUserManager */ - protected $userManager; - - /** @var \OCP\IDBConnection */ - protected $dbConnection; - - /** @var IConfig */ - protected $config; - - /** @var CardDavBackend */ - private $backend; + /** @var SyncService */ + private $syncService; /** * @param IUserManager $userManager - * @param IDBConnection $dbConnection - * @param IConfig $config + * @param SyncService $syncService */ - function __construct(IUserManager $userManager, IDBConnection $dbConnection, IConfig $config) { + function __construct(SyncService $syncService) { parent::__construct(); - $this->userManager = $userManager; - $this->dbConnection = $dbConnection; - $this->config = $config; + $this->syncService = $syncService; } protected function configure() { @@ -74,63 +63,15 @@ class SyncSystemAddressBook extends Command { * @param OutputInterface $output */ protected function execute(InputInterface $input, OutputInterface $output) { - $principalBackend = new Principal( - $this->userManager - ); - - $this->backend = new CardDavBackend($this->dbConnection, $principalBackend); - - // ensure system addressbook exists - $systemAddressBook = $this->ensureSystemAddressBookExists(); - $converter = new Converter(); $output->writeln('Syncing users ...'); $progress = new ProgressBar($output); $progress->start(); - $this->userManager->callForAllUsers(function($user) use ($systemAddressBook, $converter, $progress) { - /** @var IUser $user */ - $name = $user->getBackendClassName(); - $userId = $user->getUID(); - - $cardId = "$name:$userId.vcf"; - $card = $this->backend->getCard($systemAddressBook['id'], $cardId); - if ($card === false) { - $vCard = $converter->createCardFromUser($user); - $this->backend->createCard($systemAddressBook['id'], $cardId, $vCard->serialize()); - } else { - $vCard = Reader::read($card['carddata']); - if ($converter->updateCard($vCard, $user)) { - $this->backend->updateCard($systemAddressBook['id'], $cardId, $vCard->serialize()); - } - } + $this->syncService->syncInstance(function() use ($progress) { $progress->advance(); }); - // remove no longer existing - $allCards = $this->backend->getCards($systemAddressBook['id']); - foreach($allCards as $card) { - $vCard = Reader::read($card['carddata']); - $uid = $vCard->UID->getValue(); - // load backend and see if user exists - if (!$this->userManager->userExists($uid)) { - $this->backend->deleteCard($systemAddressBook['id'], $card['uri']); - } - } - $progress->finish(); $output->writeln(''); } - - protected function ensureSystemAddressBookExists() { - $book = $this->backend->getAddressBooksByUri('system'); - if (!is_null($book)) { - return $book; - } - $systemPrincipal = "principals/system/system"; - $this->backend->createAddressBook($systemPrincipal, 'system', [ - '{' . Plugin::NS_CARDDAV . '}addressbook-description' => 'System addressbook which holds all users of this instance' - ]); - - return $this->backend->getAddressBooksByUri('system'); - } } diff --git a/apps/dav/lib/carddav/syncservice.php b/apps/dav/lib/carddav/syncservice.php index 30dc78c4877..97a46d62501 100644 --- a/apps/dav/lib/carddav/syncservice.php +++ b/apps/dav/lib/carddav/syncservice.php @@ -21,18 +21,27 @@ namespace OCA\DAV\CardDAV; +use OCP\IUser; +use OCP\IUserManager; use Sabre\DAV\Client; use Sabre\DAV\Xml\Response\MultiStatus; use Sabre\DAV\Xml\Service; -use Sabre\HTTP\ClientException; +use Sabre\VObject\Reader; class SyncService { /** @var CardDavBackend */ private $backend; - public function __construct(CardDavBackend $backend) { + /** @var IUserManager */ + private $userManager; + + /** @var array */ + private $localSystemAddressBook; + + public function __construct(CardDavBackend $backend, IUserManager $userManager) { $this->backend = $backend; + $this->userManager = $userManager; } /** @@ -80,7 +89,7 @@ class SyncService { * @return array|null * @throws \Sabre\DAV\Exception\BadRequest */ - protected function ensureSystemAddressBookExists($principal, $id, $properties) { + public function ensureSystemAddressBookExists($principal, $id, $properties) { $book = $this->backend->getAddressBooksByUri($id); if (!is_null($book)) { return $book; @@ -180,5 +189,75 @@ class SyncService { return ['response' => $result, 'token' => $multiStatus->getSyncToken()]; } + /** + * @param IUser $user + */ + public function updateUser($user) { + $systemAddressBook = $this->getLocalSystemAddressBook(); + $addressBookId = $systemAddressBook['id']; + $converter = new Converter(); + $name = $user->getBackendClassName(); + $userId = $user->getUID(); + + $cardId = "$name:$userId.vcf"; + $card = $this->backend->getCard($addressBookId, $cardId); + if ($card === false) { + $vCard = $converter->createCardFromUser($user); + $this->backend->createCard($addressBookId, $cardId, $vCard->serialize()); + } else { + $vCard = Reader::read($card['carddata']); + if ($converter->updateCard($vCard, $user)) { + $this->backend->updateCard($addressBookId, $cardId, $vCard->serialize()); + } + } + } + + /** + * @param IUser|string $userOrCardId + */ + public function deleteUser($userOrCardId) { + $systemAddressBook = $this->getLocalSystemAddressBook(); + if ($userOrCardId instanceof IUser){ + $name = $userOrCardId->getBackendClassName(); + $userId = $userOrCardId->getUID(); + + $userOrCardId = "$name:$userId.vcf"; + } + $this->backend->deleteCard($systemAddressBook['id'], $userOrCardId); + } + + /** + * @return array|null + */ + public function getLocalSystemAddressBook() { + if (is_null($this->localSystemAddressBook)) { + $systemPrincipal = "principals/system/system"; + $this->localSystemAddressBook = $this->ensureSystemAddressBookExists($systemPrincipal, 'system', [ + '{' . Plugin::NS_CARDDAV . '}addressbook-description' => 'System addressbook which holds all users of this instance' + ]); + } + + return $this->localSystemAddressBook; + } + + public function syncInstance(\Closure $progressCallback) { + $systemAddressBook = $this->getLocalSystemAddressBook(); + $this->userManager->callForAllUsers(function($user) use ($systemAddressBook, $progressCallback) { + $this->updateUser($user); + $progressCallback(); + }); + + // remove no longer existing + $allCards = $this->backend->getCards($systemAddressBook['id']); + foreach($allCards as $card) { + $vCard = Reader::read($card['carddata']); + $uid = $vCard->UID->getValue(); + // load backend and see if user exists + if (!$this->userManager->userExists($uid)) { + $this->deleteUser($card['uri']); + } + } + } + } diff --git a/apps/dav/lib/hookmanager.php b/apps/dav/lib/hookmanager.php new file mode 100644 index 00000000000..7902bf31459 --- /dev/null +++ b/apps/dav/lib/hookmanager.php @@ -0,0 +1,74 @@ +<?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/> + * + */ +namespace OCA\DAV; + +use OCA\DAV\CardDAV\SyncService; +use OCP\IUser; +use OCP\IUserManager; +use OCP\Util; + +class HookManager { + + /** @var IUserManager */ + private $userManager; + + /** @var SyncService */ + private $syncService; + + /** @var IUser[] */ + private $usersToDelete; + + public function __construct(IUserManager $userManager, SyncService $syncService) { + $this->userManager = $userManager; + $this->syncService = $syncService; + } + + public function setup() { + Util::connectHook('OC_User', + 'post_createUser', + $this, + 'postCreateUser'); + Util::connectHook('OC_User', + 'pre_deleteUser', + $this, + 'preDeleteUser'); + Util::connectHook('OC_User', + 'post_deleteUser', + $this, + 'postDeleteUser'); + } + + public function postCreateUser($params) { + $user = $this->userManager->get($params['uid']); + $this->syncService->updateUser($user); + } + + public function preDeleteUser($params) { + $this->usersToDelete[$params['uid']] = $this->userManager->get($params['uid']); + } + public function postDeleteUser($params) { + $uid = $params['uid']; + if (isset($this->usersToDelete[$uid])){ + $this->syncService->deleteUser($this->usersToDelete[$uid]); + } + } + +} diff --git a/apps/dav/tests/unit/carddav/syncservicetest.php b/apps/dav/tests/unit/carddav/syncservicetest.php index a6a773babc2..338ac2bbe1b 100644 --- a/apps/dav/tests/unit/carddav/syncservicetest.php +++ b/apps/dav/tests/unit/carddav/syncservicetest.php @@ -77,8 +77,9 @@ class SyncServiceTest extends TestCase { * @return SyncService|\PHPUnit_Framework_MockObject_MockObject */ private function getSyncServiceMock($backend, $response) { + $userManager = $this->getMockBuilder('OCP\IUserManager')->disableOriginalConstructor()->getMock(); /** @var SyncService | \PHPUnit_Framework_MockObject_MockObject $ss */ - $ss = $this->getMock('OCA\DAV\CardDAV\SyncService', ['ensureSystemAddressBookExists', 'requestSyncReport', 'download'], [$backend]); + $ss = $this->getMock('OCA\DAV\CardDAV\SyncService', ['ensureSystemAddressBookExists', 'requestSyncReport', 'download'], [$backend, $userManager]); $ss->method('requestSyncReport')->withAnyParameters()->willReturn(['response' => $response, 'token' => 'sync-token-1']); $ss->method('ensureSystemAddressBookExists')->willReturn(['id' => 1]); $ss->method('download')->willReturn([ |