Skip to content

Commit 87e2c71

Browse files
CarlSchwanbackportbot[bot]
authored andcommitted
feat: Introduce new UserEnumerationFilterEvent
feat: Introduce new UserEnumerationFilterEvent This event allow apps to filter the user returned by queries. Signed-off-by: Carl Schwan <carlschwan@kde.org> [skip ci]
1 parent d7a525f commit 87e2c71

5 files changed

Lines changed: 84 additions & 4 deletions

File tree

apps/user_status/lib/Controller/StatusesController.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
use OCP\AppFramework\Http\DataResponse;
1919
use OCP\AppFramework\OCS\OCSNotFoundException;
2020
use OCP\AppFramework\OCSController;
21+
use OCP\EventDispatcher\IEventDispatcher;
2122
use OCP\IRequest;
23+
use OCP\User\Events\UserEnumerationFilterEvent;
2224
use OCP\UserStatus\IUserStatus;
2325

2426
/**
@@ -37,7 +39,8 @@ class StatusesController extends OCSController {
3739
public function __construct(
3840
string $appName,
3941
IRequest $request,
40-
private StatusService $service,
42+
private readonly StatusService $service,
43+
private readonly IEventDispatcher $eventDispatcher,
4144
) {
4245
parent::__construct($appName, $request);
4346
}
@@ -56,6 +59,15 @@ public function __construct(
5659
public function findAll(?int $limit = null, ?int $offset = null): DataResponse {
5760
$allStatuses = $this->service->findAll($limit, $offset);
5861

62+
$users = array_map(fn (UserStatus $userStatus): string => $userStatus->getUserId(), $allStatuses);
63+
$event = new UserEnumerationFilterEvent($users);
64+
$this->eventDispatcher->dispatchTyped($event);
65+
66+
if ($users !== $event->getUsers()) {
67+
$removedUsers = $event->getFilteredOutUsers();
68+
$allStatuses = array_filter($allStatuses, fn (UserStatus $userStatus): bool => in_array($userStatus->getUserId(), $removedUsers, true));
69+
}
70+
5971
return new DataResponse(array_values(array_map(function ($userStatus) {
6072
return $this->formatStatus($userStatus);
6173
}, $allStatuses)));

apps/user_status/lib/Service/StatusService.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public function __construct(
8181
/**
8282
* @param int|null $limit
8383
* @param int|null $offset
84-
* @return UserStatus[]
84+
* @return list<UserStatus>
8585
*/
8686
public function findAll(?int $limit = null, ?int $offset = null): array {
8787
// Return empty array if user enumeration is disabled or limited to groups
@@ -91,9 +91,9 @@ public function findAll(?int $limit = null, ?int $offset = null): array {
9191
return [];
9292
}
9393

94-
return array_map(function ($status) {
94+
return array_values(array_map(function ($status) {
9595
return $this->processStatus($status);
96-
}, $this->mapper->findAll($limit, $offset));
96+
}, $this->mapper->findAll($limit, $offset)));
9797
}
9898

9999
/**

lib/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,7 @@
10731073
'OCP\\User\\Events\\UserConfigChangedEvent' => $baseDir . '/lib/public/User/Events/UserConfigChangedEvent.php',
10741074
'OCP\\User\\Events\\UserCreatedEvent' => $baseDir . '/lib/public/User/Events/UserCreatedEvent.php',
10751075
'OCP\\User\\Events\\UserDeletedEvent' => $baseDir . '/lib/public/User/Events/UserDeletedEvent.php',
1076+
'OCP\\User\\Events\\UserEnumerationFilterEvent' => $baseDir . '/lib/public/User/Events/UserEnumerationFilterEvent.php',
10761077
'OCP\\User\\Events\\UserFirstTimeLoggedInEvent' => $baseDir . '/lib/public/User/Events/UserFirstTimeLoggedInEvent.php',
10771078
'OCP\\User\\Events\\UserIdAssignedEvent' => $baseDir . '/lib/public/User/Events/UserIdAssignedEvent.php',
10781079
'OCP\\User\\Events\\UserIdUnassignedEvent' => $baseDir . '/lib/public/User/Events/UserIdUnassignedEvent.php',

lib/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
11141114
'OCP\\User\\Events\\UserConfigChangedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserConfigChangedEvent.php',
11151115
'OCP\\User\\Events\\UserCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserCreatedEvent.php',
11161116
'OCP\\User\\Events\\UserDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserDeletedEvent.php',
1117+
'OCP\\User\\Events\\UserEnumerationFilterEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserEnumerationFilterEvent.php',
11171118
'OCP\\User\\Events\\UserFirstTimeLoggedInEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserFirstTimeLoggedInEvent.php',
11181119
'OCP\\User\\Events\\UserIdAssignedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserIdAssignedEvent.php',
11191120
'OCP\\User\\Events\\UserIdUnassignedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserIdUnassignedEvent.php',
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCP\User\Events;
11+
12+
use OCP\AppFramework\Attribute\Consumable;
13+
use OCP\AppFramework\Attribute\Listenable;
14+
use OCP\EventDispatcher\Event;
15+
16+
/**
17+
* @brief This event is triggered when a list of users is returned to the user.
18+
*
19+
* Applications that restricts the enumeration of users should listen to this event
20+
* and modify the list of users with the getUsers and setUsers method.
21+
*
22+
* @since 31.0.14
23+
*/
24+
#[Consumable(since: '31.0.14')]
25+
#[Listenable(since: '31.0.14')]
26+
class UserEnumerationFilterEvent extends Event {
27+
/** @var list<string> $initialUsers */
28+
private readonly array $initialUsers;
29+
30+
/**
31+
* @param list<string> $users
32+
* @since 31.0.14
33+
*/
34+
public function __construct(
35+
private array $users,
36+
) {
37+
$this->initialUsers = $users;
38+
parent::__construct();
39+
}
40+
41+
/**
42+
* @return list<string>
43+
* @since 31.0.14
44+
*/
45+
public function getUsers(): array {
46+
return $this->users;
47+
}
48+
49+
/**
50+
* @param list<string> $users
51+
* @since 31.0.14
52+
*/
53+
public function setUsers(array $users): void {
54+
$this->users = $users;
55+
}
56+
57+
/**
58+
* Get the users what were filtered out by one of the listeners of this event.
59+
*
60+
* @return array<int<0, max>, string> $users
61+
* @since 31.0.14
62+
*/
63+
public function getFilteredOutUsers(): array {
64+
return array_diff($this->initialUsers, $this->users);
65+
}
66+
}

0 commit comments

Comments
 (0)