From c91192fb7324c246d3af95ae83ad9ac1ae0a8ec1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Thomas=20M=C3=BCller?= Date: Tue, 24 Nov 2015 23:53:27 +0100 Subject: [PATCH] Adding system addressbook for users of this instance - a occ command is supplied for synchronizing --- apps/dav/appinfo/register_command.php | 3 + apps/dav/command/syncsystemaddressbook.php | 112 +++++++++++++++++++++ apps/dav/lib/carddav/addressbook.php | 26 +++++ apps/dav/lib/carddav/carddavbackend.php | 4 +- apps/dav/lib/carddav/useraddressbooks.php | 26 +++++ apps/dav/lib/connector/sabre/principal.php | 12 +++ 6 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 apps/dav/command/syncsystemaddressbook.php diff --git a/apps/dav/appinfo/register_command.php b/apps/dav/appinfo/register_command.php index 1f0df054110..af41036cddc 100644 --- a/apps/dav/appinfo/register_command.php +++ b/apps/dav/appinfo/register_command.php @@ -2,7 +2,9 @@ use OCA\DAV\Command\CreateAddressBook; use OCA\DAV\Command\CreateCalendar; +use OCA\DAV\Command\SyncSystemAddressBook; +$config = \OC::$server->getConfig(); $dbConnection = \OC::$server->getDatabaseConnection(); $userManager = OC::$server->getUserManager(); $config = \OC::$server->getConfig(); @@ -10,3 +12,4 @@ $config = \OC::$server->getConfig(); /** @var Symfony\Component\Console\Application $application */ $application->add(new CreateAddressBook($userManager, $dbConnection, $config)); $application->add(new CreateCalendar($userManager, $dbConnection)); +$application->add(new SyncSystemAddressBook($userManager, $dbConnection, $config)); diff --git a/apps/dav/command/syncsystemaddressbook.php b/apps/dav/command/syncsystemaddressbook.php new file mode 100644 index 00000000000..01f4d08940b --- /dev/null +++ b/apps/dav/command/syncsystemaddressbook.php @@ -0,0 +1,112 @@ +userManager = $userManager; + $this->dbConnection = $dbConnection; + $this->config = $config; + } + + protected function configure() { + $this + ->setName('dav:sync-system-addressbook') + ->setDescription('Synchronizes users to the system addressbook'); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $principalBackend = new Principal( + $this->config, + $this->userManager + ); + + $this->backend = new CardDavBackend($this->dbConnection, $principalBackend); + + // ensure system addressbook exists + $systemAddressBook = $this->ensureSystemAddressBookExists(); + + $output->writeln('Syncing users ...'); + $progress = new ProgressBar($output); + $progress->start(); + $page = 0; + foreach( $this->userManager->getBackends() as $backend) { + $users = $backend->getUsers('', 50, $page++); + foreach($users as $user) { + $user = $this->userManager->get($user); + $name = $user->getBackendClassName(); + $userId = $user->getUID(); + $displayName = $user->getDisplayName(); + $cardId = "$name:$userId.vcf"; + $card = $this->backend->getCard($systemAddressBook['id'], $cardId); + if ($card === false) { + $vCard = new VCard(); + $vCard->add(new Text($vCard, 'UID', $user->getUID())); + $vCard->add(new Text($vCard, 'FN', $displayName)); +// $vCard->add(new Text($vCard, 'EMAIL', $user->getEMailAddress())); + //$vCard->add(new Binary($vCard, 'PHOTO', $user->getAvatar())); + $vCard->validate(); + $this->backend->createCard($systemAddressBook['id'], $cardId, $vCard->serialize()); + } else { + $updated = false; + $vCard = Reader::read($card['carddata']); + if($vCard->FN !== $user->getDisplayName()) { + $vCard->FN = new Text($vCard, 'FN', $displayName); + $updated = true; + } + if ($updated) { + $this->backend->updateCard($systemAddressBook['id'], $cardId, $vCard->serialize()); + } + } + $progress->advance(); + } + } + $progress->finish(); + } + + protected function ensureSystemAddressBookExists() { + $book = $this->backend->getAddressBooksByUri('system'); + if (!is_null($book)) { + return $book; + } + $systemPrincipal = "principals/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/addressbook.php b/apps/dav/lib/carddav/addressbook.php index eff1ad321e5..41227088ece 100644 --- a/apps/dav/lib/carddav/addressbook.php +++ b/apps/dav/lib/carddav/addressbook.php @@ -51,4 +51,30 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddres $carddavBackend = $this->carddavBackend; $carddavBackend->getShares($this->getName()); } + + function getACL() { + $acl = parent::getACL(); + if ($this->getOwner() === 'principals/system') { + $acl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => '{DAV:}authenticated', + 'protected' => true, + ]; + } + + return $acl; + } + + function getChildACL() { + $acl = parent::getChildACL(); + if ($this->getOwner() === 'principals/system') { + $acl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => '{DAV:}authenticated', + 'protected' => true, + ]; + } + + return $acl; + } } diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php index daa31725fa1..752669aae2a 100644 --- a/apps/dav/lib/carddav/carddavbackend.php +++ b/apps/dav/lib/carddav/carddavbackend.php @@ -108,7 +108,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { return $addressBooks; } - private function getAddressBooksByUri($addressBookUri) { + public function getAddressBooksByUri($addressBookUri) { $query = $this->db->getQueryBuilder(); $result = $query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken']) ->from('addressbooks') @@ -117,7 +117,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { ->execute(); $row = $result->fetch(); - if (is_null($row)) { + if ($row === false) { return null; } $result->closeCursor(); diff --git a/apps/dav/lib/carddav/useraddressbooks.php b/apps/dav/lib/carddav/useraddressbooks.php index 5f618a0ece3..2e630942e74 100644 --- a/apps/dav/lib/carddav/useraddressbooks.php +++ b/apps/dav/lib/carddav/useraddressbooks.php @@ -20,4 +20,30 @@ class UserAddressBooks extends \Sabre\CardDAV\AddressBookHome { } + /** + * Returns a list of ACE's for this node. + * + * Each ACE has the following properties: + * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are + * currently the only supported privileges + * * 'principal', a url to the principal who owns the node + * * 'protected' (optional), indicating that this ACE is not allowed to + * be updated. + * + * @return array + */ + function getACL() { + + $acl = parent::getACL(); + if ($this->principalUri === 'principals/system') { + $acl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => '{DAV:}authenticated', + 'protected' => true, + ]; + } + + return $acl; + } + } diff --git a/apps/dav/lib/connector/sabre/principal.php b/apps/dav/lib/connector/sabre/principal.php index cc9c1c40d59..7852eca61ab 100644 --- a/apps/dav/lib/connector/sabre/principal.php +++ b/apps/dav/lib/connector/sabre/principal.php @@ -74,6 +74,11 @@ class Principal implements \Sabre\DAVACL\PrincipalBackend\BackendInterface { } } + $principals[] = [ + 'uri' => 'principals/system', + '{DAV:}displayname' => 'system', + ]; + return $principals; } @@ -90,6 +95,13 @@ class Principal implements \Sabre\DAVACL\PrincipalBackend\BackendInterface { if ($elements[0] !== 'principals') { return null; } + if ($elements[1] === 'system') { + $principal = [ + 'uri' => 'principals/system', + '{DAV:}displayname' => 'system', + ]; + return $principal; + } if ($elements[1] !== 'users') { return null; } -- 2.39.5