mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-04-08 17:15:08 +02:00
If one enables to store roles in the database for the first time, migrate them
This prevents the admin from breaking Icinga Web with one checkbox.
This commit is contained in:
parent
287cfaa87d
commit
b786e0c314
@ -3,8 +3,13 @@
|
||||
|
||||
namespace Icinga\Controllers;
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use Icinga\Application\Version;
|
||||
use Icinga\Common\Database;
|
||||
use Icinga\Forms\Security\RoleForm;
|
||||
use Icinga\Model\Role;
|
||||
use Icinga\Util\StringHelper;
|
||||
use InvalidArgumentException;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Icinga;
|
||||
@ -23,12 +28,18 @@ use Icinga\Web\Controller;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Web\Widget;
|
||||
use ipl\Sql\Connection;
|
||||
use ipl\Sql\Insert;
|
||||
use ipl\Sql\Select;
|
||||
use ipl\Sql\Update;
|
||||
|
||||
/**
|
||||
* Application and module configuration
|
||||
*/
|
||||
class ConfigController extends Controller
|
||||
{
|
||||
use Database;
|
||||
|
||||
/**
|
||||
* Create and return the tabs to display when showing application configuration
|
||||
*/
|
||||
@ -99,13 +110,21 @@ class ConfigController extends Controller
|
||||
$form->setOnSuccess(function (GeneralConfigForm $form) {
|
||||
$config = Config::app();
|
||||
$useStrictCsp = (bool) $config->get('security', 'use_strict_csp', false);
|
||||
$storeRolesInDb = (bool) $config->get('global', 'store_roles_in_db', false);
|
||||
if ($form->onSuccess() === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$appConfigForm = $form->getSubForm('form_config_general_application');
|
||||
if ($appConfigForm && (bool) $appConfigForm->getValue('security_use_strict_csp') !== $useStrictCsp) {
|
||||
$this->getResponse()->setReloadWindow(true);
|
||||
|
||||
if ($appConfigForm) {
|
||||
if ((bool) $appConfigForm->getValue('security_use_strict_csp') !== $useStrictCsp) {
|
||||
$this->getResponse()->setReloadWindow(true);
|
||||
}
|
||||
|
||||
if (! $storeRolesInDb && $appConfigForm->getValue('global_store_roles_in_db')) {
|
||||
$this->migrateRolesToFreshDb();
|
||||
}
|
||||
}
|
||||
})->handleRequest();
|
||||
|
||||
@ -114,6 +133,106 @@ class ConfigController extends Controller
|
||||
$this->createApplicationTabs()->activate('general');
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate roles.ini to database if the latter contains no roles
|
||||
*/
|
||||
private function migrateRolesToFreshDb(): void
|
||||
{
|
||||
$roles = Config::app('roles');
|
||||
$now = (new DateTime())->getTimestamp() * 1000;
|
||||
|
||||
$this->getDb()->transaction(function (Connection $db) use ($roles, $now) {
|
||||
if (Role::on($db)->columns('id')->first()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($roles as $name => $role) {
|
||||
$db->prepexec(
|
||||
(new Insert())
|
||||
->into('icingaweb_role')
|
||||
->columns(['name', 'unrestricted', 'ctime'])
|
||||
->values([$name, $role->unrestricted ? 'y' : 'n', $now])
|
||||
);
|
||||
|
||||
$id = $db->lastInsertId();
|
||||
$permissions = StringHelper::trimSplit($role->permissions);
|
||||
$refusals = StringHelper::trimSplit($role->refusals);
|
||||
$permissionsAndRefusals = [];
|
||||
|
||||
foreach (StringHelper::trimSplit($role->users) as $user) {
|
||||
$db->prepexec(
|
||||
(new Insert())
|
||||
->into('icingaweb_role_user')
|
||||
->columns(['role_id', 'user_name'])
|
||||
->values([$id, $user])
|
||||
);
|
||||
}
|
||||
|
||||
foreach (StringHelper::trimSplit($role->groups) as $group) {
|
||||
$db->prepexec(
|
||||
(new Insert())
|
||||
->into('icingaweb_role_group')
|
||||
->columns(['role_id', 'group_name'])
|
||||
->values([$id, $group])
|
||||
);
|
||||
}
|
||||
|
||||
foreach ([$permissions, $refusals] as $permissionsOrRefusals) {
|
||||
foreach ($permissionsOrRefusals as $permissionOrRefusal) {
|
||||
$permissionsAndRefusals[$permissionOrRefusal] = ['allowed' => 'n', 'denied' => 'n'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
$permissionsAndRefusals[$permission]['allowed'] = 'y';
|
||||
}
|
||||
|
||||
foreach ($refusals as $refusal) {
|
||||
$permissionsAndRefusals[$refusal]['denied'] = 'y';
|
||||
}
|
||||
|
||||
foreach ($permissionsAndRefusals as $permission => $authz) {
|
||||
$db->prepexec(
|
||||
(new Insert())
|
||||
->into('icingaweb_role_permission')
|
||||
->columns(['role_id', 'permission', 'allowed', 'denied'])
|
||||
->values([$id, $permission, $authz['allowed'], $authz['denied']])
|
||||
);
|
||||
}
|
||||
|
||||
foreach (RoleForm::collectProvidedPrivileges()[1] as $restrictionList) {
|
||||
foreach ($restrictionList as $restriction => $_) {
|
||||
if (isset($role->$restriction)) {
|
||||
$db->prepexec(
|
||||
(new Insert())
|
||||
->into('icingaweb_role_restriction')
|
||||
->columns(['role_id', 'restriction', 'filter'])
|
||||
->values([$id, $restriction, $role->$restriction])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($roles as $name => $role) {
|
||||
if (isset($role->parent)) {
|
||||
$db->prepexec(
|
||||
(new Update())
|
||||
->table('icingaweb_role')
|
||||
->set([
|
||||
'parent_id' => (new Select())
|
||||
->from('icingaweb_role')
|
||||
->where(['name = ?' => $role->parent])
|
||||
->columns(['id'])
|
||||
,
|
||||
])
|
||||
->where(['name = ?' => $name])
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the list of all modules
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user