Loading patches/025-optimize-get-by-email.patch +62 −13 Original line number Diff line number Diff line Loading @@ -4,7 +4,35 @@ Subject: [PATCH] To optimize getByEmail as we have boundary conditions that emai --- ./lib/private/User/Manager.php 2023-05-05 18:29:34.818568291 +0530 +++ ./lib/private/User/Manager-new.php 2023-05-05 18:33:49.872682118 +0530 @@ -653,12 +653,33 @@ @@ -270,11 +270,26 @@ public function search($pattern, $limit = null, $offset = null) { $users = []; + + // If pattern contains @, also search by email (domain-independent search) + if(str_contains($pattern, '@')) { + $usersByEmail = $this->getByEmail($pattern); + foreach($usersByEmail as $user) { + if($user instanceof IUser) { + $users[$user->getUID()] = $user; + } + } + } + + // Search by username through backends foreach ($this->backends as $backend) { $backendUsers = $backend->getUsers($pattern, $limit, $offset); if (is_array($backendUsers)) { foreach ($backendUsers as $uid) { - $users[$uid] = new LazyUser($uid, $this, null, $backend); + // Avoid duplicates if already found via email search + if(!isset($users[$uid])) { + $users[$uid] = new LazyUser($uid, $this, null, $backend); + } } } } @@ -687,12 +702,54 @@ */ public function getByEmail($email) { // looking for 'email' only (and not primary_mail) is intentional Loading @@ -23,20 +51,41 @@ Subject: [PATCH] To optimize getByEmail as we have boundary conditions that emai + return $this->get($uid); + }, $userIds); + } else { + $uid = ''; + $legacyDomainSuffix = empty($legacyDomain) ? '' : '@' . $legacyDomain; + $mainDomainSuffix = empty($mainDomain) ? '' : '@' . $mainDomain; + // Normalize email to lowercase for case-insensitive comparison + $emailLower = mb_strtolower($email, 'UTF-8'); + $legacyDomainSuffix = empty($legacyDomain) ? '' : '@' . mb_strtolower($legacyDomain, 'UTF-8'); + $mainDomainSuffix = empty($mainDomain) ? '' : '@' . mb_strtolower($mainDomain, 'UTF-8'); + + if (!empty($legacyDomainSuffix) && str_ends_with($email, $legacyDomainSuffix)) { + // In case of legacy_domain, username is email + $uid = $email; + } else if (!empty($mainDomainSuffix) && str_ends_with($email, $mainDomainSuffix)) { + // In case of main_domain, username is email without domain suffix + $uid = str_replace($mainDomainSuffix, '', $email); + } + // If no match of domain, no user + if(!empty($uid)) { + $users = [$this->get($uid)]; + // Domain-independent search: try multiple uid formats to resolve user + $candidates = []; + if (str_contains($emailLower, '@')) { + // Input has domain - resolve using domain rules (case-insensitive) + if (!empty($legacyDomainSuffix) && str_ends_with($emailLower, $legacyDomainSuffix)) { + // For legacy domain, uid is the full email (preserve original case) + $candidates[] = $email; + } elseif (!empty($mainDomainSuffix) && str_ends_with($emailLower, $mainDomainSuffix)) { + // For main domain, uid is local part without domain + // Extract local part by finding @ position (case-insensitive) + $atPos = strrpos($emailLower, '@'); + if ($atPos !== false) { + $localPart = substr($email, 0, $atPos); + $candidates[] = $localPart; + } + } + } else { + // No domain in input - try both formats for domain-independent lookup + if (!empty($legacyDomainSuffix)) { + $candidates[] = $email . $legacyDomainSuffix; // try as legacy user (user@e.email) + } + $candidates[] = $email; // try as main domain user (uid = user1) + } + + foreach ($candidates as $uid) { + $user = $this->get($uid); + if ($user instanceof IUser) { + $users = [$user]; + break; // found a match, email is unique per user + } + } + } return array_values(array_filter($users, function ($u) { Loading Loading
patches/025-optimize-get-by-email.patch +62 −13 Original line number Diff line number Diff line Loading @@ -4,7 +4,35 @@ Subject: [PATCH] To optimize getByEmail as we have boundary conditions that emai --- ./lib/private/User/Manager.php 2023-05-05 18:29:34.818568291 +0530 +++ ./lib/private/User/Manager-new.php 2023-05-05 18:33:49.872682118 +0530 @@ -653,12 +653,33 @@ @@ -270,11 +270,26 @@ public function search($pattern, $limit = null, $offset = null) { $users = []; + + // If pattern contains @, also search by email (domain-independent search) + if(str_contains($pattern, '@')) { + $usersByEmail = $this->getByEmail($pattern); + foreach($usersByEmail as $user) { + if($user instanceof IUser) { + $users[$user->getUID()] = $user; + } + } + } + + // Search by username through backends foreach ($this->backends as $backend) { $backendUsers = $backend->getUsers($pattern, $limit, $offset); if (is_array($backendUsers)) { foreach ($backendUsers as $uid) { - $users[$uid] = new LazyUser($uid, $this, null, $backend); + // Avoid duplicates if already found via email search + if(!isset($users[$uid])) { + $users[$uid] = new LazyUser($uid, $this, null, $backend); + } } } } @@ -687,12 +702,54 @@ */ public function getByEmail($email) { // looking for 'email' only (and not primary_mail) is intentional Loading @@ -23,20 +51,41 @@ Subject: [PATCH] To optimize getByEmail as we have boundary conditions that emai + return $this->get($uid); + }, $userIds); + } else { + $uid = ''; + $legacyDomainSuffix = empty($legacyDomain) ? '' : '@' . $legacyDomain; + $mainDomainSuffix = empty($mainDomain) ? '' : '@' . $mainDomain; + // Normalize email to lowercase for case-insensitive comparison + $emailLower = mb_strtolower($email, 'UTF-8'); + $legacyDomainSuffix = empty($legacyDomain) ? '' : '@' . mb_strtolower($legacyDomain, 'UTF-8'); + $mainDomainSuffix = empty($mainDomain) ? '' : '@' . mb_strtolower($mainDomain, 'UTF-8'); + + if (!empty($legacyDomainSuffix) && str_ends_with($email, $legacyDomainSuffix)) { + // In case of legacy_domain, username is email + $uid = $email; + } else if (!empty($mainDomainSuffix) && str_ends_with($email, $mainDomainSuffix)) { + // In case of main_domain, username is email without domain suffix + $uid = str_replace($mainDomainSuffix, '', $email); + } + // If no match of domain, no user + if(!empty($uid)) { + $users = [$this->get($uid)]; + // Domain-independent search: try multiple uid formats to resolve user + $candidates = []; + if (str_contains($emailLower, '@')) { + // Input has domain - resolve using domain rules (case-insensitive) + if (!empty($legacyDomainSuffix) && str_ends_with($emailLower, $legacyDomainSuffix)) { + // For legacy domain, uid is the full email (preserve original case) + $candidates[] = $email; + } elseif (!empty($mainDomainSuffix) && str_ends_with($emailLower, $mainDomainSuffix)) { + // For main domain, uid is local part without domain + // Extract local part by finding @ position (case-insensitive) + $atPos = strrpos($emailLower, '@'); + if ($atPos !== false) { + $localPart = substr($email, 0, $atPos); + $candidates[] = $localPart; + } + } + } else { + // No domain in input - try both formats for domain-independent lookup + if (!empty($legacyDomainSuffix)) { + $candidates[] = $email . $legacyDomainSuffix; // try as legacy user (user@e.email) + } + $candidates[] = $email; // try as main domain user (uid = user1) + } + + foreach ($candidates as $uid) { + $user = $this->get($uid); + if ($user instanceof IUser) { + $users = [$user]; + break; // found a match, email is unique per user + } + } + } return array_values(array_filter($users, function ($u) { Loading