Skip to content

Commit 0fbe2c9

Browse files
authored
ENGCOM-2983: Feature/issue 13561 2.3 #18075
2 parents 01982dc + ef25981 commit 0fbe2c9

File tree

14 files changed

+454
-50
lines changed

14 files changed

+454
-50
lines changed

lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class ConfigOptionsListConstants
2121
const CONFIG_PATH_CRYPT_KEY = 'crypt/key';
2222
const CONFIG_PATH_SESSION_SAVE = 'session/save';
2323
const CONFIG_PATH_RESOURCE_DEFAULT_SETUP = 'resource/default_setup/connection';
24+
const CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS = 'db/connection/default/driver_options';
2425
const CONFIG_PATH_DB_CONNECTION_DEFAULT = 'db/connection/default';
2526
const CONFIG_PATH_DB_CONNECTIONS = 'db/connection';
2627
const CONFIG_PATH_DB_PREFIX = 'db/table_prefix';
@@ -64,6 +65,10 @@ class ConfigOptionsListConstants
6465
const INPUT_KEY_DB_MODEL = 'db-model';
6566
const INPUT_KEY_DB_INIT_STATEMENTS = 'db-init-statements';
6667
const INPUT_KEY_DB_ENGINE = 'db-engine';
68+
const INPUT_KEY_DB_SSL_KEY = 'db-ssl-key';
69+
const INPUT_KEY_DB_SSL_CERT = 'db-ssl-cert';
70+
const INPUT_KEY_DB_SSL_CA = 'db-ssl-ca';
71+
const INPUT_KEY_DB_SSL_VERIFY = 'db-ssl-verify';
6772
const INPUT_KEY_RESOURCE = 'resource';
6873
const INPUT_KEY_SKIP_DB_VALIDATION = 'skip-db-validation';
6974
const INPUT_KEY_CACHE_HOSTS = 'http-cache-hosts';
@@ -104,6 +109,20 @@ class ConfigOptionsListConstants
104109
const KEY_MODEL = 'model';
105110
const KEY_INIT_STATEMENTS = 'initStatements';
106111
const KEY_ACTIVE = 'active';
112+
const KEY_DRIVER_OPTIONS = 'driver_options';
113+
/**#@-*/
114+
115+
/**#@+
116+
* Array keys for database driver options configurations
117+
*/
118+
const KEY_MYSQL_SSL_KEY = \PDO::MYSQL_ATTR_SSL_KEY;
119+
const KEY_MYSQL_SSL_CERT = \PDO::MYSQL_ATTR_SSL_CERT;
120+
const KEY_MYSQL_SSL_CA = \PDO::MYSQL_ATTR_SSL_CA;
121+
/**
122+
* Constant \PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT cannot be used as it was introduced in PHP 7.1.4
123+
* and Magento 2 is currently supporting PHP 7.1.3.
124+
*/
125+
const KEY_MYSQL_SSL_VERIFY = 1014;
107126
/**#@-*/
108127

109128
/**

setup/src/Magento/Setup/Controller/DatabaseCheck.php

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
*/
66
namespace Magento\Setup\Controller;
77

8+
use Magento\Framework\Config\ConfigOptionsListConstants;
89
use Magento\Setup\Validator\DbValidator;
910
use Zend\Json\Json;
1011
use Zend\Mvc\Controller\AbstractActionController;
1112
use Zend\View\Model\JsonModel;
1213

14+
/**
15+
* Class DatabaseCheck
16+
*/
1317
class DatabaseCheck extends AbstractActionController
1418
{
1519
/**
@@ -37,12 +41,45 @@ public function indexAction()
3741
try {
3842
$params = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
3943
$password = isset($params['password']) ? $params['password'] : '';
40-
$this->dbValidator->checkDatabaseConnection($params['name'], $params['host'], $params['user'], $password);
44+
$driverOptions = [];
45+
if ($this->isDriverOptionsGiven($params)) {
46+
if (empty($params['driverOptionsSslVerify'])) {
47+
$params['driverOptionsSslVerify'] = 0;
48+
}
49+
$driverOptions = [
50+
ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => $params['driverOptionsSslKey'],
51+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => $params['driverOptionsSslCert'],
52+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => $params['driverOptionsSslCa'],
53+
ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => (int) $params['driverOptionsSslVerify'],
54+
];
55+
}
56+
$this->dbValidator->checkDatabaseConnectionWithDriverOptions(
57+
$params['name'],
58+
$params['host'],
59+
$params['user'],
60+
$password,
61+
$driverOptions
62+
);
4163
$tablePrefix = isset($params['tablePrefix']) ? $params['tablePrefix'] : '';
4264
$this->dbValidator->checkDatabaseTablePrefix($tablePrefix);
4365
return new JsonModel(['success' => true]);
4466
} catch (\Exception $e) {
4567
return new JsonModel(['success' => false, 'error' => $e->getMessage()]);
4668
}
4769
}
70+
71+
/**
72+
* Is Driver Options Given
73+
*
74+
* @param array $params
75+
* @return bool
76+
*/
77+
private function isDriverOptionsGiven($params)
78+
{
79+
return !(
80+
empty($params['driverOptionsSslKey']) ||
81+
empty($params['driverOptionsSslCert']) ||
82+
empty($params['driverOptionsSslCa'])
83+
);
84+
}
4885
}

setup/src/Magento/Setup/Model/ConfigGenerator.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
use Magento\Framework\Config\ConfigOptionsListConstants;
1515
use Magento\Framework\App\State;
1616
use Magento\Framework\Math\Random;
17+
use Magento\Setup\Model\ConfigOptionsList\DriverOptions;
1718

1819
/**
1920
* Creates deployment config data based on user input array
20-
* this class introduced to break down Magento\Setup\Model\ConfigOptionsList::createConfig
21+
*
22+
* This class introduced to break down {@see Magento\Setup\Model\ConfigOptionsList::createConfig}
2123
*/
2224
class ConfigGenerator
2325
{
@@ -61,28 +63,37 @@ class ConfigGenerator
6163
*/
6264
private $cryptKeyGenerator;
6365

66+
/**
67+
* @var DriverOptions
68+
*/
69+
private $driverOptions;
70+
6471
/**
6572
* Constructor
6673
*
6774
* @param Random $random Deprecated since 100.2.0
6875
* @param DeploymentConfig $deploymentConfig
6976
* @param ConfigDataFactory|null $configDataFactory
7077
* @param CryptKeyGeneratorInterface|null $cryptKeyGenerator
78+
* @param DriverOptions|null $driverOptions
7179
*/
7280
public function __construct(
7381
Random $random,
7482
DeploymentConfig $deploymentConfig,
7583
ConfigDataFactory $configDataFactory = null,
76-
CryptKeyGeneratorInterface $cryptKeyGenerator = null
84+
CryptKeyGeneratorInterface $cryptKeyGenerator = null,
85+
DriverOptions $driverOptions = null
7786
) {
7887
$this->random = $random;
7988
$this->deploymentConfig = $deploymentConfig;
8089
$this->configDataFactory = $configDataFactory ?? ObjectManager::getInstance()->get(ConfigDataFactory::class);
8190
$this->cryptKeyGenerator = $cryptKeyGenerator ?? ObjectManager::getInstance()->get(CryptKeyGenerator::class);
91+
$this->driverOptions = $driverOptions ?? ObjectManager::getInstance()->get(DriverOptions::class);
8292
}
8393

8494
/**
8595
* Creates encryption key config data
96+
*
8697
* @param array $data
8798
* @return ConfigData
8899
*/
@@ -179,6 +190,9 @@ public function createDbConfig(array $data)
179190
$configData->set($dbConnectionPrefix . ConfigOptionsListConstants::KEY_ACTIVE, '1');
180191
}
181192

193+
$driverOptions = $this->driverOptions->getDriverOptions($data);
194+
$configData->set($dbConnectionPrefix . ConfigOptionsListConstants::KEY_DRIVER_OPTIONS, $driverOptions);
195+
182196
return $configData;
183197
}
184198

setup/src/Magento/Setup/Model/ConfigOptionsList.php

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Magento\Framework\Setup\Option\FlagConfigOption;
1414
use Magento\Framework\Setup\Option\SelectConfigOption;
1515
use Magento\Framework\Setup\Option\TextConfigOption;
16+
use Magento\Setup\Model\ConfigOptionsList\DriverOptions;
1617
use Magento\Setup\Validator\DbValidator;
1718

1819
/**
@@ -54,17 +55,24 @@ class ConfigOptionsList implements ConfigOptionsListInterface
5455
\Magento\Setup\Model\ConfigOptionsList\Lock::class,
5556
];
5657

58+
/**
59+
* @var DriverOptions
60+
*/
61+
private $driverOptions;
62+
5763
/**
5864
* Constructor
5965
*
6066
* @param ConfigGenerator $configGenerator
6167
* @param DbValidator $dbValidator
6268
* @param KeyValidator|null $encryptionKeyValidator
69+
* @param DriverOptions|null $driverOptions
6370
*/
6471
public function __construct(
6572
ConfigGenerator $configGenerator,
6673
DbValidator $dbValidator,
67-
KeyValidator $encryptionKeyValidator = null
74+
KeyValidator $encryptionKeyValidator = null,
75+
DriverOptions $driverOptions = null
6876
) {
6977
$this->configGenerator = $configGenerator;
7078
$this->dbValidator = $dbValidator;
@@ -73,11 +81,11 @@ public function __construct(
7381
$this->configOptionsCollection[] = $objectManager->get($className);
7482
}
7583
$this->encryptionKeyValidator = $encryptionKeyValidator ?: $objectManager->get(KeyValidator::class);
84+
$this->driverOptions = $driverOptions ?? $objectManager->get(DriverOptions::class);
7685
}
7786

7887
/**
7988
* @inheritdoc
80-
*
8189
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
8290
*/
8391
public function getOptions()
@@ -164,6 +172,36 @@ public function getOptions()
164172
ConfigOptionsListConstants::CONFIG_PATH_CACHE_HOSTS,
165173
'http Cache hosts'
166174
),
175+
new TextConfigOption(
176+
ConfigOptionsListConstants::INPUT_KEY_DB_SSL_KEY,
177+
TextConfigOption::FRONTEND_WIZARD_TEXT,
178+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS .
179+
'/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY,
180+
'Full path of client key file in order to establish db connection through SSL',
181+
null
182+
),
183+
new TextConfigOption(
184+
ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CERT,
185+
TextConfigOption::FRONTEND_WIZARD_TEXT,
186+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS .
187+
'/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT,
188+
'Full path of client certificate file in order to establish db connection through SSL',
189+
null
190+
),
191+
new TextConfigOption(
192+
ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CA,
193+
TextConfigOption::FRONTEND_WIZARD_TEXT,
194+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS .
195+
'/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_CA,
196+
'Full path of server certificate file in order to establish db connection through SSL',
197+
null
198+
),
199+
new FlagConfigOption(
200+
ConfigOptionsListConstants::INPUT_KEY_DB_SSL_VERIFY,
201+
ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS .
202+
'/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY,
203+
'Verify server certification'
204+
),
167205
];
168206

169207
foreach ($this->configOptionsCollection as $configOptionsList) {
@@ -349,12 +387,14 @@ private function validateDbSettings(array $options, DeploymentConfig $deployment
349387
) {
350388
try {
351389
$options = $this->getDbSettings($options, $deploymentConfig);
390+
$driverOptions = $this->driverOptions->getDriverOptions($options);
352391

353-
$this->dbValidator->checkDatabaseConnection(
392+
$this->dbValidator->checkDatabaseConnectionWithDriverOptions(
354393
$options[ConfigOptionsListConstants::INPUT_KEY_DB_NAME],
355394
$options[ConfigOptionsListConstants::INPUT_KEY_DB_HOST],
356395
$options[ConfigOptionsListConstants::INPUT_KEY_DB_USER],
357-
$options[ConfigOptionsListConstants::INPUT_KEY_DB_PASSWORD]
396+
$options[ConfigOptionsListConstants::INPUT_KEY_DB_PASSWORD],
397+
$driverOptions
358398
);
359399
} catch (\Exception $exception) {
360400
$errors[] = $exception->getMessage();
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Setup\Model\ConfigOptionsList;
9+
10+
use Magento\Framework\Config\ConfigOptionsListConstants;
11+
12+
/**
13+
* MySql driver options
14+
*/
15+
class DriverOptions
16+
{
17+
/**
18+
* Get driver options.
19+
*
20+
* @param array $options
21+
* @return array
22+
*/
23+
public function getDriverOptions(array $options): array
24+
{
25+
$driverOptionKeys = [
26+
ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_KEY,
27+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CERT,
28+
ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CA,
29+
];
30+
$booleanDriverOptionKeys = [
31+
ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_VERIFY,
32+
];
33+
$driverOptions = [];
34+
foreach ($driverOptionKeys as $configKey => $driverOptionKey) {
35+
if ($this->optionExists($options, $driverOptionKey)) {
36+
$driverOptions[$configKey] = $options[$driverOptionKey];
37+
}
38+
}
39+
foreach ($booleanDriverOptionKeys as $configKey => $driverOptionKey) {
40+
$driverOptions[$configKey] = $this->booleanValue($options, $driverOptionKey);
41+
}
42+
43+
return $driverOptions;
44+
}
45+
46+
/**
47+
* Check if provided option exists.
48+
*
49+
* @param array $options
50+
* @param string $driverOptionKey
51+
* @return bool
52+
*/
53+
private function optionExists(array $options, string $driverOptionKey): bool
54+
{
55+
return isset($options[$driverOptionKey])
56+
&& ($options[$driverOptionKey] === false || !empty($options[$driverOptionKey]));
57+
}
58+
59+
/**
60+
* Transforms checkbox flag value into boolean.
61+
*
62+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#value
63+
*
64+
* @param array $options
65+
* @param string $driverOptionKey
66+
* @return bool
67+
*/
68+
private function booleanValue(array $options, string $driverOptionKey): bool
69+
{
70+
return isset($options[$driverOptionKey]) && (bool)$options[$driverOptionKey];
71+
}
72+
}

0 commit comments

Comments
 (0)