Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/private/DB/ConnectionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public function createConnectionParams(string $configPrefix = '', array $additio
//additional driver options, eg. for mysql ssl
$driverOptions = $this->config->getValue($configPrefix . 'dbdriveroptions', $this->config->getValue('dbdriveroptions', null));
if ($driverOptions) {
$connectionParams['driverOptions'] = array_merge($connectionParams['driverOptions'], $driverOptions);
$connectionParams['driverOptions'] = $driverOptions + ($connectionParams['driverOptions'] ?? []);
}

// set default table creation options
Expand Down
55 changes: 55 additions & 0 deletions tests/lib/DB/ConnectionFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,64 @@ public function testSplitHostFromPortAndSocket($host, array $expected): void {
$this->assertEquals($expected, self::invokePrivate($factory, 'splitHostFromPortAndSocket', [$host]));
}

/**
* The numeric value of a PDO MySQL attribute, e.g. `SSL_CA`.
*
* The values are not stable across PHP versions, so they must never be hardcoded.
* Since PHP 8.5 the `PDO::MYSQL_ATTR_*` constants are deprecated in favor of
* `Pdo\Mysql::ATTR_*`, and either only exists with the MySQL driver installed.
*/
private function mysqlAttribute(string $name): int {
if (!extension_loaded('pdo_mysql')) {
$this->markTestSkipped('The pdo_mysql extension is required to resolve the PDO attribute values');
}
if (PHP_VERSION_ID >= 80500 && class_exists(\Pdo\Mysql::class)) {
return (int)constant('Pdo\Mysql::ATTR_' . $name);
}
return (int)constant('PDO::MYSQL_ATTR_' . $name);
}

public function testMysqlSslConnection(): void {
/** @var SystemConfig|\PHPUnit\Framework\MockObject\MockObject $config */
$config = $this->createMock(SystemConfig::class);
$config->method('getValue')
->willReturnCallback(function ($key, $default) {
return match ($key) {
'dbdriveroptions' => [
$this->mysqlAttribute('SSL_CA') => 'rootCA.crt',
$this->mysqlAttribute('SSL_CERT') => 'client.crt',
$this->mysqlAttribute('SSL_KEY') => 'client.key',
$this->mysqlAttribute('SSL_VERIFY_SERVER_CERT') => true,
],
'dbtype' => 'mysql',
default => $default,
};
});
$factory = new ConnectionFactory($config);

$params = $factory->createConnectionParams();

$this->assertEquals('pdo_mysql', $params['driver']);
$this->assertEquals([
$this->mysqlAttribute('FOUND_ROWS') => true,
$this->mysqlAttribute('SSL_CA') => 'rootCA.crt',
$this->mysqlAttribute('SSL_CERT') => 'client.crt',
$this->mysqlAttribute('SSL_KEY') => 'client.key',
$this->mysqlAttribute('SSL_VERIFY_SERVER_CERT') => true,
], $params['driverOptions']);
}

public function testPgsqlSslConnection(): void {
/** @var SystemConfig|\PHPUnit\Framework\MockObject\MockObject $config */
$config = $this->createMock(SystemConfig::class);
$config->method('getValue')
->willReturnCallback(function ($key, $default) {
return match ($key) {
'dbtype' => 'pgsql',
'dbdriveroptions' => [
1 => 'foo',
3 => 'bar',
],
'pgsql_ssl' => [
'mode' => 'verify-full',
'cert' => 'client.crt',
Expand All @@ -68,5 +119,9 @@ public function testPgsqlSslConnection(): void {
$this->assertEquals('client.crt', $params['sslcert']);
$this->assertEquals('client.key', $params['sslkey']);
$this->assertEquals('client.crl', $params['sslcrl']);
$this->assertEquals([
1 => 'foo',
3 => 'bar',
], $params['driverOptions']);
}
}