mirror of
https://github.com/nextcloud/server.git
synced 2026-06-12 10:10:49 -04:00
perf(MailPlugin): Optimize checking group memberships
Signed-off-by: provokateurin <kate@provokateurin.de>
This commit is contained in:
parent
1c7e381858
commit
5c21fb5062
4 changed files with 37 additions and 40 deletions
|
|
@ -14,6 +14,7 @@ use OCP\Contacts\IManager;
|
|||
use OCP\Federation\ICloudIdManager;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Mail\IEmailValidator;
|
||||
use OCP\Share\IShare;
|
||||
|
|
@ -31,6 +32,7 @@ class MailByMailPlugin extends MailPlugin {
|
|||
KnownUserService $knownUserService,
|
||||
IUserSession $userSession,
|
||||
IEmailValidator $emailValidator,
|
||||
IUserManager $userManager,
|
||||
mixed $shareWithGroupOnlyExcludeGroupsList = [],
|
||||
) {
|
||||
parent::__construct(
|
||||
|
|
@ -41,6 +43,7 @@ class MailByMailPlugin extends MailPlugin {
|
|||
$knownUserService,
|
||||
$userSession,
|
||||
$emailValidator,
|
||||
$userManager,
|
||||
$shareWithGroupOnlyExcludeGroupsList,
|
||||
IShare::TYPE_EMAIL,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use OCP\Federation\ICloudIdManager;
|
|||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Mail\IEmailValidator;
|
||||
use OCP\Share\IShare;
|
||||
|
|
@ -42,6 +43,7 @@ class MailPlugin implements ISearchPlugin {
|
|||
private KnownUserService $knownUserService,
|
||||
private IUserSession $userSession,
|
||||
private IEmailValidator $emailValidator,
|
||||
private IUserManager $userManager,
|
||||
private mixed $shareWithGroupOnlyExcludeGroupsList,
|
||||
private int $shareType,
|
||||
) {
|
||||
|
|
@ -72,6 +74,7 @@ class MailPlugin implements ISearchPlugin {
|
|||
}
|
||||
|
||||
$currentUserId = $this->userSession->getUser()->getUID();
|
||||
$userGroups = null;
|
||||
|
||||
$result = $userResults = ['wide' => [], 'exact' => []];
|
||||
$userType = new SearchResultType('users');
|
||||
|
|
@ -114,26 +117,19 @@ class MailPlugin implements ISearchPlugin {
|
|||
$exactEmailMatch = strtolower($emailAddress) === $lowerSearch;
|
||||
|
||||
if (isset($contact['isLocalSystemBook'])) {
|
||||
$contactUser = $this->userManager->get($contact['UID']);
|
||||
if ($contactUser === null) {
|
||||
continue;
|
||||
}
|
||||
$contactGroups = $this->groupManager->getUserGroupIds($contactUser);
|
||||
|
||||
if ($this->shareWithGroupOnly) {
|
||||
/*
|
||||
* Check if the user may share with the user associated with the e-mail of the just found contact
|
||||
*/
|
||||
$userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
|
||||
|
||||
// ShareWithGroupOnly filtering
|
||||
$userGroups = array_diff($userGroups, $this->shareWithGroupOnlyExcludeGroupsList);
|
||||
|
||||
$found = false;
|
||||
foreach ($userGroups as $userGroup) {
|
||||
if ($this->groupManager->isInGroup($contact['UID'], $userGroup)) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
$userGroups ??= $this->groupManager->getUserGroupIds($this->userSession->getUser());
|
||||
if (array_intersect($contactGroups, array_diff($userGroups, $this->shareWithGroupOnlyExcludeGroupsList)) === []) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($exactEmailMatch && $this->shareeEnumerationFullMatch) {
|
||||
try {
|
||||
$cloud = $this->cloudIdManager->resolveCloudId($contact['CLOUD'][0] ?? '');
|
||||
|
|
@ -174,14 +170,8 @@ class MailPlugin implements ISearchPlugin {
|
|||
}
|
||||
|
||||
if (!$addToWide && $this->shareeEnumerationInGroupOnly) {
|
||||
$addToWide = false;
|
||||
$userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
|
||||
foreach ($userGroups as $userGroup) {
|
||||
if ($this->groupManager->isInGroup($contact['UID'], $userGroup)) {
|
||||
$addToWide = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$userGroups ??= $this->groupManager->getUserGroupIds($this->userSession->getUser());
|
||||
$addToWide = array_intersect($contactGroups, $userGroups) !== [];
|
||||
}
|
||||
if ($addToWide && !$this->isCurrentUser($cloud) && !$searchResult->hasResult($userType, $cloud->getUser())) {
|
||||
if ($this->shareType === IShare::TYPE_USER) {
|
||||
|
|
@ -247,7 +237,7 @@ class MailPlugin implements ISearchPlugin {
|
|||
}
|
||||
|
||||
if ($this->shareType === IShare::TYPE_EMAIL
|
||||
&& !$searchResult->hasExactIdMatch($emailType) && $this->emailValidator->isValid($search)) {
|
||||
&& !$searchResult->hasExactIdMatch($emailType) && $this->emailValidator->isValid($search)) {
|
||||
$result['exact'][] = [
|
||||
'label' => $search,
|
||||
'uuid' => $search,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use OCP\Contacts\IManager;
|
|||
use OCP\Federation\ICloudIdManager;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Mail\IEmailValidator;
|
||||
use OCP\Share\IShare;
|
||||
|
|
@ -31,6 +32,7 @@ class UserByMailPlugin extends MailPlugin {
|
|||
KnownUserService $knownUserService,
|
||||
IUserSession $userSession,
|
||||
IEmailValidator $emailValidator,
|
||||
IUserManager $userManager,
|
||||
mixed $shareWithGroupOnlyExcludeGroupsList = [],
|
||||
) {
|
||||
parent::__construct(
|
||||
|
|
@ -41,6 +43,7 @@ class UserByMailPlugin extends MailPlugin {
|
|||
$knownUserService,
|
||||
$userSession,
|
||||
$emailValidator,
|
||||
$userManager,
|
||||
$shareWithGroupOnlyExcludeGroupsList,
|
||||
IShare::TYPE_USER,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class MailPluginTest extends TestCase {
|
|||
protected IGroupManager&MockObject $groupManager;
|
||||
protected KnownUserService&MockObject $knownUserService;
|
||||
protected IUserSession&MockObject $userSession;
|
||||
protected IUserManager&MockObject $userManager;
|
||||
|
||||
#[\Override]
|
||||
protected function setUp(): void {
|
||||
|
|
@ -49,6 +50,17 @@ class MailPluginTest extends TestCase {
|
|||
$this->groupManager = $this->createMock(IGroupManager::class);
|
||||
$this->knownUserService = $this->createMock(KnownUserService::class);
|
||||
$this->userSession = $this->createMock(IUserSession::class);
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->userManager
|
||||
->method('get')
|
||||
->willReturnCallback(function (string $uid): IUser {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user
|
||||
->method('getUID')
|
||||
->willReturn($uid);
|
||||
|
||||
return $user;
|
||||
});
|
||||
$this->cloudIdManager = new CloudIdManager(
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class),
|
||||
|
|
@ -69,6 +81,7 @@ class MailPluginTest extends TestCase {
|
|||
$this->knownUserService,
|
||||
$this->userSession,
|
||||
$this->getEmailValidatorWithStrictEmailCheck(),
|
||||
$this->userManager,
|
||||
[],
|
||||
$shareType,
|
||||
);
|
||||
|
|
@ -727,7 +740,7 @@ class MailPluginTest extends TestCase {
|
|||
]
|
||||
],
|
||||
false,
|
||||
['users' => [], 'exact' => ['users' => [['uuid' => 'uid1', 'name' => 'User', 'label' => 'User (test@example.com)','value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'shareWithDisplayNameUnique' => 'test@example.com']]]],
|
||||
['users' => [], 'exact' => ['users' => [['uuid' => 'uid1', 'name' => 'User', 'label' => 'User (test@example.com)', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'shareWithDisplayNameUnique' => 'test@example.com']]]],
|
||||
true,
|
||||
false,
|
||||
],
|
||||
|
|
@ -872,12 +885,6 @@ class MailPluginTest extends TestCase {
|
|||
return $userToGroupMapping[$user->getUID()];
|
||||
});
|
||||
|
||||
$this->groupManager->expects($this->any())
|
||||
->method('isInGroup')
|
||||
->willReturnCallback(function ($userId, $group) use ($userToGroupMapping) {
|
||||
return in_array($group, $userToGroupMapping[$userId]);
|
||||
});
|
||||
|
||||
$moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
|
||||
$result = $this->searchResult->asArray();
|
||||
|
||||
|
|
@ -942,7 +949,7 @@ class MailPluginTest extends TestCase {
|
|||
'UID' => 'User',
|
||||
]
|
||||
],
|
||||
['emails' => [], 'exact' => ['emails' => [['label' => 'test@example.com', 'uuid' => 'test@example.com', 'value' => ['shareType' => IShare::TYPE_EMAIL,'shareWith' => 'test@example.com']]]]],
|
||||
['emails' => [], 'exact' => ['emails' => [['label' => 'test@example.com', 'uuid' => 'test@example.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@example.com']]]]],
|
||||
false,
|
||||
false,
|
||||
[
|
||||
|
|
@ -996,12 +1003,6 @@ class MailPluginTest extends TestCase {
|
|||
return $userToGroupMapping[$user->getUID()];
|
||||
});
|
||||
|
||||
$this->groupManager->expects($this->any())
|
||||
->method('isInGroup')
|
||||
->willReturnCallback(function ($userId, $group) use ($userToGroupMapping) {
|
||||
return in_array($group, $userToGroupMapping[$userId]);
|
||||
});
|
||||
|
||||
$moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
|
||||
$result = $this->searchResult->asArray();
|
||||
|
||||
|
|
@ -1024,7 +1025,7 @@ class MailPluginTest extends TestCase {
|
|||
'UID' => 'User',
|
||||
]
|
||||
],
|
||||
['users' => [['label' => 'User (test@example.com)', 'uuid' => 'User', 'name' => 'User', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'],'shareWithDisplayNameUnique' => 'test@example.com',]], 'exact' => ['users' => []]],
|
||||
['users' => [['label' => 'User (test@example.com)', 'uuid' => 'User', 'name' => 'User', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'shareWithDisplayNameUnique' => 'test@example.com',]], 'exact' => ['users' => []]],
|
||||
false,
|
||||
false,
|
||||
[
|
||||
|
|
|
|||
Loading…
Reference in a new issue