Merge pull request #59040 from nextcloud/backport/59034/stable31
Some checks are pending
Integration sqlite / changes (push) Waiting to run
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, --tags ~@large files_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, capabilities_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, collaboration_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, comments_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, dav_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, federation_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, file_conversions) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, files_reminders) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, filesdrop_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, ldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, openldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, openldap_numerical_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, remoteapi_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, setup_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, sharees_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, sharing_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, theming_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (stable31, 8.1, stable31, videoverification_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite-summary (push) Blocked by required conditions
Psalm static code analysis / static-code-analysis (push) Waiting to run
Psalm static code analysis / static-code-analysis-security (push) Waiting to run
Psalm static code analysis / static-code-analysis-ocp (push) Waiting to run
Psalm static code analysis / static-code-analysis-ncu (push) Waiting to run

[stable31] fix(LDAP): use displayname from DB, before reaching out to LDAP
This commit is contained in:
Arthur Schiwon 2026-03-18 21:20:40 +01:00 committed by GitHub
commit b0210d03c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 58 additions and 47 deletions

View file

@ -704,7 +704,7 @@ class Access extends LDAPUtility {
continue;
}
$sndName = $ldapObject[$sndAttribute][0] ?? '';
$this->cacheUserDisplayName($ncName, $nameByLDAP, $sndName);
$this->applyUserDisplayName($ncName, $nameByLDAP, $sndName);
} elseif ($nameByLDAP !== null) {
$this->cacheGroupDisplayName($ncName, $nameByLDAP);
}
@ -752,20 +752,16 @@ class Access extends LDAPUtility {
$this->connection->writeToCache('groupExists' . $gid, true);
}
/**
* caches the user display name
*
* @param string $ocName the internal Nextcloud username
* @param string $displayName the display name
* @param string $displayName2 the second display name
* @throws \Exception
*/
public function cacheUserDisplayName(string $ocName, string $displayName, string $displayName2 = ''): void {
$user = $this->userManager->get($ocName);
public function applyUserDisplayName(string $uid, string $displayName, string $displayName2 = ''): void {
$user = $this->userManager->get($uid);
if ($user === null) {
return;
}
$displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
$composedDisplayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
$this->cacheUserDisplayName($uid, $composedDisplayName);
}
public function cacheUserDisplayName(string $ocName, string $displayName): void {
$cacheKeyTrunk = 'getDisplayName';
$this->connection->writeToCache($cacheKeyTrunk . $ocName, $displayName);
}

View file

@ -113,12 +113,8 @@ class User {
$displayName2 = (string)$ldapEntry[$attr][0];
}
if ($displayName !== '') {
$this->composeAndStoreDisplayName($displayName, $displayName2);
$this->access->cacheUserDisplayName(
$this->getUsername(),
$displayName,
$displayName2
);
$composedDisplayName = $this->composeAndStoreDisplayName($displayName, $displayName2);
$this->access->cacheUserDisplayName($this->getUsername(), $composedDisplayName);
}
unset($attr);
@ -128,7 +124,8 @@ class User {
$attr = strtolower($this->connection->ldapEmailAttribute);
if (isset($ldapEntry[$attr])) {
$mailValue = 0;
for ($x = 0; $x < count($ldapEntry[$attr]); $x++) {
$emailValues = count($ldapEntry[$attr]);
for ($x = 0; $x < $emailValues; $x++) {
if (filter_var($ldapEntry[$attr][$x], FILTER_VALIDATE_EMAIL)) {
$mailValue = $x;
break;
@ -451,6 +448,10 @@ class User {
return $displayName;
}
public function fetchStoredDisplayName(): string {
return $this->config->getUserValue($this->uid, 'user_ldap', 'displayName', '');
}
/**
* Stores the LDAP Username in the Database
*/

View file

@ -409,26 +409,21 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
return $path;
}
/**
* get display name of the user
* @param string $uid user ID of the user
* @return string|false display name
*/
public function getDisplayName($uid) {
if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
return $this->userPluginManager->getDisplayName($uid);
private function getDisplayNameFromDatabase(string $uid): ?string {
$user = $this->access->userManager->get($uid);
if ($user instanceof User) {
$displayName = $user->fetchStoredDisplayName();
if ($displayName !== '') {
return $displayName;
}
}
if (!$this->userExists($uid)) {
return false;
if ($user instanceof OfflineUser) {
return $user->getDisplayName();
}
return null;
}
$cacheKey = 'getDisplayName' . $uid;
if (!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
return $displayName;
}
//Check whether the display name is configured to have a 2nd feature
private function getDisplayNameFromLdap(string $uid): string {
$additionalAttribute = $this->access->connection->ldapUserDisplayName2;
$displayName2 = '';
if ($additionalAttribute !== '') {
@ -450,16 +445,40 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
$user = $this->access->userManager->get($uid);
if ($user instanceof User) {
$displayName = $user->composeAndStoreDisplayName($displayName, (string)$displayName2);
$this->access->connection->writeToCache($cacheKey, $displayName);
return $user->composeAndStoreDisplayName($displayName, (string)$displayName2);
}
if ($user instanceof OfflineUser) {
$displayName = $user->getDisplayName();
return $user->getDisplayName();
}
}
return '';
}
public function getDisplayName($uid): string {
if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
return $this->userPluginManager->getDisplayName($uid);
}
if (!$this->userExists($uid)) {
return '';
}
$cacheKey = 'getDisplayName' . $uid;
if (!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
return $displayName;
}
return null;
if ($displayName = $this->getDisplayNameFromDatabase($uid)) {
$this->access->connection->writeToCache($cacheKey, $displayName);
return $displayName;
}
if ($displayName = $this->getDisplayNameFromLdap($uid)) {
$this->access->connection->writeToCache($cacheKey, $displayName);
}
return $displayName;
}
/**
@ -483,7 +502,8 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
* @param string $search
* @param int|null $limit
* @param int|null $offset
* @return array an array of all displayNames (value) and the corresponding uids (key)
* @return array an array of all displayNames (value) and the corresponding
* uids (key)
*/
public function getDisplayNames($search = '', $limit = null, $offset = null) {
$cacheKey = 'getDisplayNames-' . $search . '-' . $limit . '-' . $offset;

View file

@ -1101,16 +1101,10 @@
</InvalidDocblock>
</file>
<file src="apps/user_ldap/lib/User_LDAP.php">
<ImplementedReturnTypeMismatch>
<code><![CDATA[string|false]]></code>
</ImplementedReturnTypeMismatch>
<MoreSpecificImplementedParamType>
<code><![CDATA[$limit]]></code>
<code><![CDATA[$offset]]></code>
</MoreSpecificImplementedParamType>
<NullableReturnStatement>
<code><![CDATA[null]]></code>
</NullableReturnStatement>
<RedundantCondition>
<code><![CDATA[$displayName && (count($displayName) > 0)]]></code>
<code><![CDATA[is_string($dn)]]></code>