From 919701ce240e2ad1f0d03a671006641f4dfc6b49 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Fri, 26 Sep 2025 11:30:23 +0200 Subject: [PATCH] fix(Collaboration\UserPlugin): ensure full match is included in results When searching we need to: 1. check if sharing is limited to groups - if yes only include those - otherwise continue 2. check if there are restrictions to groups or phonebook 3. check if full match is included Signed-off-by: Ferdinand Thiessen --- .../Collaborators/UserPlugin.php | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/lib/private/Collaboration/Collaborators/UserPlugin.php b/lib/private/Collaboration/Collaborators/UserPlugin.php index 671181aea35..ffad426e15d 100644 --- a/lib/private/Collaboration/Collaborators/UserPlugin.php +++ b/lib/private/Collaboration/Collaborators/UserPlugin.php @@ -63,8 +63,10 @@ class UserPlugin implements ISearchPlugin { $users = []; $hasMoreResults = false; - $currentUserId = $this->userSession->getUser()->getUID(); - $currentUserGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser()); + /** @var IUser */ + $currentUser = $this->userSession->getUser(); + $currentUserId = $currentUser->getUID(); + $currentUserGroups = $this->groupManager->getUserGroupIds($currentUser); // ShareWithGroupOnly filtering $currentUserGroups = array_diff($currentUserGroups, $this->shareWithGroupOnlyExcludeGroupsList); @@ -76,7 +78,7 @@ class UserPlugin implements ISearchPlugin { foreach ($usersInGroup as $userId => $displayName) { $userId = (string)$userId; $user = $this->userManager->get($userId); - if (!$user->isEnabled()) { + if (!$user?->isEnabled()) { // Ignore disabled users continue; } @@ -86,37 +88,43 @@ class UserPlugin implements ISearchPlugin { $hasMoreResults = true; } } + } - if (!$this->shareWithGroupOnly && $this->shareeEnumerationPhone) { - $usersTmp = $this->userManager->searchKnownUsersByDisplayName($currentUserId, $search, $limit, $offset); - if (!empty($usersTmp)) { + // not limited to group only sharing + if (!$this->shareWithGroupOnly) { + if (!$this->shareeEnumerationPhone && !$this->shareeEnumerationInGroupOnly) { + // no restrictions, add everything + $usersTmp = $this->userManager->searchDisplayName($search, $limit, $offset); + foreach ($usersTmp as $user) { + if ($user->isEnabled()) { // Don't keep deactivated users + $users[$user->getUID()] = $user; + } + } + } else { + // make sure to add phonebook matches if configured + if ($this->shareeEnumerationPhone) { + $usersTmp = $this->userManager->searchKnownUsersByDisplayName($currentUserId, $search, $limit, $offset); foreach ($usersTmp as $user) { if ($user->isEnabled()) { // Don't keep deactivated users $users[$user->getUID()] = $user; } } - - uasort($users, function ($a, $b) { - /** - * @var \OC\User\User $a - * @var \OC\User\User $b - */ - return strcasecmp($a->getDisplayName(), $b->getDisplayName()); - }); } - } - } else { - // Search in all users - if ($this->shareeEnumerationPhone) { - $usersTmp = $this->userManager->searchKnownUsersByDisplayName($currentUserId, $search, $limit, $offset); - } else { - $usersTmp = $this->userManager->searchDisplayName($search, $limit, $offset); - } - foreach ($usersTmp as $user) { - if ($user->isEnabled()) { // Don't keep deactivated users - $users[$user->getUID()] = $user; + + // additionally we need to add full matches + if ($this->shareeEnumerationFullMatch) { + $usersTmp = $this->userManager->searchDisplayName($search, $limit, $offset); + foreach ($usersTmp as $user) { + if ($user->isEnabled() && mb_strtolower($user->getDisplayName()) === mb_strtolower($search)) { + $users[$user->getUID()] = $user; + } + } } } + + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($a->getDisplayName(), $b->getDisplayName()); + }); } $this->takeOutCurrentUser($users); @@ -149,10 +157,13 @@ class UserPlugin implements ISearchPlugin { if ( $this->shareeEnumerationFullMatch - && $lowerSearch !== '' && (strtolower($uid) === $lowerSearch - || strtolower($userDisplayName) === $lowerSearch - || ($this->shareeEnumerationFullMatchIgnoreSecondDisplayName && trim(strtolower(preg_replace('/ \(.*\)$/', '', $userDisplayName))) === $lowerSearch) - || ($this->shareeEnumerationFullMatchEmail && strtolower($userEmail ?? '') === $lowerSearch)) + && $lowerSearch !== '' + && ( + strtolower($uid) === $lowerSearch + || strtolower($userDisplayName) === $lowerSearch + || ($this->shareeEnumerationFullMatchIgnoreSecondDisplayName && trim(strtolower(preg_replace('/ \(.*\)$/', '', $userDisplayName))) === $lowerSearch) + || ($this->shareeEnumerationFullMatchEmail && strtolower($userEmail ?? '') === $lowerSearch) + ) ) { if (strtolower($uid) === $lowerSearch) { $foundUserById = true;