]> source.dussan.org Git - nextcloud-server.git/commitdiff
Start updating system addressbook
authorThomas Müller <thomas.mueller@tmit.eu>
Wed, 13 Jan 2016 19:56:25 +0000 (20:56 +0100)
committerThomas Müller <thomas.mueller@tmit.eu>
Thu, 14 Jan 2016 11:10:45 +0000 (12:10 +0100)
apps/dav/appinfo/app.php
apps/dav/appinfo/application.php
apps/dav/command/syncsystemaddressbook.php
apps/dav/lib/carddav/syncservice.php
apps/dav/lib/hookmanager.php [new file with mode: 0644]
apps/dav/tests/unit/carddav/syncservicetest.php

index 5ba7278e88eb52a34808ac56682d08b386502d9b..5cccab98f17f2cbc9fe367f425b7e0a65ea76424 100644 (file)
 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);
 });
index 71236a3325e3a86e9fe8023a8ab7ef37a00abb65..3fce53b48bb63bbd8c9c5a44aef3c747ef27228a 100644 (file)
  */
 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');
+       }
+
 }
index 338529c195264035fbaec9f109717e326ed179bb..c7401107480cfa9fc95966f5797d04c814f80051 100644 (file)
@@ -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');
-       }
 }
index 30dc78c48776da5444c0dc09f288402f3c44c019..97a46d62501c532c4fa941cf5d04afc34432c08c 100644 (file)
 
 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 (file)
index 0000000..7902bf3
--- /dev/null
@@ -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]);
+               }
+       }
+
+}
index a6a773babc2641f165b6b5203812f95fa4a8636f..338ac2bbe1ba0b674e8f05d47296564ee95d3e60 100644 (file)
@@ -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([