From 5924a2e3ecb2e7d6384a293396e9562b22d54548 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 13 Jan 2026 15:17:49 +0100 Subject: [PATCH] feat: add api to get a user object without verifying they exist Signed-off-by: Robin Appelman --- lib/private/User/Manager.php | 4 ++++ lib/public/IUserManager.php | 18 ++++++++++++++++++ tests/lib/User/ManagerTest.php | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 2bea9bb65dd..2c79ba3e618 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -833,4 +833,8 @@ class Manager extends PublicEmitter implements IUserManager { } } while (count($userIds) === $batchSize && $limit !== 0); } + + public function getExistingUser(string $userId, ?string $displayName = null): IUser { + return new LazyUser($userId, $this, $displayName); + } } diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index caf1a704cce..18962f9f6d9 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -62,6 +62,9 @@ interface IUserManager { /** * get a user by user id * + * If you're already 100% sure that the user exists, + * consider IUserManager::getExistingUser which has less overhead. + * * @param string $uid * @return \OCP\IUser|null Either the user or null if the specified user does not exist * @since 8.0.0 @@ -246,4 +249,19 @@ interface IUserManager { * @since 32.0.0 */ public function getSeenUsers(int $offset = 0, ?int $limit = null): \Iterator; + + /** + * Get a user by user id without validating that the user exists. + * + * This should only be used if you're certain that the provided user id exists in the system. + * Using this to get a user object for a non-existing user will lead to unexpected behavior down the line. + * + * If you're not 100% sure that the user exists, use IUserManager::get instead. + * + * @param string $userId + * @param ?string $displayName If the display name is known in advance you can provide it so it doesn't have to be fetched again + * @return IUser + * @since 33.0.0 + */ + public function getExistingUser(string $userId, ?string $displayName = null): IUser; } diff --git a/tests/lib/User/ManagerTest.php b/tests/lib/User/ManagerTest.php index 7dadc4e9e8f..17007aa8a24 100644 --- a/tests/lib/User/ManagerTest.php +++ b/tests/lib/User/ManagerTest.php @@ -740,4 +740,26 @@ class ManagerTest extends TestCase { $this->assertEquals('uid1', $users[0]->getUID()); $this->assertEquals('uid2', $users[1]->getUID()); } + + public function testGetExistingUser() { + $backend = $this->createMock(\Test\Util\User\Dummy::class); + $backend->method('userExists') + ->with('foobar') + ->willReturn(true); + $backend->method('getDisplayName') + ->willReturn('Foo Bar'); + $backend->method('implementsActions') + ->willReturnCallback(fn (int $action) => $action === Backend::GET_DISPLAYNAME); + + $manager = new Manager($this->config, $this->cacheFactory, $this->eventDispatcher, $this->logger); + $manager->registerBackend($backend); + + $user = $manager->getExistingUser('foobar'); + $this->assertEquals('foobar', $user->getUID()); + $this->assertEquals('Foo Bar', $user->getDisplayName()); + + $user = $manager->getExistingUser('nobody', 'None'); + $this->assertEquals('nobody', $user->getUID()); + $this->assertEquals('None', $user->getDisplayName()); + } }