qwewqe
All checks were successful
Deploy / deploy-staging (push) Successful in 24s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-06-24 00:50:15 +02:00
parent 30d7456fde
commit 9ea248753e
7 changed files with 387 additions and 4 deletions

View File

@@ -61,6 +61,82 @@ final class LdapProvisioner
return $this->getUserByUsername($username, ['uid']) !== null;
}
/**
* @return array<int, array<string, string>>
*/
public function searchUsers(string $needle = '', int $limit = 200): array
{
try {
$link = $this->connectAsService();
$baseDn = trim((string) ($this->config['ldap']['users_dn'] ?? ''));
if ($baseDn === '') {
return [];
}
$needle = trim($needle);
$escaped = $this->escapeFilterValue($needle);
$filter = $escaped === ''
? '(&(objectClass=person)(uid=*))'
: '(&(objectClass=person)(|(uid=*' . $escaped . '*)(cn=*' . $escaped . '*)(displayName=*' . $escaped . '*)(mail=*' . $escaped . '*)(givenName=*' . $escaped . '*)(sn=*' . $escaped . '*)))';
$search = @ldap_search(
$link,
$baseDn,
$filter,
['uid', 'cn', 'displayName', 'mail', 'givenName', 'sn'],
0,
max(1, min($limit, 500))
);
if ($search === false) {
return [];
}
$entries = ldap_get_entries($link, $search);
if (!is_array($entries) || (int) ($entries['count'] ?? 0) < 1) {
return [];
}
$results = [];
for ($index = 0; $index < (int) $entries['count']; $index++) {
$entry = $entries[$index] ?? null;
if (!is_array($entry)) {
continue;
}
$username = $this->firstAttributeValue($entry, 'uid');
if ($username === '') {
continue;
}
$displayName = $this->firstAttributeValue($entry, 'displayname');
if ($displayName === '') {
$displayName = $this->firstAttributeValue($entry, 'cn');
}
$results[] = [
'username' => $username,
'display_name' => $displayName,
'email' => $this->firstAttributeValue($entry, 'mail'),
'dn' => (string) ($entry['dn'] ?? ''),
];
}
usort(
$results,
static fn (array $left, array $right): int => strnatcasecmp(
(string) ($left['username'] ?? ''),
(string) ($right['username'] ?? '')
)
);
return $results;
} catch (\Throwable) {
return [];
}
}
/**
* @param array<int, string> $attributes
* @return array<string, mixed>|null
@@ -608,6 +684,38 @@ final class LdapProvisioner
return is_string($error) && $error !== '' ? $error : 'Unbekannter LDAP-Fehler';
}
private function escapeFilterValue(string $value): string
{
if ($value === '') {
return '';
}
if (function_exists('ldap_escape')) {
return (string) ldap_escape($value, '', LDAP_ESCAPE_FILTER);
}
return strtr($value, [
'\\' => '\5c',
'*' => '\2a',
'(' => '\28',
')' => '\29',
"\0" => '\00',
]);
}
/**
* @param array<string, mixed> $entry
*/
private function firstAttributeValue(array $entry, string $attribute): string
{
$value = $entry[strtolower($attribute)] ?? null;
if (!is_array($value)) {
return '';
}
return isset($value[0]) ? trim((string) $value[0]) : '';
}
private function generateUuidV4(): string
{
$bytes = random_bytes(16);

View File

@@ -335,6 +335,14 @@ final class RegistrationService
return $this->ldapProvisioner->updateUserPassword($username, $password);
}
/**
* @return array<int, array<string, string>>
*/
public function searchExistingUsers(string $needle = '', int $limit = 200): array
{
return $this->ldapProvisioner->searchUsers($needle, $limit);
}
/**
* @return array<int, array<string, mixed>>
*/