diff --git a/framework/core/src/Api/Controller/ListUsersController.php b/framework/core/src/Api/Controller/ListUsersController.php index 6e3c03652..bc31ef2b0 100644 --- a/framework/core/src/Api/Controller/ListUsersController.php +++ b/framework/core/src/Api/Controller/ListUsersController.php @@ -76,6 +76,13 @@ class ListUsersController extends AbstractListController $actor->assertCan('viewUserList'); + if (! $actor->hasPermission('user.viewLastSeenAt')) { + // If a user cannot see everyone's last online date, we prevent them from sorting by it + // Otherwise this sort field would defeat the privacy setting discloseOnline + // We use remove instead of add so that extensions can still completely disable the sort using the extender + $this->removeSortField('lastSeenAt'); + } + $filters = $this->extractFilter($request); $sort = $this->extractSort($request); diff --git a/framework/core/tests/integration/api/users/ListTest.php b/framework/core/tests/integration/api/users/ListTest.php index 72199e3b4..f7e1b5137 100644 --- a/framework/core/tests/integration/api/users/ListTest.php +++ b/framework/core/tests/integration/api/users/ListTest.php @@ -91,6 +91,49 @@ class ListTest extends TestCase $this->assertEquals(['1', '2'], Arr::pluck($data, 'id')); } + /** + * @test + */ + public function allows_last_seen_sorting_with_permission() + { + $this->prepareDatabase([ + 'group_permission' => [ + ['permission' => 'viewUserList', 'group_id' => 2], + ['permission' => 'user.viewLastSeenAt', 'group_id' => 2], + ], + ]); + + $response = $this->send( + $this->request('GET', '/api/users') + ->withQueryParams([ + 'sort' => 'lastSeenAt', + ]) + ); + + $this->assertEquals(200, $response->getStatusCode()); + } + + /** + * @test + */ + public function disallows_last_seen_sorting_without_permission() + { + $this->prepareDatabase([ + 'group_permission' => [ + ['permission' => 'viewUserList', 'group_id' => 2], + ], + ]); + + $response = $this->send( + $this->request('GET', '/api/users') + ->withQueryParams([ + 'sort' => 'lastSeenAt', + ]) + ); + + $this->assertEquals(400, $response->getStatusCode()); + } + /** * @test */