Enforce database as configuration backend (#4135)

This commit is contained in:
sukhwinder33445 2021-02-18 12:31:21 +01:00 committed by GitHub
parent 91d4669dcb
commit ab97b6fdf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 151 additions and 45 deletions

View File

@ -61,9 +61,9 @@ class AccountController extends Controller
$form = new PreferenceForm();
$form->setPreferences($user->getPreferences());
if ($config->get('config_backend', 'ini') !== 'none') {
if ($config->get('config_backend', 'db') !== 'none') {
$form->setStore(PreferencesStore::create(new ConfigObject(array(
'store' => $config->get('config_backend', 'ini'),
'store' => $config->get('config_backend', 'db'),
'resource' => $config->config_resource
)), $user));
}

View File

@ -70,22 +70,35 @@ class ApplicationConfigForm extends Form
)
);
$this->addElement(
'select',
'global_config_backend',
array(
'required' => true,
'autosubmit' => true,
'label' => $this->translate('User Preference Storage Type'),
'multiOptions' => array(
'ini' => $this->translate('File System (INI Files)'),
'db' => $this->translate('Database'),
'none' => $this->translate('Don\'t Store Preferences')
)
)
);
// we do not need this form for setup because we set the database there as default.
// this form is only displayed in configuration -> application if preferences backend type of ini is recognized
if (isset($formData['global_config_backend']) && $formData['global_config_backend'] === 'ini') {
$this->addElement(
'select',
'global_config_backend',
[
'required' => true,
'autosubmit' => true,
'label' => $this->translate('User Preference Storage Type'),
'multiOptions' => [
'ini' => $this->translate('File System (INI Files)'),
'db' => $this->translate('Database')
]
]
);
} else {
$this->addElement(
'hidden',
'global_config_backend',
[
'required' => true,
'value' => 'db',
'disabled' => true
]
);
}
if (isset($formData['global_config_backend']) && $formData['global_config_backend'] === 'db') {
if (! isset($formData['global_config_backend']) || $formData['global_config_backend'] === 'db') {
$backends = array();
foreach (ResourceFactory::getResourceConfigs()->toArray() as $name => $resource) {
if ($resource['type'] === 'db') {
@ -98,8 +111,13 @@ class ApplicationConfigForm extends Form
'global_config_resource',
array(
'required' => true,
'multiOptions' => $backends,
'label' => $this->translate('Database Connection')
'multiOptions' => array_merge(
['' => sprintf(' - %s - ', $this->translate('Please choose'))],
$backends
),
'disable' => [''],
'value' => '',
'label' => $this->translate('Configuration Database')
)
);
}

View File

@ -37,4 +37,13 @@ class GeneralConfigForm extends ConfigForm
$this->addSubForm($themingConfigForm->create($formData));
$this->addSubForm($domainConfigForm->create($formData));
}
public function onRequest()
{
parent::onRequest();
if ($this->config->getConfigObject()->global->config_backend === 'ini') {
$this->warning('The preferences backend of type INI is deprecated and will be removed with version 2.10');
}
}
}

View File

@ -111,9 +111,9 @@ class Auth
);
$config = new Config();
}
if ($config->get('global', 'config_backend', 'ini') !== 'none') {
if ($config->get('global', 'config_backend', 'db') !== 'none') {
$preferencesConfig = new ConfigObject(array(
'store' => $config->get('global', 'config_backend', 'ini'),
'store' => $config->get('global', 'config_backend', 'db'),
'resource' => $config->get('global', 'config_resource')
));
try {

View File

@ -0,0 +1,29 @@
<?php
/* Icinga Web 2 | (c) 2020 Icinga GmbH | GPLv2+ */
namespace Icinga\Common;
use Icinga\Application\Config as IcingaConfig;
use Icinga\Data\ResourceFactory;
use ipl\Sql\Config as SqlConfig;
use ipl\Sql\Connection;
use PDO;
trait Database
{
protected function getDb()
{
$config = new SqlConfig(ResourceFactory::getResourceConfig(
IcingaConfig::app()->get('global', 'config_resource')
));
$config->options = [
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET SESSION SQL_MODE='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE"
. ",ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'"
];
$conn = new Connection($config);
return $conn;
}
}

View File

@ -4,6 +4,7 @@
namespace Icinga\User\Preferences;
use Icinga\Application\Config;
use Icinga\Application\Logger;
use Icinga\User;
use Icinga\User\Preferences;
use Icinga\Data\ConfigObject;
@ -116,7 +117,7 @@ abstract class PreferencesStore
*/
public static function create(ConfigObject $config, User $user)
{
$type = ucfirst(strtolower($config->get('store', 'ini')));
$type = ucfirst(strtolower($config->get('store', 'db')));
$storeClass = 'Icinga\\User\\Preferences\\Store\\' . $type . 'Store';
if (!class_exists($storeClass)) {
throw new ConfigurationError(
@ -126,6 +127,7 @@ abstract class PreferencesStore
}
if ($type === 'Ini') {
Logger::warning('The preferences backend of type INI is deprecated and will be removed with version 2.10');
$config->location = Config::resolvePath('preferences');
} elseif ($type === 'Db') {
$config->connection = new DbConnection(ResourceFactory::getResourceConfig($config->resource));

View File

@ -0,0 +1,34 @@
<?php
/* Icinga Web 2 | (c) 2020 Icinga GmbH | GPLv2+ */
namespace Icinga\Module\Setup\Requirement;
use Icinga\Module\Setup\Requirement;
/**
* Add requirement field
*
* @package Icinga\Module\Setup\Requirement
*/
class SetRequirement extends Requirement
{
protected function evaluate()
{
$condition = $this->getCondition();
if ($condition->getState()) {
$this->setStateText(sprintf(
mt('setup', '%s is available.'),
$this->getAlias() ?: $this->getTitle()
));
return true;
}
$this->setStateText(sprintf(
mt('setup', '%s is missing.'),
$this->getAlias() ?: $this->getTitle()
));
return false;
}
}

View File

@ -3,6 +3,7 @@
namespace Icinga\Module\Setup;
use Icinga\Module\Setup\Requirement\SetRequirement;
use PDOException;
use Icinga\Web\Form;
use Icinga\Web\Wizard;
@ -227,28 +228,13 @@ class WebWizard extends Wizard implements SetupWizard
unset($pageData['setup_usergroup_backend']);
}
}
} elseif ($page->getName() === 'setup_general_config') {
$authData = $this->getPageData('setup_authentication_type');
if ($authData['type'] === 'db') {
$page
->create($this->getRequestData($page, $request))
->getElement('global_config_backend')
->setValue('db');
$page->info(
mt(
'setup',
'Note that choosing "Database" as preference storage causes'
. ' Icinga Web 2 to use the same database as for authentication.'
),
false
);
}
} elseif ($page->getName() === 'setup_authentication_type' && $this->getDirection() === static::FORWARD) {
} elseif ($page->getName() === 'setup_authentication_type') {
$authData = $this->getPageData($page->getName());
$pageData = & $this->getPageData();
if ($authData !== null && $request->getPost('type') !== $authData['type']) {
// Drop any existing page data in case the authentication type has changed,
// otherwise it will conflict with other forms that depend on this one
$pageData = & $this->getPageData();
unset($pageData['setup_admin_account']);
unset($pageData['setup_authentication_backend']);
@ -259,6 +245,13 @@ class WebWizard extends Wizard implements SetupWizard
unset($pageData['setup_config_db_resource']);
unset($pageData['setup_config_db_creation']);
}
} elseif (isset($authData['type']) && $authData['type'] == 'external') {
// If you choose the authentication type external and validate the database and then come
// back to change the authentication type but do not change it, you will get an database configuration
// related error message on the next page. To avoid this error, the 'setup_config_db_resource'
// page must be unset.
unset($pageData['setup_config_db_resource']);
}
}
}
@ -295,18 +288,20 @@ class WebWizard extends Wizard implements SetupWizard
$skip = $backendConfig['backend'] !== 'ldap';
} elseif ($newPage->getName() === 'setup_config_db_resource') {
$authData = $this->getPageData('setup_authentication_type');
$configData = $this->getPageData('setup_general_config');
$skip = $authData['type'] === 'db' || $configData['global_config_backend'] !== 'db';
$skip = $authData['type'] === 'db';
} elseif (in_array($newPage->getName(), array('setup_auth_db_creation', 'setup_config_db_creation'))) {
if (($newPage->getName() === 'setup_auth_db_creation' || $this->hasPageData('setup_config_db_resource'))
&& (($config = $this->getPageData('setup_auth_db_resource')) !== null
|| ($config = $this->getPageData('setup_config_db_resource')) !== null)
&& !$config['skip_validation']
&& !$config['skip_validation'] && $this->getDirection() == static::FORWARD
) {
// Execute this code only if the direction is forward.
// Otherwise, an error will be output when you go back.
$db = new DbTool($config);
try {
$db->connectToDb(); // Are we able to login on the database?
if (array_search(reset($this->databaseTables), $db->listTables(), true) === false) {
// In case the database schema does not yet exist the
// user needs the privileges to setup the database
@ -651,6 +646,8 @@ class WebWizard extends Wizard implements SetupWizard
)
)));
$dbSet = new RequirementSet(false, RequirementSet::MODE_OR);
$mysqlSet = new RequirementSet(true);
$mysqlSet->add(new PhpModuleRequirement(array(
'optional' => true,
@ -680,7 +677,8 @@ class WebWizard extends Wizard implements SetupWizard
'setup.requirement.class'
)
)));
$set->merge($mysqlSet);
$dbSet->merge($mysqlSet);
$pgsqlSet = new RequirementSet(true);
$pgsqlSet->add(new PhpModuleRequirement(array(
@ -711,7 +709,23 @@ class WebWizard extends Wizard implements SetupWizard
'setup.requirement.class'
)
)));
$set->merge($pgsqlSet);
$dbSet->merge($pgsqlSet);
$set->merge($dbSet);
$dbRequire = (new SetRequirement(array(
'optional' => false,
'condition' => $dbSet,
'title' =>'Database',
'alias' => 'PDO-MySQL OR PDO-PostgreSQL',
'description' => mt(
'setup',
'A database is mandatory, therefore at least one module PDO-MySQL OR PDO-PostgreSQL for PHP
is required.'
)
)));
$set->add($dbRequire);
$set->add(new ConfigDirectoryRequirement(array(
'condition' => Icinga::app()->getConfigDir(),