Ldap host failover: updated method names and split out method

This commit is contained in:
Dan Brown 2022-10-16 22:40:10 +01:00
parent 392eef8273
commit 303dbf9b01
No known key found for this signature in database
GPG key ID: 46D9F943C24A2EF9

View file

@ -216,7 +216,7 @@ class LdapService
$this->ldap->setOption(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER); $this->ldap->setOption(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER);
} }
$serverDetails = $this->parseEnvironmentServer($this->config['server']); $serverDetails = $this->parseMultiServerString($this->config['server']);
$this->ldapConnection = $this->prepareServerConnection($serverDetails); $this->ldapConnection = $this->prepareServerConnection($serverDetails);
return $this->ldapConnection; return $this->ldapConnection;
@ -225,7 +225,7 @@ class LdapService
/** /**
* Processes an array of received servers and returns the first working connection. * Processes an array of received servers and returns the first working connection.
* *
* @param array $serverDetails * @param array $serverDetails array<array{host: string, port: int}>
* @return resource * @return resource
* @throws LdapException * @throws LdapException
*/ */
@ -234,31 +234,7 @@ class LdapService
$lastException = null; $lastException = null;
foreach ($serverDetails as $server) { foreach ($serverDetails as $server) {
try { try {
$ldapConnection = $this->ldap->connect($server['host'], $server['port']); return $this->startServerConnection($server);
if (!$ldapConnection) {
throw new LdapException(trans('errors.ldap_cannot_connect'));
}
// Set any required options
if ($this->config['version']) {
$this->ldap->setVersion($ldapConnection, $this->config['version']);
}
// Start and verify TLS if it's enabled
if ($this->config['start_tls']) {
try {
$tlsStarted = $this->ldap->startTls($ldapConnection);
} catch (ErrorException $exception) {
$tlsStarted = false;
}
if (!$tlsStarted) {
throw new LdapException('Could not start TLS connection');
}
}
return $ldapConnection;
} catch (LdapException $exception) { } catch (LdapException $exception) {
$lastException = $exception; $lastException = $exception;
} }
@ -268,27 +244,61 @@ class LdapService
} }
/** /**
* Parse environment variable with LDAP server and returns an array of recognized servers. * Attempt to start a server connection from the provided details.
* If you need to use multiple addresses, separate them with a semicolon. *
* Ex: 'ldap.example.com:8069;ldaps://ldap.example.com' * @param array{host: string, port: int} $serverDetail
* @return resource
* @throws LdapException
*/ */
protected function parseEnvironmentServer(string $environmentServer): array protected function startServerConnection(array $serverDetail)
{ {
$explodedEnvironmentServer = explode(';', $environmentServer); $ldapConnection = $this->ldap->connect($serverDetail['host'], $serverDetail['port']);
$result_servers = [];
foreach ($explodedEnvironmentServer as $serverString) { if (!$ldapConnection) {
$result_servers[] = $this->parseServerString($serverString); throw new LdapException(trans('errors.ldap_cannot_connect'));
} }
return $result_servers; // Set any required options
if ($this->config['version']) {
$this->ldap->setVersion($ldapConnection, $this->config['version']);
}
// Start and verify TLS if it's enabled
if ($this->config['start_tls']) {
try {
$tlsStarted = $this->ldap->startTls($ldapConnection);
} catch (ErrorException $exception) {
$tlsStarted = false;
}
if (!$tlsStarted) {
throw new LdapException('Could not start TLS connection');
}
}
return $ldapConnection;
} }
/** /**
* Parse a LDAP server string and return the host and port for a connection. * Parse a potentially multi-value LDAP server host string and return an array of host/port detail pairs.
* Is flexible to formats such as 'ldap.example.com:8069' or 'ldaps://ldap.example.com'. * Multiple hosts are separated with a semicolon, for example: 'ldap.example.com:8069;ldaps://ldap.example.com'
*
* @return array<array{host: string, port: int}>
*/ */
protected function parseServerString(string $serverString): array protected function parseMultiServerString(string $serversString): array
{
$serverStringList = explode(';', $serversString);
return array_map(fn ($serverStr) => $this->parseSingleServerString($serverStr), $serverStringList);
}
/**
* Parse an LDAP server string and return the host and port for a connection.
* Is flexible to formats such as 'ldap.example.com:8069' or 'ldaps://ldap.example.com'.
*
* @return array{host: string, port: int}
*/
protected function parseSingleServerString(string $serverString): array
{ {
$serverNameParts = explode(':', $serverString); $serverNameParts = explode(':', $serverString);