From 906777dc9c8e0d9075e6a8d8c7f6eeb7c07e5256 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Thomas=20M=C3=BCller?= Date: Mon, 30 Nov 2015 16:59:41 +0100 Subject: [PATCH] Add converter to generate/update a vcard from a given user --- apps/dav/command/syncsystemaddressbook.php | 27 +--- apps/dav/lib/carddav/converter.php | 98 +++++++++++++++ apps/dav/tests/unit/carddav/convertertest.php | 116 ++++++++++++++++++ 3 files changed, 218 insertions(+), 23 deletions(-) create mode 100644 apps/dav/lib/carddav/converter.php create mode 100644 apps/dav/tests/unit/carddav/convertertest.php diff --git a/apps/dav/command/syncsystemaddressbook.php b/apps/dav/command/syncsystemaddressbook.php index 74d8295e77b..288616d065b 100644 --- a/apps/dav/command/syncsystemaddressbook.php +++ b/apps/dav/command/syncsystemaddressbook.php @@ -3,6 +3,7 @@ namespace OCA\DAV\Command; use OCA\DAV\CardDAV\CardDavBackend; +use OCA\DAV\CardDAV\Converter; use OCA\DAV\Connector\Sabre\Principal; use OCP\IConfig; use OCP\IDBConnection; @@ -63,6 +64,7 @@ class SyncSystemAddressBook extends Command { // ensure system addressbook exists $systemAddressBook = $this->ensureSystemAddressBookExists(); + $converter = new Converter(); $output->writeln('Syncing users ...'); $progress = new ProgressBar($output); @@ -74,36 +76,15 @@ class SyncSystemAddressBook extends Command { $user = $this->userManager->get($user); $name = $user->getBackendClassName(); $userId = $user->getUID(); - $displayName = $user->getDisplayName(); - $emailAddress = $user->getEMailAddress(); - $cloudId = $user->getCloudId(); - $image = $user->getAvatarImage(-1); $cardId = "$name:$userId.vcf"; $card = $this->backend->getCard($systemAddressBook['id'], $cardId); if ($card === false) { - $vCard = new VCard(); - $vCard->add(new Text($vCard, 'UID', $userId)); - $vCard->add(new Text($vCard, 'FN', $displayName)); - $vCard->add(new Text($vCard, 'EMAIL', $emailAddress)); - $vCard->add(new Text($vCard, 'CLOUD', $cloudId)); - if ($image) { - $vCard->add('PHOTO', $image->data(), ['ENCODING' => 'b', 'TYPE' => $image->mimeType()]); - } - $vCard->validate(); + $vCard = $converter->createCardFromUser($user); $this->backend->createCard($systemAddressBook['id'], $cardId, $vCard->serialize()); } else { - $updated = false; $vCard = Reader::read($card['carddata']); - if($vCard->FN !== $displayName) { - $vCard->FN = new Text($vCard, 'FN', $displayName); - $updated = true; - } - if($vCard->EMail !== $emailAddress) { - $vCard->FN = new Text($vCard, 'EMAIL', $emailAddress); - $updated = true; - } - if ($updated) { + if ($converter->updateCard($vCard, $user)) { $this->backend->updateCard($systemAddressBook['id'], $cardId, $vCard->serialize()); } } diff --git a/apps/dav/lib/carddav/converter.php b/apps/dav/lib/carddav/converter.php new file mode 100644 index 00000000000..3aa3639ffa3 --- /dev/null +++ b/apps/dav/lib/carddav/converter.php @@ -0,0 +1,98 @@ + + * + * @copyright Copyright (c) 2015, 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 + * + */ + +namespace OCA\DAV\CardDAV; + +use OCP\IUser; +use Sabre\VObject\Component\VCard; +use Sabre\VObject\Property\Text; + +class Converter { + + public function __construct() { + } + + public function createCardFromUser(IUser $user) { + + $uid = $user->getUID(); + $displayName = $user->getDisplayName(); + $displayName = empty($displayName ) ? $uid : $displayName; + $emailAddress = $user->getEMailAddress(); + $cloudId = $user->getCloudId(); + $image = $user->getAvatarImage(-1); + + $vCard = new VCard(); + $vCard->add(new Text($vCard, 'UID', $uid)); + if (!empty($displayName)) { + $vCard->add(new Text($vCard, 'FN', $displayName)); + } + if (!empty($emailAddress)) { + $vCard->add(new Text($vCard, 'EMAIL', $emailAddress)); + } + if (!empty($cloudId)) { + $vCard->add(new Text($vCard, 'CLOUD', $cloudId)); + } + if ($image) { + $vCard->add('PHOTO', $image->data(), ['ENCODING' => 'b', 'TYPE' => $image->mimeType()]); + } + $vCard->validate(); + + return $vCard; + } + + public function updateCard(VCard $vCard, IUser $user) { + $uid = $user->getUID(); + $displayName = $user->getDisplayName(); + $displayName = empty($displayName ) ? $uid : $displayName; + $emailAddress = $user->getEMailAddress(); + $cloudId = $user->getCloudId(); + $image = $user->getAvatarImage(-1); + + $updated = false; + if(!is_null($vCard->FN) && $vCard->FN->getValue() !== $displayName) { + $vCard->FN = new Text($vCard, 'FN', $displayName); + $updated = true; + } + if(!is_null($vCard->EMail) && $vCard->EMail->getValue() !== $emailAddress) { + $vCard->EMAIL = new Text($vCard, 'EMAIL', $emailAddress); + $updated = true; + } + if(!is_null($vCard->CLOUD) && $vCard->CLOUD->getValue() !== $cloudId) { + $vCard->CLOUD = new Text($vCard, 'CLOUD', $cloudId); + $updated = true; + } + + if (empty($emailAddress) && !is_null($vCard->EMAIL)) { + unset($vCard->EMAIL); + $updated = true; + } + if (empty($cloudId) && !is_null($vCard->CLOUD)) { + unset($vCard->CLOUD); + $updated = true; + } + if (empty($image) && !is_null($vCard->PHOTO)) { + unset($vCard->PHOTO); + $updated = true; + } + + return $updated; + } +} diff --git a/apps/dav/tests/unit/carddav/convertertest.php b/apps/dav/tests/unit/carddav/convertertest.php new file mode 100644 index 00000000000..cb68326a7bc --- /dev/null +++ b/apps/dav/tests/unit/carddav/convertertest.php @@ -0,0 +1,116 @@ + + * + * @copyright Copyright (c) 2015, 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 + * + */ + +namespace OCA\DAV\Tests\Unit; + +use OCA\DAV\CardDAV\Converter; +use Test\TestCase; + +class ConverterTests extends TestCase { + + /** + * @dataProvider providesNewUsers + */ + public function testCreation($expectedVCard, $displayName = null, $eMailAddress = null, $cloudId = null) { + $user = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock(); + $user->method('getUID')->willReturn('12345'); + $user->method('getDisplayName')->willReturn($displayName); + $user->method('getEMailAddress')->willReturn($eMailAddress); + $user->method('getCloudId')->willReturn($cloudId); + + $converter = new Converter(); + $vCard = $converter->createCardFromUser($user); + $cardData = $vCard->serialize(); + + $this->assertEquals($expectedVCard, $cardData); + } + + public function providesNewUsers() { + return [ + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:12345\r\nEND:VCARD\r\n"], + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:Dr. Foo Bar\r\nEND:VCARD\r\n", "Dr. Foo Bar"], + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:Dr. Foo Bar\r\nCLOUD:foo@bar.net\r\nEND:VCARD\r\n", "Dr. Foo Bar", null, "foo@bar.net"], + ]; + } + + /** + * @dataProvider providesUsersForUpdate + */ + public function testUpdateOfUnchangedUser($expectedVCard, $displayName = null, $eMailAddress = null, $cloudId = null) { + $user = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock(); + $user->method('getUID')->willReturn('12345'); + $user->method('getDisplayName')->willReturn($displayName); + $user->method('getEMailAddress')->willReturn($eMailAddress); + $user->method('getCloudId')->willReturn($cloudId); + + $converter = new Converter(); + $vCard = $converter->createCardFromUser($user); + $updated = $converter->updateCard($vCard, $user); + $this->assertFalse($updated); + $cardData = $vCard->serialize(); + + $this->assertEquals($expectedVCard, $cardData); + } + + public function providesUsersForUpdate() { + return [ + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:12345\r\nEND:VCARD\r\n"], + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:Dr. Foo Bar\r\nEND:VCARD\r\n", "Dr. Foo Bar"], + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:Dr. Foo Bar\r\nEMAIL:foo@bar.net\r\nEND:VCARD\r\n", "Dr. Foo Bar", "foo@bar.net"], + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:Dr. Foo Bar\r\nCLOUD:foo@bar.net\r\nEND:VCARD\r\n", "Dr. Foo Bar", null, "foo@bar.net"], + ]; + } + + /** + * @dataProvider providesUsersForUpdateOfRemovedElement + */ + public function testUpdateOfRemovedElement($expectedVCard, $displayName = null, $eMailAddress = null, $cloudId = null) { + $user = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock(); + $user->method('getUID')->willReturn('12345'); + $user->method('getDisplayName')->willReturn($displayName); + $user->method('getEMailAddress')->willReturn($eMailAddress); + $user->method('getCloudId')->willReturn($cloudId); + + $converter = new Converter(); + $vCard = $converter->createCardFromUser($user); + + $user1 = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock(); + $user1->method('getUID')->willReturn('12345'); + $user1->method('getDisplayName')->willReturn(null); + $user1->method('getEMailAddress')->willReturn(null); + $user1->method('getCloudId')->willReturn(null); + + $updated = $converter->updateCard($vCard, $user1); + $this->assertTrue($updated); + $cardData = $vCard->serialize(); + + $this->assertEquals($expectedVCard, $cardData); + } + + public function providesUsersForUpdateOfRemovedElement() { + return [ + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:12345\r\nEND:VCARD\r\n", "Dr. Foo Bar"], + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:12345\r\nEND:VCARD\r\n", "Dr. Foo Bar", "foo@bar.net"], + ["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:12345\r\nEND:VCARD\r\n", "Dr. Foo Bar", null, "foo@bar.net"], + ]; + } + +} -- 2.39.5