feat(UserPlugin): Also full match on additional email addresses

Signed-off-by: provokateurin <kate@provokateurin.de>
This commit is contained in:
provokateurin 2026-01-21 10:33:09 +01:00
parent 7539fdbb72
commit bf49f62da3
No known key found for this signature in database
2 changed files with 39 additions and 8 deletions

View file

@ -475,3 +475,23 @@ Feature: sharees_user
And "exact users" sharees returned are
| Test One | 0 | test1 | test@example.com |
And "users" sharees returned is empty
Scenario: Search for exact additional email returns exact user
Given user "test1" with displayname "Test One" exists
And As an "admin"
And sending "PUT" to "/cloud/users/test1" with
| key | email |
| value | test@example.com |
And sending "PUT" to "/cloud/users/test1" with
| key | additional_mail |
| value | test@example.org |
And user "user1" exists
And As an "user1"
When getting sharees for
| search | test@example.org |
| itemType | file |
Then the OCS status code should be "100"
And the HTTP status code should be "200"
And "exact users" sharees returned are
| Test One (test@example.org) | 0 | test1 | test@example.org |
And "users" sharees returned is empty

View file

@ -10,6 +10,7 @@ namespace OC\Collaboration\Collaborators;
use OCP\Collaboration\Collaborators\ISearchPlugin;
use OCP\Collaboration\Collaborators\ISearchResult;
use OCP\Collaboration\Collaborators\SearchResultType;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IAppConfig;
use OCP\IDBConnection;
use OCP\IGroupManager;
@ -106,14 +107,16 @@ readonly class UserPlugin implements ISearchPlugin {
if ($shareeEnumerationFullMatchEmail) {
$qb = $this->connection->getQueryBuilder();
$qb
->selectDistinct('uid')
->select('uid', 'value', 'name')
->from('accounts_data')
->where($qb->expr()->eq($qb->func()->lower('value'), $qb->createNamedParameter($lowerSearch)))
->andWhere($qb->expr()->eq('name', $qb->createNamedParameter('email')));
->andWhere($qb->expr()->in('name', $qb->createNamedParameter(['email', 'additional_mail'], IQueryBuilder::PARAM_STR_ARRAY)));
$result = $qb->executeQuery();
while ($uid = $result->fetchOne()) {
/** @var string $uid */
$users[$uid] = ['exact', $this->userManager->get($uid)];
while ($row = $result->fetch()) {
$uid = $row['uid'];
$email = $row['value'];
$isAdditional = $row['name'] === 'additional_mail';
$users[$uid] = ['exact', $this->userManager->get($uid), $isAdditional ? $email : null];
}
$result->closeCursor();
}
@ -144,17 +147,25 @@ readonly class UserPlugin implements ISearchPlugin {
$result = ['wide' => [], 'exact' => []];
foreach ($users as $match) {
[$type, $user] = $match;
$match[2] ??= null;
[$type, $user, $uniqueDisplayName] = $match;
$displayName = $user->getDisplayName();
if ($uniqueDisplayName !== null) {
$displayName .= ' (' . $uniqueDisplayName . ')';
}
$status = $userStatuses[$user->getUID()] ?? [];
$result[$type][] = [
'label' => $user->getDisplayName(),
'label' => $displayName,
'subline' => $status['message'] ?? '',
'icon' => 'icon-user',
'value' => [
'shareType' => IShare::TYPE_USER,
'shareWith' => $user->getUID(),
],
'shareWithDisplayNameUnique' => $user->getSystemEMailAddress() ?: $user->getUID(),
'shareWithDisplayNameUnique' => $uniqueDisplayName ?? $user->getSystemEMailAddress() ?: $user->getUID(),
'status' => $status,
];
}