mirror of
https://github.com/nextcloud/server.git
synced 2026-06-10 17:23:59 -04:00
Merge pull request #58603 from pymnh/feat/extend-group-search-to-teams
feat(UserPlugin): Include teams in group search
This commit is contained in:
commit
56eaf1dbcc
5 changed files with 54 additions and 13 deletions
|
|
@ -4,11 +4,11 @@
|
|||
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OC\Core\Controller;
|
||||
|
||||
use Exception;
|
||||
use OC\Contacts\ContactsMenu\Manager;
|
||||
use OC\Teams\TeamManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
|
|
@ -38,12 +38,10 @@ class ContactsMenuController extends Controller {
|
|||
public function index(?string $filter = null, ?string $teamId = null): array {
|
||||
$entries = $this->manager->getEntries($this->userSession->getUser(), $filter);
|
||||
if ($teamId !== null) {
|
||||
/** @var TeamManager */
|
||||
$teamManager = $this->teamManager;
|
||||
$memberIds = $teamManager->getMembersOfTeam($teamId, $this->userSession->getUser()->getUID());
|
||||
$memberIds = $this->teamManager->getMembersOfTeam($teamId, $this->userSession->getUser()->getUID());
|
||||
$entries['contacts'] = array_filter(
|
||||
$entries['contacts'],
|
||||
fn (IEntry $entry) => in_array($entry->getProperty('UID'), $memberIds, true)
|
||||
fn (IEntry $entry) => array_key_exists($entry->getProperty('UID'), $memberIds)
|
||||
);
|
||||
}
|
||||
return $entries;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ use OCP\IUser;
|
|||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Share\IShare;
|
||||
use OCP\Teams\ITeamManager;
|
||||
use OCP\UserStatus\IManager as IUserStatusManager;
|
||||
use OCP\UserStatus\IUserStatus;
|
||||
|
||||
|
|
@ -26,6 +27,7 @@ readonly class UserPlugin implements ISearchPlugin {
|
|||
private IAppConfig $appConfig,
|
||||
private IUserManager $userManager,
|
||||
private IGroupManager $groupManager,
|
||||
private ITeamManager $teamManager,
|
||||
private IUserSession $userSession,
|
||||
private IUserStatusManager $userStatusManager,
|
||||
private IDBConnection $connection,
|
||||
|
|
@ -41,6 +43,7 @@ readonly class UserPlugin implements ISearchPlugin {
|
|||
|
||||
/** @var array<string, array{0: 'wide'|'exact', 1: IUser}> $users */
|
||||
$users = [];
|
||||
$lowerSearch = mb_strtolower($search);
|
||||
|
||||
$shareeEnumeration = $this->appConfig->getValueString('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
|
||||
if ($shareeEnumeration) {
|
||||
|
|
@ -67,6 +70,23 @@ readonly class UserPlugin implements ISearchPlugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If teams are enabled, also search in them
|
||||
if ($this->teamManager->hasTeamSupport()) {
|
||||
$teams = $this->teamManager->getTeamsForUser($currentUser->getUID());
|
||||
foreach ($teams as $team) {
|
||||
$usersInTeam = $this->teamManager->getMembersOfTeam($team->getId(), $currentUser->getUID());
|
||||
foreach ($usersInTeam as $userId => $displayName) {
|
||||
if (!str_contains(mb_strtolower($userId), $lowerSearch) && !str_contains(mb_strtolower($displayName), $lowerSearch)) {
|
||||
continue;
|
||||
}
|
||||
$user = $this->userManager->get($userId);
|
||||
if ($user !== null && $user->isEnabled()) {
|
||||
$users[$userId] = ['wide', $user];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($shareeEnumerationRestrictToPhone) {
|
||||
|
|
@ -87,8 +107,6 @@ readonly class UserPlugin implements ISearchPlugin {
|
|||
$shareeEnumerationFullMatchEmail = $this->appConfig->getValueString('core', 'shareapi_restrict_user_enumeration_full_match_email', 'yes') === 'yes';
|
||||
$shareeEnumerationFullMatchIgnoreSecondDisplayName = $this->appConfig->getValueString('core', 'shareapi_restrict_user_enumeration_full_match_ignore_second_dn', 'no') === 'yes';
|
||||
|
||||
$lowerSearch = mb_strtolower($search);
|
||||
|
||||
// Re-use the results from earlier if possible
|
||||
$usersByDisplayName ??= $this->userManager->searchDisplayName($search, $limit, $offset);
|
||||
foreach ($usersByDisplayName as $user) {
|
||||
|
|
|
|||
|
|
@ -133,7 +133,9 @@ class TeamManager implements ITeamManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* Returns a mapping of user id to display name for all members of a given team.
|
||||
*
|
||||
* @return array<string, string> userId => displayName
|
||||
*/
|
||||
public function getMembersOfTeam(string $teamId, string $userId): array {
|
||||
$team = $this->getTeam($teamId, $userId);
|
||||
|
|
@ -141,7 +143,11 @@ class TeamManager implements ITeamManager {
|
|||
return [];
|
||||
}
|
||||
$members = $team->getInheritedMembers();
|
||||
return array_map(fn ($member) => $member->getUserId(), $members);
|
||||
$result = [];
|
||||
foreach ($members as $member) {
|
||||
$result[$member->getUserId()] = $member->getDisplayName();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -56,4 +56,23 @@ interface ITeamManager {
|
|||
* @since 33.0.0
|
||||
*/
|
||||
public function getTeamsForUser(string $userId): array;
|
||||
|
||||
/**
|
||||
* Returns a mapping of user ID to display name for all members of a given team.
|
||||
*
|
||||
* @param string $teamId ID of the team whose members are being queried
|
||||
* @param string $userId ID of the user from whose point of view the members are being queried
|
||||
*
|
||||
* @return array<string, string> userId => displayName
|
||||
* @since 34.0.0
|
||||
*/
|
||||
public function getMembersOfTeam(string $teamId, string $userId): array;
|
||||
|
||||
/**
|
||||
* Returns whether the Teams backend is available
|
||||
*
|
||||
* @return bool
|
||||
* @since 34.0.0
|
||||
*/
|
||||
public function hasTeamSupport(): bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,18 +9,18 @@ namespace Tests\Controller;
|
|||
|
||||
use OC\Contacts\ContactsMenu\Manager;
|
||||
use OC\Core\Controller\ContactsMenuController;
|
||||
use OC\Teams\TeamManager;
|
||||
use OCP\Contacts\ContactsMenu\IEntry;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Teams\ITeamManager;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Test\TestCase;
|
||||
|
||||
class ContactsMenuControllerTest extends TestCase {
|
||||
private IUserSession&MockObject $userSession;
|
||||
private Manager&MockObject $contactsManager;
|
||||
private TeamManager&MockObject $teamManager;
|
||||
private ITeamManager&MockObject $teamManager;
|
||||
|
||||
private ContactsMenuController $controller;
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ class ContactsMenuControllerTest extends TestCase {
|
|||
$request = $this->createMock(IRequest::class);
|
||||
$this->userSession = $this->createMock(IUserSession::class);
|
||||
$this->contactsManager = $this->createMock(Manager::class);
|
||||
$this->teamManager = $this->createMock(TeamManager::class);
|
||||
$this->teamManager = $this->createMock(ITeamManager::class);
|
||||
|
||||
$this->controller = new ContactsMenuController(
|
||||
$request,
|
||||
|
|
@ -86,7 +86,7 @@ class ContactsMenuControllerTest extends TestCase {
|
|||
$this->teamManager->expects($this->once())
|
||||
->method('getMembersOfTeam')
|
||||
->with('team-id', 'current-user')
|
||||
->willReturn(['member1', 'member3']);
|
||||
->willReturn(['member1' => 'Member 1', 'member3' => 'Member 3']);
|
||||
|
||||
$response = $this->controller->index(teamId: 'team-id');
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue