From cdd4a75c17db0420779b8f429208f052c39bb76a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 13 Jun 2017 18:07:47 +0200 Subject: [PATCH] Backport of #5384 to stable12 Allow to find local users by their email address Signed-off-by: Joas Schilling Make sure to only add system users once Signed-off-by: Joas Schilling Add unit test Signed-off-by: Joas Schilling --- .../lib/Controller/ShareesAPIController.php | 64 +++++++++++++++++-- .../Controller/ShareesAPIControllerTest.php | 15 +++++ 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index 7d345efb3e..57d51ebac6 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -593,24 +593,52 @@ class ShareesAPIController extends OCSController { * @return array */ protected function getEmail($search) { - $result = ['results' => [], 'exact' => []]; + $result = ['results' => [], 'exact' => [], 'exactIdMatch' => false]; // Search in contacts //@todo Pagination missing $addressBookContacts = $this->contactsManager->search($search, ['EMAIL', 'FN']); - $result['exactIdMatch'] = false; + $lowerSearch = strtolower($search); foreach ($addressBookContacts as $contact) { - if (isset($contact['isLocalSystemBook'])) { - continue; - } if (isset($contact['EMAIL'])) { $emailAddresses = $contact['EMAIL']; if (!is_array($emailAddresses)) { $emailAddresses = [$emailAddresses]; } foreach ($emailAddresses as $emailAddress) { - if (strtolower($contact['FN']) === strtolower($search) || strtolower($emailAddress) === strtolower($search)) { - if (strtolower($emailAddress) === strtolower($search)) { + $exactEmailMatch = strtolower($emailAddress) === $lowerSearch; + + if (isset($contact['isLocalSystemBook'])) { + if ($exactEmailMatch) { + $cloud = $this->cloudIdManager->resolveCloudId($contact['CLOUD'][0]); + if (!$this->hasUserInResult($cloud->getUser())) { + $this->result['exact']['users'][] = [ + 'label' => $contact['FN'] . " ($emailAddress)", + 'value' => [ + 'shareType' => Share::SHARE_TYPE_USER, + 'shareWith' => $cloud->getUser(), + ], + ]; + } + return ['results' => [], 'exact' => [], 'exactIdMatch' => true]; + } + if ($this->shareeEnumeration) { + $cloud = $this->cloudIdManager->resolveCloudId($contact['CLOUD'][0]); + if (!$this->hasUserInResult($cloud->getUser())) { + $this->result['users'][] = [ + 'label' => $contact['FN'] . " ($emailAddress)", + 'value' => [ + 'shareType' => Share::SHARE_TYPE_USER, + 'shareWith' => $cloud->getUser(), + ], + ]; + } + } + continue; + } + + if ($exactEmailMatch || strtolower($contact['FN']) === $lowerSearch) { + if ($exactEmailMatch) { $result['exactIdMatch'] = true; } $result['exact'][] = [ @@ -688,6 +716,28 @@ class ShareesAPIController extends OCSController { $this->result['lookup'] = $result; } + /** + * Check if a given user is already part of the result + * + * @param string $userId + * @return bool + */ + protected function hasUserInResult($userId) { + foreach ($this->result['exact']['users'] as $result) { + if ($result['value']['shareWith'] === $userId) { + return true; + } + } + + foreach ($this->result['users'] as $result) { + if ($result['value']['shareWith'] === $userId) { + return true; + } + } + + return false; + } + /** * Generates a bunch of pagination links for the current page * diff --git a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php index e3d869db3d..e027d0751c 100644 --- a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php @@ -1272,6 +1272,21 @@ class ShareesAPIControllerTest extends TestCase { ['results' => [], 'exact' => [], 'exactIdMatch' => false], true, ], + // Local user found by email + [ + 'test@example.com', + [ + [ + 'FN' => 'User', + 'EMAIL' => ['test@example.com'], + 'CLOUD' => ['test@localhost'], + 'isLocalSystemBook' => true, + ] + ], + false, + ['results' => [], 'exact' => [], 'exactIdMatch' => true], + false, + ] ]; }