Enforce database as configuration backend (#4135)
This commit is contained in:
parent
91d4669dcb
commit
ab97b6fdf0
|
@ -61,9 +61,9 @@ class AccountController extends Controller
|
||||||
|
|
||||||
$form = new PreferenceForm();
|
$form = new PreferenceForm();
|
||||||
$form->setPreferences($user->getPreferences());
|
$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(
|
$form->setStore(PreferencesStore::create(new ConfigObject(array(
|
||||||
'store' => $config->get('config_backend', 'ini'),
|
'store' => $config->get('config_backend', 'db'),
|
||||||
'resource' => $config->config_resource
|
'resource' => $config->config_resource
|
||||||
)), $user));
|
)), $user));
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,22 +70,35 @@ class ApplicationConfigForm extends Form
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 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(
|
$this->addElement(
|
||||||
'select',
|
'select',
|
||||||
'global_config_backend',
|
'global_config_backend',
|
||||||
array(
|
[
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'autosubmit' => true,
|
'autosubmit' => true,
|
||||||
'label' => $this->translate('User Preference Storage Type'),
|
'label' => $this->translate('User Preference Storage Type'),
|
||||||
'multiOptions' => array(
|
'multiOptions' => [
|
||||||
'ini' => $this->translate('File System (INI Files)'),
|
'ini' => $this->translate('File System (INI Files)'),
|
||||||
'db' => $this->translate('Database'),
|
'db' => $this->translate('Database')
|
||||||
'none' => $this->translate('Don\'t Store Preferences')
|
]
|
||||||
)
|
]
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
} 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();
|
$backends = array();
|
||||||
foreach (ResourceFactory::getResourceConfigs()->toArray() as $name => $resource) {
|
foreach (ResourceFactory::getResourceConfigs()->toArray() as $name => $resource) {
|
||||||
if ($resource['type'] === 'db') {
|
if ($resource['type'] === 'db') {
|
||||||
|
@ -98,8 +111,13 @@ class ApplicationConfigForm extends Form
|
||||||
'global_config_resource',
|
'global_config_resource',
|
||||||
array(
|
array(
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'multiOptions' => $backends,
|
'multiOptions' => array_merge(
|
||||||
'label' => $this->translate('Database Connection')
|
['' => sprintf(' - %s - ', $this->translate('Please choose'))],
|
||||||
|
$backends
|
||||||
|
),
|
||||||
|
'disable' => [''],
|
||||||
|
'value' => '',
|
||||||
|
'label' => $this->translate('Configuration Database')
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,4 +37,13 @@ class GeneralConfigForm extends ConfigForm
|
||||||
$this->addSubForm($themingConfigForm->create($formData));
|
$this->addSubForm($themingConfigForm->create($formData));
|
||||||
$this->addSubForm($domainConfigForm->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');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,9 +111,9 @@ class Auth
|
||||||
);
|
);
|
||||||
$config = new Config();
|
$config = new Config();
|
||||||
}
|
}
|
||||||
if ($config->get('global', 'config_backend', 'ini') !== 'none') {
|
if ($config->get('global', 'config_backend', 'db') !== 'none') {
|
||||||
$preferencesConfig = new ConfigObject(array(
|
$preferencesConfig = new ConfigObject(array(
|
||||||
'store' => $config->get('global', 'config_backend', 'ini'),
|
'store' => $config->get('global', 'config_backend', 'db'),
|
||||||
'resource' => $config->get('global', 'config_resource')
|
'resource' => $config->get('global', 'config_resource')
|
||||||
));
|
));
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
namespace Icinga\User\Preferences;
|
namespace Icinga\User\Preferences;
|
||||||
|
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
|
use Icinga\Application\Logger;
|
||||||
use Icinga\User;
|
use Icinga\User;
|
||||||
use Icinga\User\Preferences;
|
use Icinga\User\Preferences;
|
||||||
use Icinga\Data\ConfigObject;
|
use Icinga\Data\ConfigObject;
|
||||||
|
@ -116,7 +117,7 @@ abstract class PreferencesStore
|
||||||
*/
|
*/
|
||||||
public static function create(ConfigObject $config, User $user)
|
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';
|
$storeClass = 'Icinga\\User\\Preferences\\Store\\' . $type . 'Store';
|
||||||
if (!class_exists($storeClass)) {
|
if (!class_exists($storeClass)) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
|
@ -126,6 +127,7 @@ abstract class PreferencesStore
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type === 'Ini') {
|
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');
|
$config->location = Config::resolvePath('preferences');
|
||||||
} elseif ($type === 'Db') {
|
} elseif ($type === 'Db') {
|
||||||
$config->connection = new DbConnection(ResourceFactory::getResourceConfig($config->resource));
|
$config->connection = new DbConnection(ResourceFactory::getResourceConfig($config->resource));
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
namespace Icinga\Module\Setup;
|
namespace Icinga\Module\Setup;
|
||||||
|
|
||||||
|
use Icinga\Module\Setup\Requirement\SetRequirement;
|
||||||
use PDOException;
|
use PDOException;
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Web\Wizard;
|
use Icinga\Web\Wizard;
|
||||||
|
@ -227,28 +228,13 @@ class WebWizard extends Wizard implements SetupWizard
|
||||||
unset($pageData['setup_usergroup_backend']);
|
unset($pageData['setup_usergroup_backend']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif ($page->getName() === 'setup_general_config') {
|
} elseif ($page->getName() === 'setup_authentication_type') {
|
||||||
$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) {
|
|
||||||
$authData = $this->getPageData($page->getName());
|
$authData = $this->getPageData($page->getName());
|
||||||
|
$pageData = & $this->getPageData();
|
||||||
|
|
||||||
if ($authData !== null && $request->getPost('type') !== $authData['type']) {
|
if ($authData !== null && $request->getPost('type') !== $authData['type']) {
|
||||||
// Drop any existing page data in case the authentication type has changed,
|
// Drop any existing page data in case the authentication type has changed,
|
||||||
// otherwise it will conflict with other forms that depend on this one
|
// otherwise it will conflict with other forms that depend on this one
|
||||||
$pageData = & $this->getPageData();
|
|
||||||
unset($pageData['setup_admin_account']);
|
unset($pageData['setup_admin_account']);
|
||||||
unset($pageData['setup_authentication_backend']);
|
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_resource']);
|
||||||
unset($pageData['setup_config_db_creation']);
|
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';
|
$skip = $backendConfig['backend'] !== 'ldap';
|
||||||
} elseif ($newPage->getName() === 'setup_config_db_resource') {
|
} elseif ($newPage->getName() === 'setup_config_db_resource') {
|
||||||
$authData = $this->getPageData('setup_authentication_type');
|
$authData = $this->getPageData('setup_authentication_type');
|
||||||
$configData = $this->getPageData('setup_general_config');
|
$skip = $authData['type'] === 'db';
|
||||||
$skip = $authData['type'] === 'db' || $configData['global_config_backend'] !== 'db';
|
|
||||||
} elseif (in_array($newPage->getName(), array('setup_auth_db_creation', 'setup_config_db_creation'))) {
|
} 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'))
|
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_auth_db_resource')) !== null
|
||||||
|| ($config = $this->getPageData('setup_config_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);
|
$db = new DbTool($config);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$db->connectToDb(); // Are we able to login on the database?
|
$db->connectToDb(); // Are we able to login on the database?
|
||||||
|
|
||||||
if (array_search(reset($this->databaseTables), $db->listTables(), true) === false) {
|
if (array_search(reset($this->databaseTables), $db->listTables(), true) === false) {
|
||||||
// In case the database schema does not yet exist the
|
// In case the database schema does not yet exist the
|
||||||
// user needs the privileges to setup the database
|
// 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 = new RequirementSet(true);
|
||||||
$mysqlSet->add(new PhpModuleRequirement(array(
|
$mysqlSet->add(new PhpModuleRequirement(array(
|
||||||
'optional' => true,
|
'optional' => true,
|
||||||
|
@ -680,7 +677,8 @@ class WebWizard extends Wizard implements SetupWizard
|
||||||
'setup.requirement.class'
|
'setup.requirement.class'
|
||||||
)
|
)
|
||||||
)));
|
)));
|
||||||
$set->merge($mysqlSet);
|
|
||||||
|
$dbSet->merge($mysqlSet);
|
||||||
|
|
||||||
$pgsqlSet = new RequirementSet(true);
|
$pgsqlSet = new RequirementSet(true);
|
||||||
$pgsqlSet->add(new PhpModuleRequirement(array(
|
$pgsqlSet->add(new PhpModuleRequirement(array(
|
||||||
|
@ -711,7 +709,23 @@ class WebWizard extends Wizard implements SetupWizard
|
||||||
'setup.requirement.class'
|
'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(
|
$set->add(new ConfigDirectoryRequirement(array(
|
||||||
'condition' => Icinga::app()->getConfigDir(),
|
'condition' => Icinga::app()->getConfigDir(),
|
||||||
|
|
Loading…
Reference in New Issue