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->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));
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
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(),
|
||||
|
|
Loading…
Reference in New Issue