From b9c5bc8ec663a74d304015ca1d6b29f65b6df2e9 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Wed, 22 Jul 2026 11:54:33 +0200 Subject: [PATCH] feat: Allow to check user existence outside specific user backends Signed-off-by: Carl Schwan --- lib/private/User/Manager.php | 22 ++++++++++++++++------ lib/public/IUserManager.php | 5 +++-- tests/Core/Command/User/AddTest.php | 5 +++++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 765e8fa3d7b7f..9bd1f20721fda 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -110,19 +110,25 @@ public function clearBackends(): void { * @param string $uid * @return \OC\User\User|null Either the user or null if the specified user does not exist */ - public function get($uid) { + public function get($uid, array $excludeBackends = []) { if (is_null($uid) || $uid === '' || $uid === false) { return null; } - if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends - return $this->cachedUsers[$uid]; - } if (strlen($uid) > IUser::MAX_USERID_LENGTH) { return null; } + // check the cache first to prevent having to loop over the backends + if ($excludeBackends === [] && isset($this->cachedUsers[$uid])) { + return $this->cachedUsers[$uid]; + } + $cachedBackend = $this->cache->get(sha1($uid)); + if (in_array($cachedBackend, $excludeBackends)) { + $cachedBackend = null; + } + if ($cachedBackend !== null && isset($this->backends[$cachedBackend])) { // Cache has the info of the user backend already, so ask that one directly $backend = $this->backends[$cachedBackend]; @@ -137,6 +143,10 @@ public function get($uid) { continue; } + if (in_array($i, $excludeBackends)) { + continue; + } + if ($backend->userExists($uid)) { // Hash $uid to ensure that only valid characters are used for the cache key $this->cache->set(sha1($uid), $i, 300); @@ -180,12 +190,12 @@ public function getUserObject($uid, $backend, $cacheUser = true) { * @param string $uid * @return bool */ - public function userExists($uid) { + public function userExists($uid, array $excludeBackends = []) { if (strlen($uid) > IUser::MAX_USERID_LENGTH) { return false; } - $user = $this->get($uid); + $user = $this->get($uid, $excludeBackends); return ($user !== null); } diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index 973e1c5ef4077..137d595767323 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -78,13 +78,14 @@ public function get($uid); public function getDisplayName(string $uid): ?string; /** - * check if a user exists + * Check if a user exists. * * @param string $uid + * @param list $excludeBackends A list of IUserBackend::getBackendName() that need to be excluded from the search. * @return bool * @since 8.0.0 */ - public function userExists($uid); + public function userExists($uid, array $excludeBackends = []); /** * Check if the password is valid for the user diff --git a/tests/Core/Command/User/AddTest.php b/tests/Core/Command/User/AddTest.php index 5a8bc3abea1e9..42cc6ec198661 100644 --- a/tests/Core/Command/User/AddTest.php +++ b/tests/Core/Command/User/AddTest.php @@ -109,6 +109,11 @@ public function testAddEmail( $this->mailHelper->expects($isEmailValid && $shouldSendEmail ? static::once() : static::never()) ->method('sendMail'); + $this->consoleInput->method('getArgument') + ->willReturnMap([ + ['uid', 'JohnDoe'], + ]); + $this->consoleInput->method('getOption') ->willReturnMap([ ['generate-password', 'true'],