mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-04-08 17:15:08 +02:00
Merge branch 'bugfix/rebuild-form-builder-5525' into bugfix/commands-6593
Conflicts: library/Icinga/Web/Form.php modules/monitoring/application/forms/Config/SecurityForm.php
This commit is contained in:
commit
4ca1eaa7ce
application
controllers
forms
Authentication
Config
Dashboard
Install
Preference
views/scripts/config
library/Icinga
modules/monitoring
application
controllers
forms/Config
views/scripts/config
library/Monitoring/Web/Widget
public/css/icinga
@ -14,7 +14,6 @@ use Icinga\Exception\AuthenticationException;
|
||||
use Icinga\Exception\NotReadableError;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\User;
|
||||
use Icinga\Web\Session;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
/**
|
||||
@ -36,7 +35,6 @@ class AuthenticationController extends ActionController
|
||||
{
|
||||
$auth = $this->Auth();
|
||||
$this->view->form = $form = new LoginForm();
|
||||
$form->setRequest($this->_request);
|
||||
$this->view->title = $this->translate('Icingaweb Login');
|
||||
|
||||
try {
|
||||
@ -55,27 +53,17 @@ class AuthenticationController extends ActionController
|
||||
$config = Config::app('authentication');
|
||||
} catch (NotReadableError $e) {
|
||||
throw new ConfigurationError(
|
||||
$this->translate(
|
||||
'Could not read your authentiction.ini, no authentication methods are available.'
|
||||
)
|
||||
$this->translate('Could not read your authentiction.ini, no authentication methods are available.'),
|
||||
0,
|
||||
$e
|
||||
);
|
||||
}
|
||||
|
||||
$chain = new AuthChain($config);
|
||||
if ($this->getRequest()->isGet()) {
|
||||
$user = new User('');
|
||||
foreach ($chain as $backend) {
|
||||
if ($backend instanceof AutoLoginBackend) {
|
||||
$authenticated = $backend->authenticate($user);
|
||||
if ($authenticated === true) {
|
||||
$auth->setAuthenticated($user);
|
||||
$this->rerenderLayout()->redirectNow($redirectUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($form->isSubmittedAndValid()) {
|
||||
$user = new User($form->getValue('username'));
|
||||
$password = $form->getValue('password');
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost() && $this->view->form->isValid($request->getPost())) {
|
||||
$user = new User($this->view->form->getValue('username'));
|
||||
$password = $this->view->form->getValue('password');
|
||||
$backendsTried = 0;
|
||||
$backendsWithError = 0;
|
||||
|
||||
@ -121,14 +109,25 @@ class AuthenticationController extends ActionController
|
||||
);
|
||||
}
|
||||
if ($backendsWithError) {
|
||||
$form->addNote(
|
||||
$this->view->form->getElement('username')->addError(
|
||||
$this->translate(
|
||||
'Please note that not all authentication methods where available.'
|
||||
. ' Check the system log or Icinga Web 2 log for more information.'
|
||||
)
|
||||
);
|
||||
}
|
||||
$form->getElement('password')->addError($this->translate('Incorrect username or password'));
|
||||
$this->view->form->getElement('password')->addError($this->translate('Incorrect username or password'));
|
||||
} elseif ($request->isGet()) {
|
||||
$user = new User('');
|
||||
foreach ($chain as $backend) {
|
||||
if ($backend instanceof AutoLoginBackend) {
|
||||
$authenticated = $backend->authenticate($user);
|
||||
if ($authenticated === true) {
|
||||
$auth->setAuthenticated($user);
|
||||
$this->rerenderLayout()->redirectNow($redirectUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->view->errorInfo = $e->getMessage();
|
||||
|
@ -3,23 +3,22 @@
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
use Icinga\Web\Controller\BaseConfigController;
|
||||
use Icinga\Web\Widget\Tab;
|
||||
use Icinga\Web\Widget\AlertMessageBox;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Application\Modules\Module;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Widget;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Config as IcingaConfig;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Form\Config\GeneralForm;
|
||||
use Icinga\Form\Config\Authentication\ReorderForm;
|
||||
use Icinga\Form\Config\Authentication\LdapBackendForm;
|
||||
use Icinga\Form\Config\Authentication\DbBackendForm;
|
||||
use Icinga\Form\Config\Authentication\AutologinBackendForm;
|
||||
use Icinga\Form\Config\ResourceForm;
|
||||
use Icinga\Form\Config\LoggingForm;
|
||||
use Icinga\Form\Config\ConfirmRemovalForm;
|
||||
use Icinga\Config\PreservingIniWriter;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
|
||||
|
||||
/**
|
||||
@ -27,13 +26,6 @@ use Icinga\Config\PreservingIniWriter;
|
||||
*/
|
||||
class ConfigController extends BaseConfigController
|
||||
{
|
||||
/**
|
||||
* The resource types that are available.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $resourceTypes = array('livestatus', 'ido', 'statusdat', 'ldap');
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->view->tabs = Widget::create('tabs')->add('index', array(
|
||||
@ -45,9 +37,6 @@ class ConfigController extends BaseConfigController
|
||||
))->add('resources', array(
|
||||
'title' => 'Resources',
|
||||
'url' => 'config/resource'
|
||||
))->add('logging', array(
|
||||
'title' => 'Logging',
|
||||
'url' => 'config/logging'
|
||||
));
|
||||
}
|
||||
|
||||
@ -63,39 +52,20 @@ class ConfigController extends BaseConfigController
|
||||
{
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
$this->view->tabs->activate('index');
|
||||
|
||||
$form = new GeneralForm();
|
||||
$form->setConfiguration(IcingaConfig::app());
|
||||
$form->setRequest($this->_request);
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
if (!$this->writeConfigFile($form->getConfig(), 'config')) {
|
||||
return;
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost()) {
|
||||
if ($form->isValid($request->getPost())) {
|
||||
if ($this->writeConfigFile($form->getConfiguration(), 'config')) {
|
||||
Notification::success($this->translate('New configuration has successfully been stored'));
|
||||
$this->redirectNow('config');
|
||||
}
|
||||
}
|
||||
Notification::success('New configuration has successfully been stored');
|
||||
$form->setConfiguration(IcingaConfig::app(), true);
|
||||
$this->redirectNow('config/index');
|
||||
} else {
|
||||
$form->setConfiguration(IcingaConfig::app());
|
||||
}
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form for modifying the logging configuration
|
||||
*/
|
||||
public function loggingAction()
|
||||
{
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
$this->view->tabs->activate('logging');
|
||||
|
||||
$form = new LoggingForm();
|
||||
$form->setConfiguration(IcingaConfig::app());
|
||||
$form->setRequest($this->_request);
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
if (!$this->writeConfigFile($form->getConfig(), 'config')) {
|
||||
return;
|
||||
}
|
||||
Notification::success('New configuration has sucessfully been stored');
|
||||
$form->setConfiguration(IcingaConfig::app(), true);
|
||||
$this->redirectNow('config/logging');
|
||||
}
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
@ -172,40 +142,47 @@ class ConfigController extends BaseConfigController
|
||||
}
|
||||
|
||||
/**
|
||||
* Action for creating a new authentication backend
|
||||
* Action for reordering authentication backends
|
||||
*/
|
||||
public function authenticationAction()
|
||||
{
|
||||
$config = IcingaConfig::app('authentication', true);
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
$this->view->tabs->activate('authentication');
|
||||
|
||||
$order = array_keys($config->toArray());
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
|
||||
$backends = array();
|
||||
foreach ($order as $backend) {
|
||||
$form = new ReorderForm();
|
||||
$form->setName('form_reorder_backend_' . $backend);
|
||||
$form->setBackendName($backend);
|
||||
$form->setCurrentOrder($order);
|
||||
$form->setRequest($this->_request);
|
||||
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
if ($this->writeAuthenticationFile($form->getReorderedConfig($config))) {
|
||||
Notification::success('Authentication Order Updated');
|
||||
$this->redirectNow('config/authentication');
|
||||
$config = IcingaConfig::app('authentication');
|
||||
$backendOrder = array_keys($config->toArray());
|
||||
$form = new Form();
|
||||
$form->setName('form_reorder_authbackend');
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost()) {
|
||||
$requestData = $request->getPost();
|
||||
if ($form->isValid($requestData)) { // Validate the CSRF token
|
||||
$reordered = false;
|
||||
foreach ($backendOrder as $backendName) {
|
||||
if (isset($requestData[$backendName])) {
|
||||
array_splice($backendOrder, array_search($backendName, $backendOrder), 1);
|
||||
array_splice($backendOrder, $requestData[$backendName], 0, $backendName);
|
||||
$reordered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if ($reordered) {
|
||||
$reorderedConfig = array();
|
||||
foreach ($backendOrder as $backendName) {
|
||||
$reorderedConfig[$backendName] = $config->{$backendName};
|
||||
}
|
||||
|
||||
$backends[] = (object) array(
|
||||
'name' => $backend,
|
||||
'reorderForm' => $form
|
||||
);
|
||||
if ($this->writeAuthenticationFile($reorderedConfig)) {
|
||||
Notification::success($this->translate('Authentication order updated!'));
|
||||
$this->redirectNow('config/authentication');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->backends = $backends;
|
||||
$this->view->form = $form->create(); // Necessary in case its a GET request
|
||||
$this->view->backendNames = $backendOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -214,38 +191,56 @@ class ConfigController extends BaseConfigController
|
||||
public function createauthenticationbackendAction()
|
||||
{
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
$this->view->tabs->activate('authentication');
|
||||
|
||||
if ($this->getRequest()->getParam('type') === 'ldap') {
|
||||
$form = new LdapBackendForm();
|
||||
} else {
|
||||
$form = new DbBackendForm();
|
||||
}
|
||||
if ($this->getParam('auth_backend')) {
|
||||
$form->setBackendName($this->getParam('auth_backend'));
|
||||
}
|
||||
$form->setRequest($this->getRequest());
|
||||
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$backendCfg = IcingaConfig::app('authentication')->toArray();
|
||||
foreach ($backendCfg as $backendName => $settings) {
|
||||
unset($backendCfg[$backendName]['name']);
|
||||
$backendType = $this->getRequest()->getParam('type');
|
||||
$authenticationConfig = IcingaConfig::app('authentication')->toArray();
|
||||
try {
|
||||
switch ($backendType) {
|
||||
case 'ldap':
|
||||
$form = new LdapBackendForm();
|
||||
break;
|
||||
case 'db':
|
||||
$form = new DbBackendForm();
|
||||
break;
|
||||
case 'autologin':
|
||||
foreach ($authenticationConfig as $ac) {
|
||||
if (array_key_exists('backend', $ac) && $ac['backend'] === 'autologin') {
|
||||
throw new ConfigurationError(
|
||||
$this->translate('An autologin backend already exists')
|
||||
);
|
||||
}
|
||||
}
|
||||
$form = new AutologinBackendForm();
|
||||
break;
|
||||
default:
|
||||
$this->addErrorMessage(sprintf(
|
||||
$this->translate('There is no backend type `%s\''),
|
||||
$backendType
|
||||
));
|
||||
$this->redirectNow('config/configurationerror');
|
||||
}
|
||||
foreach ($form->getConfig() as $backendName => $settings) {
|
||||
unset($settings->{'name'});
|
||||
if (isset($backendCfg[$backendName])) {
|
||||
$this->addErrorMessage('Backend name already exists');
|
||||
$this->view->form = $form;
|
||||
$this->render('authentication/create');
|
||||
return;
|
||||
} catch (ConfigurationError $e) {
|
||||
$this->addErrorMessage($e->getMessage());
|
||||
$this->redirectNow('config/configurationerror');
|
||||
}
|
||||
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost() && $form->isValid($request->getPost())) {
|
||||
list($backendName, $backendConfig) = $form->getBackendConfig();
|
||||
if (isset($authenticationConfig[$backendName])) {
|
||||
$this->addErrorMessage(
|
||||
$this->translate('Backend name already exists')
|
||||
);
|
||||
} else {
|
||||
$authenticationConfig[$backendName] = $backendConfig;
|
||||
if ($this->writeConfigFile($authenticationConfig, 'authentication')) {
|
||||
$this->addSuccessMessage(
|
||||
$this->translate('Backend Modification Written.')
|
||||
);
|
||||
$this->redirectNow('config/authentication');
|
||||
}
|
||||
$backendCfg[$backendName] = $settings;
|
||||
}
|
||||
if ($this->writeAuthenticationFile($backendCfg)) {
|
||||
// redirect to overview with success message
|
||||
Notification::success('Backend Modification Written.');
|
||||
$this->redirectNow("config/authentication");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->view->messageBox->addForm($form);
|
||||
@ -266,18 +261,21 @@ class ConfigController extends BaseConfigController
|
||||
|
||||
$configArray = IcingaConfig::app('authentication', true)->toArray();
|
||||
$authBackend = $this->getParam('auth_backend');
|
||||
if (!isset($configArray[$authBackend])) {
|
||||
$this->addErrorMessage('Can\'t edit: Unknown Authentication Backend Provided');
|
||||
$this->configurationerrorAction();
|
||||
return;
|
||||
}
|
||||
if (!array_key_exists('resource', $configArray[$authBackend])) {
|
||||
$this->addErrorMessage('Configuration error: Backend "' . $authBackend . '" has no Resource');
|
||||
$this->configurationerrorAction();
|
||||
return;
|
||||
if (false === isset($configArray[$authBackend])) {
|
||||
$this->addErrorMessage(
|
||||
$this->translate('Can\'t edit: Unknown Authentication Backend Provided')
|
||||
);
|
||||
$this->redirectNow('config/configurationerror');
|
||||
}
|
||||
|
||||
$type = ResourceFactory::getResourceConfig($configArray[$authBackend]['resource'])->type;
|
||||
if (false === array_key_exists('backend', $configArray[$authBackend])) {
|
||||
$this->addErrorMessage(sprintf(
|
||||
$this->translate('Backend "%s" has no `backend\' setting'),
|
||||
$authBackend
|
||||
));
|
||||
$this->redirectNow('config/configurationerror');
|
||||
}
|
||||
$type = $configArray[$authBackend]['backend'];
|
||||
switch ($type) {
|
||||
case 'ldap':
|
||||
$form = new LdapBackendForm();
|
||||
@ -285,32 +283,37 @@ class ConfigController extends BaseConfigController
|
||||
case 'db':
|
||||
$form = new DbBackendForm();
|
||||
break;
|
||||
case 'autologin':
|
||||
$form = new AutologinBackendForm();
|
||||
break;
|
||||
default:
|
||||
$this->addErrorMessage('Can\'t edit: backend type "' . $type . '" of given resource not supported.');
|
||||
$this->configurationerrorAction();
|
||||
return;
|
||||
$this->addErrorMessage(sprintf(
|
||||
$this->translate('Can\'t edit: backend type "%s" of given resource not supported.'),
|
||||
$type
|
||||
));
|
||||
$this->redirectNow('config/configurationerror');
|
||||
}
|
||||
|
||||
$form->setBackendName($this->getParam('auth_backend'));
|
||||
$form->setBackend(IcingaConfig::app('authentication', true)->$authBackend);
|
||||
$form->setRequest($this->getRequest());
|
||||
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$backendCfg = IcingaConfig::app('authentication')->toArray();
|
||||
foreach ($form->getConfig() as $backendName => $settings) {
|
||||
$backendCfg[$backendName] = $settings;
|
||||
// Remove the old section if the backend is renamed
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost()) {
|
||||
if ($form->isValid($request->getPost())) {
|
||||
list($backendName, $backendConfig) = $form->getBackendConfig();
|
||||
$configArray[$backendName] = $backendConfig;
|
||||
if ($backendName != $authBackend) {
|
||||
unset($backendCfg[$authBackend]);
|
||||
unset($configArray[$authBackend]);
|
||||
}
|
||||
unset($settings['name']);
|
||||
if ($this->writeAuthenticationFile($configArray)) {
|
||||
// redirect to overview with success message
|
||||
Notification::success(sprintf(
|
||||
$this->translate('Backend "%s" saved'),
|
||||
$backendName
|
||||
));
|
||||
$this->redirectNow('config/authentication');
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ($this->writeAuthenticationFile($backendCfg)) {
|
||||
// redirect to overview with success message
|
||||
Notification::success('Backend "' . $authBackend . '" created');
|
||||
$this->redirectNow("config/authentication");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
$form->setBackendConfig($authBackend, $configArray[$authBackend]);
|
||||
}
|
||||
|
||||
$this->view->messageBox->addForm($form);
|
||||
@ -330,23 +333,25 @@ class ConfigController extends BaseConfigController
|
||||
|
||||
$configArray = IcingaConfig::app('authentication', true)->toArray();
|
||||
$authBackend = $this->getParam('auth_backend');
|
||||
if (!isset($configArray[$authBackend])) {
|
||||
Notification::error('Can\'t perform removal: Unknown Authentication Backend Provided');
|
||||
$this->render('authentication/remove');
|
||||
return;
|
||||
if (false === array_key_exists($authBackend, $configArray)) {
|
||||
$this->addErrorMessage(
|
||||
$this->translate('Can\'t perform removal: Unknown authentication backend provided')
|
||||
);
|
||||
$this->redirectNow('config/configurationerror');
|
||||
}
|
||||
|
||||
$form = new ConfirmRemovalForm();
|
||||
$form->setRequest($this->getRequest());
|
||||
$form->setRemoveTarget('auth_backend', $authBackend);
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
if ($request->isPost() && $form->isValid($request->getPost())) {
|
||||
unset($configArray[$authBackend]);
|
||||
if ($this->writeAuthenticationFile($configArray)) {
|
||||
Notification::success('Authentication Backend "' . $authBackend . '" Removed');
|
||||
$this->redirectNow("config/authentication");
|
||||
Notification::success(sprintf(
|
||||
$this->translate('Authentication Backend "%s" Removed'),
|
||||
$authBackend
|
||||
));
|
||||
$this->redirectNow('config/authentication');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
@ -354,116 +359,130 @@ class ConfigController extends BaseConfigController
|
||||
$this->render('authentication/remove');
|
||||
}
|
||||
|
||||
public function resourceAction($showOnly = false)
|
||||
/**
|
||||
* Display all available resources and a link to create a new one
|
||||
*/
|
||||
public function resourceAction()
|
||||
{
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
$this->view->tabs->activate('resources');
|
||||
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
$this->view->resources = IcingaConfig::app('resources', true)->toArray();
|
||||
$this->render('resource');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a form to create a new resource
|
||||
*/
|
||||
public function createresourceAction()
|
||||
{
|
||||
$this->view->resourceTypes = $this->resourceTypes;
|
||||
$resources = IcingaConfig::app('resources', true);
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
|
||||
$form = new ResourceForm();
|
||||
$form->setRequest($this->_request);
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$name = $form->getName();
|
||||
if (isset($resources->{$name})) {
|
||||
$this->addErrorMessage('Resource name "' . $name .'" already in use.');
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost() && $form->isValid($request->getPost())) {
|
||||
list($name, $config) = $form->getResourceConfig();
|
||||
$resources = IcingaConfig::app('resources')->toArray();
|
||||
if (array_key_exists($name, $resources)) {
|
||||
$this->addErrorMessage(sprintf($this->translate('Resource name "%s" already in use.'), $name));
|
||||
} else {
|
||||
$resources->{$name} = $form->getConfig();
|
||||
$resources[$name] = $config;
|
||||
if ($this->writeConfigFile($resources, 'resources')) {
|
||||
$this->addSuccessMessage('Resource "' . $name . '" created.');
|
||||
$this->redirectNow("config/resource");
|
||||
$this->addSuccessMessage(sprintf($this->translate('Resource "%s" successfully created.'), $name));
|
||||
$this->redirectNow('config/resource');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
$this->view->messageBox->addForm($form);
|
||||
$this->view->form = $form;
|
||||
$this->view->messageBox->addForm($form);
|
||||
$this->render('resource/create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a form to edit a existing resource
|
||||
*/
|
||||
public function editresourceAction()
|
||||
{
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
|
||||
$resources = ResourceFactory::getResourceConfigs();
|
||||
$name = $this->getParam('resource');
|
||||
if ($resources->get($name) === null) {
|
||||
$this->addErrorMessage('Can\'t edit: Unknown Resource Provided');
|
||||
$this->render('resource/modify');
|
||||
return;
|
||||
}
|
||||
$form = new ResourceForm();
|
||||
if ($this->_request->isPost() === false) {
|
||||
$form->setOldName($name);
|
||||
$form->setName($name);
|
||||
}
|
||||
$form->setRequest($this->_request);
|
||||
$form->setResource($resources->get($name));
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$oldName = $form->getOldName();
|
||||
$name = $form->getName();
|
||||
if ($oldName !== $name) {
|
||||
unset($resources->{$oldName});
|
||||
}
|
||||
$resources->{$name} = $form->getConfig();
|
||||
if ($this->writeConfigFile($resources, 'resources')) {
|
||||
$this->addSuccessMessage('Resource "' . $name . '" edited.');
|
||||
$this->redirectNow("config/resource");
|
||||
}
|
||||
return;
|
||||
// Fetch the resource to be edited
|
||||
$resources = IcingaConfig::app('resources')->toArray();
|
||||
$name = $this->getParam('resource');
|
||||
if (false === array_key_exists($name, $resources)) {
|
||||
$this->addErrorMessage(sprintf($this->translate('Cannot edit "%s". Resource not found.'), $name));
|
||||
$this->redirectNow('config/configurationerror');
|
||||
}
|
||||
|
||||
$form = new ResourceForm();
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost()) {
|
||||
if ($form->isValid($request->getPost())) {
|
||||
list($newName, $config) = $form->getResourceConfig();
|
||||
|
||||
if ($newName !== $name) {
|
||||
// Resource name has changed
|
||||
unset($resources[$name]); // We can safely use unset as all values are part of the form
|
||||
}
|
||||
|
||||
$resources[$newName] = $config;
|
||||
if ($this->writeConfigFile($resources, 'resources')) {
|
||||
$this->addSuccessMessage(sprintf($this->translate('Resource "%s" successfully edited.'), $name));
|
||||
$this->redirectNow('config/resource');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$form->setResourceConfig($name, $resources[$name]);
|
||||
}
|
||||
|
||||
$this->view->messageBox->addForm($form);
|
||||
$this->view->form = $form;
|
||||
$this->view->name = $name;
|
||||
$this->view->messageBox->addForm($form);
|
||||
$this->render('resource/modify');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a confirmation form to remove a resource
|
||||
*/
|
||||
public function removeresourceAction()
|
||||
{
|
||||
$this->view->messageBox = new AlertMessageBox(true);
|
||||
|
||||
$resources = ResourceFactory::getResourceConfigs()->toArray();
|
||||
$name = $this->getParam('resource');
|
||||
if (!isset($resources[$name])) {
|
||||
$this->addSuccessMessage('Can\'t remove: Unknown resource provided');
|
||||
$this->render('resource/remove');
|
||||
return;
|
||||
// Fetch the resource to be removed
|
||||
$resources = IcingaConfig::app('resources')->toArray();
|
||||
$name = $this->getParam('resource');
|
||||
if (false === array_key_exists($name, $resources)) {
|
||||
$this->addErrorMessage(sprintf($this->translate('Cannot remove "%s". Resource not found.'), $name));
|
||||
$this->redirectNow('config/configurationerror');
|
||||
}
|
||||
|
||||
// Check if selected resource is currently used for authentication
|
||||
$authConfig = IcingaConfig::app('authentication')->toArray();
|
||||
foreach ($authConfig as $backendName => $config) {
|
||||
if (array_key_exists('resource', $config) && $config['resource'] === $name) {
|
||||
$this->addWarningMessage(
|
||||
sprintf(
|
||||
$this->translate(
|
||||
'The resource "%s" is currently in use by the authentication backend "%s". ' .
|
||||
'Removing the resource can result in noone being able to log in any longer.'
|
||||
),
|
||||
$name,
|
||||
$backendName
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$form = new ConfirmRemovalForm();
|
||||
$form->setRequest($this->getRequest());
|
||||
$form->setRemoveTarget('resource', $name);
|
||||
|
||||
// Check if selected resource is currently used for authentication
|
||||
$authConfig = IcingaConfig::app('authentication', true)->toArray();
|
||||
foreach ($authConfig as $backendName => $config) {
|
||||
if (array_key_exists('resource', $config) && $config['resource'] === $name) {
|
||||
$this->addErrorMessage(
|
||||
'Warning: The resource "' . $name . '" is currently used for user authentication by "' . $backendName . '". ' .
|
||||
' Deleting it could eventally make login impossible.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost() && $form->isValid($request->getPost())) {
|
||||
unset($resources[$name]);
|
||||
if ($this->writeConfigFile($resources, 'resources')) {
|
||||
$this->addSuccessMessage('Resource "' . $name . '" removed.');
|
||||
$this->addSuccessMessage(sprintf($this->translate('Resource "%s" successfully removed.'), $name));
|
||||
$this->redirectNow('config/resource');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->view->name = $name;
|
||||
$this->view->form = $form;
|
||||
$this->view->messageBox->addForm($form);
|
||||
$this->render('resource/remove');
|
||||
}
|
||||
|
||||
|
@ -82,25 +82,29 @@ class DashboardController extends ActionController
|
||||
)->activate('addurl');
|
||||
|
||||
$form = new AddUrlForm();
|
||||
$form->setRequest($this->getRequest());
|
||||
$form->setAction(Url::fromRequest()->setParams(array())->getAbsoluteUrl());
|
||||
$this->view->form = $form;
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost()) {
|
||||
if ($form->isValid($request->getPost()) && $form->isSubmitted()) {
|
||||
$dashboard = $this->getDashboard();
|
||||
$dashboard->setComponentUrl(
|
||||
$form->getValue('pane'),
|
||||
$form->getValue('component'),
|
||||
ltrim($form->getValue('url'), '/')
|
||||
);
|
||||
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$dashboard = $this->getDashboard();
|
||||
$dashboard->setComponentUrl(
|
||||
$form->getValue('pane'),
|
||||
$form->getValue('component'),
|
||||
ltrim($form->getValue('url'), '/')
|
||||
);
|
||||
|
||||
$configFile = IcingaConfig::app('dashboard/dashboard')->getConfigFile();
|
||||
if ($this->writeConfiguration(new Zend_Config($dashboard->toArray()), $configFile)) {
|
||||
$this->redirectNow(Url::fromPath('dashboard', array('pane' => $form->getValue('pane'))));
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
$configFile = IcingaConfig::app('dashboard/dashboard')->getConfigFile();
|
||||
if ($this->writeConfiguration(new Zend_Config($dashboard->toArray()), $configFile)) {
|
||||
$this->redirectNow(Url::fromPath('dashboard', array('pane' => $form->getValue('pane'))));
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$form->create()->setDefault('url', htmlspecialchars_decode($request->getParam('url', '')));
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
use Icinga\Web\Controller\BasePreferenceController;
|
||||
use Icinga\Web\Widget\Tab;
|
||||
use Icinga\Application\Config as IcingaConfig;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Form\Preference\GeneralForm;
|
||||
use Icinga\Web\Notification;
|
||||
@ -38,23 +37,29 @@ class PreferenceController extends BasePreferenceController
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$form = new GeneralForm();
|
||||
$this->getTabs()->activate('general');
|
||||
$form->setConfiguration(IcingaConfig::app())
|
||||
->setRequest($this->getRequest());
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
try {
|
||||
$this->savePreferences($form->getPreferences());
|
||||
Notification::success(t('Preferences updated successfully'));
|
||||
// Recreate form to show new values
|
||||
// TODO(el): It must sufficient to call $form->populate(...)
|
||||
$form = new GeneralForm();
|
||||
$form->setConfiguration(IcingaConfig::app());
|
||||
$form->setRequest($this->getRequest());
|
||||
} catch (Exception $e) {
|
||||
Notification::error(sprintf(t('Failed to persist preferences. (%s)'), $e->getMessage()));
|
||||
|
||||
$form = new GeneralForm();
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost()) {
|
||||
if ($form->isValid($request->getPost())) {
|
||||
try {
|
||||
$this->savePreferences($form->getPreferences()->toArray());
|
||||
Notification::success($this->translate('Preferences updated successfully'));
|
||||
$this->redirectNow('preference');
|
||||
} catch (Exception $e) {
|
||||
Notification::error(
|
||||
sprintf(
|
||||
$this->translate('Failed to persist preferences. (%s)'),
|
||||
$e->getMessage()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$form->setPreferences($request->getUser()->getPreferences());
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
}
|
||||
}
|
||||
|
@ -13,36 +13,47 @@ use Icinga\Web\Url;
|
||||
class LoginForm extends Form
|
||||
{
|
||||
/**
|
||||
* Interface how the form should be created
|
||||
* Initialize this login form
|
||||
*/
|
||||
protected function create()
|
||||
public function init()
|
||||
{
|
||||
$url = Url::fromRequest()->without('renderLayout');
|
||||
|
||||
$this->setName('form_login');
|
||||
$this->addElement('text', 'username', array(
|
||||
'label' => t('Username'),
|
||||
'placeholder' => t('Please enter your username...'),
|
||||
'required' => true,
|
||||
));
|
||||
$redir = $this->addElement('hidden', 'redirect');
|
||||
$redirectUrl = $url->shift('redirect');
|
||||
if ($redirectUrl) {
|
||||
$this->setDefault('redirect', $redirectUrl);
|
||||
}
|
||||
$this->setSubmitLabel(t('Login'));
|
||||
}
|
||||
|
||||
$this->addElement('password', 'password', array(
|
||||
'label' => t('Password'),
|
||||
'placeholder' => t('...and your password'),
|
||||
'required' => true
|
||||
));
|
||||
// TODO: We need a place to intercept filled forms before rendering
|
||||
if ($this->getRequest()->getPost('username') !== null) {
|
||||
$this->getElement('password')->setAttrib('class', 'autofocus');
|
||||
} else {
|
||||
$this->getElement('username')->setAttrib('class', 'autofocus');
|
||||
}
|
||||
$this->setAction((string) $url);
|
||||
$this->setSubmitLabel('Login');
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements($formData)
|
||||
{
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'username',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Username'),
|
||||
'placeholder' => t('Please enter your username...'),
|
||||
'class' => false === isset($formData['username']) ? 'autofocus' : ''
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'password',
|
||||
'password',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Password'),
|
||||
'placeholder' => t('...and your password'),
|
||||
'class' => isset($formData['username']) ? 'autofocus' : ''
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'hidden',
|
||||
'redirect',
|
||||
array(
|
||||
'value' => Url::fromRequest()->getParam('redirect')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Form\Config\Authentication;
|
||||
|
||||
use Zend_Validate_Callback;
|
||||
|
||||
/**
|
||||
* Form class for adding/modifying autologin authentication backends
|
||||
*/
|
||||
class AutologinBackendForm extends BaseBackendForm
|
||||
{
|
||||
/**
|
||||
* Initialize this form
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('form_config_authentication_autologin');
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'name',
|
||||
array(
|
||||
'required' => true,
|
||||
'allowEmpty' => false,
|
||||
'label' => t('Backend Name'),
|
||||
'helptext' => t('The name of this authentication backend'),
|
||||
'validators' => array(
|
||||
array(
|
||||
'Regex',
|
||||
false,
|
||||
array(
|
||||
'pattern' => '/^[^\\[\\]:]+$/',
|
||||
'messages' => array(
|
||||
'regexNotMatch' => 'The backend name cannot contain \'[\', \']\' or \':\'.'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'strip_username_regexp',
|
||||
array(
|
||||
'required' => true,
|
||||
'allowEmpty' => false,
|
||||
'label' => t('Backend Domain Pattern'),
|
||||
'helptext' => t('The domain pattern of this authentication backend'),
|
||||
'value' => '/\@[^$]+$/',
|
||||
'validators' => array(
|
||||
new Zend_Validate_Callback(function ($value) {
|
||||
return @preg_match($value, '') !== false;
|
||||
})
|
||||
)
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'hidden',
|
||||
'backend',
|
||||
array(
|
||||
'required' => true,
|
||||
'value' => 'autologin'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the configuration state of this backend
|
||||
*
|
||||
* Returns just true as autologins are being handled externally by the webserver.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public function isValidAuthenticationBackend()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -4,11 +4,7 @@
|
||||
|
||||
namespace Icinga\Form\Config\Authentication;
|
||||
|
||||
use \Zend_Config;
|
||||
use \Zend_Form_Element_Checkbox;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Web\Form\Decorator\HelpText;
|
||||
|
||||
/**
|
||||
* Base form for authentication backend forms
|
||||
@ -16,149 +12,83 @@ use Icinga\Web\Form\Decorator\HelpText;
|
||||
abstract class BaseBackendForm extends Form
|
||||
{
|
||||
/**
|
||||
* The name of the backend currently displayed in this form
|
||||
* Return whether the given values are complete/valid and check whether it is possible to connect to the backend
|
||||
*
|
||||
* Will be the section in the authentication.ini file
|
||||
* If connection validation fails, a checkbox is prepended to the form to allow users to skip it.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $backendName = '';
|
||||
|
||||
/**
|
||||
* The backend configuration as a Zend_Config object
|
||||
* @param array $data The data to validate
|
||||
*
|
||||
* @var Zend_Config
|
||||
*/
|
||||
protected $backend;
|
||||
|
||||
/**
|
||||
* The resources to use instead of the factory provided ones (use for testing)
|
||||
*
|
||||
* @var Zend_Config
|
||||
*/
|
||||
protected $resources;
|
||||
|
||||
/**
|
||||
* Set the name of the currently displayed backend
|
||||
*
|
||||
* @param string $name The name to be stored as the section when persisting
|
||||
*/
|
||||
public function setBackendName($name)
|
||||
{
|
||||
$this->backendName = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the backend name of this form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBackendName()
|
||||
{
|
||||
return $this->backendName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the backend configuration or a empty Zend_Config object if none is given
|
||||
*
|
||||
* @return Zend_Config
|
||||
*/
|
||||
public function getBackend()
|
||||
{
|
||||
return ($this->backend !== null) ? $this->backend : new Zend_Config(array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the backend configuration for initial population
|
||||
*
|
||||
* @param Zend_Config $backend The backend to display in this form
|
||||
*/
|
||||
public function setBackend(Zend_Config $backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an alternative array of resources that should be used instead of the DBFactory resource set
|
||||
*
|
||||
* @param array $resources The resources to use for populating the db selection field
|
||||
*/
|
||||
public function setResources(array $resources)
|
||||
{
|
||||
$this->resources = $resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return content of the resources.ini or previously set resources
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResources()
|
||||
{
|
||||
if ($this->resources === null) {
|
||||
return ResourceFactory::getResourceConfigs()->toArray();
|
||||
} else {
|
||||
return $this->resources;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add checkbox at the beginning of the form which allows to skip logic connection validation
|
||||
*/
|
||||
protected function addForceCreationCheckbox()
|
||||
{
|
||||
$checkbox = new Zend_Form_Element_Checkbox(
|
||||
array(
|
||||
'name' => 'backend_force_creation',
|
||||
'label' => t('Force Changes'),
|
||||
'helptext' => t('Check this box to enforce changes without connectivity validation'),
|
||||
'order' => 0
|
||||
)
|
||||
);
|
||||
$checkbox->addDecorator(new HelpText());
|
||||
$this->addElement($checkbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate this form with the Zend validation mechanism and perform a logic validation of the connection.
|
||||
*
|
||||
* If logic validation fails, the 'backend_force_creation' checkbox is prepended to the form to allow users to
|
||||
* skip the logic connection validation.
|
||||
*
|
||||
* @param array $data The form input to validate
|
||||
*
|
||||
* @return bool Whether validation succeeded or not
|
||||
* @return bool Whether the validation succeeded or not
|
||||
*/
|
||||
public function isValid($data)
|
||||
{
|
||||
if (!parent::isValid($data)) {
|
||||
if (false === parent::isValid($data)) {
|
||||
return false;
|
||||
}
|
||||
if (isset($data['backend_force_creation']) && $data['backend_force_creation']) {
|
||||
return true;
|
||||
}
|
||||
if (!$this->isValidAuthenticationBackend()) {
|
||||
|
||||
if (
|
||||
(false === isset($data['force_creation']) || false === $data['force_creation'])
|
||||
&& false === $this->isValidAuthenticationBackend()
|
||||
) {
|
||||
$this->addForceCreationCheckbox();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array containing all sections defined by this form as the key and all settings
|
||||
* as an key-value sub-array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getConfig();
|
||||
|
||||
/**
|
||||
* Validate the configuration state of this backend with the concrete authentication backend.
|
||||
*
|
||||
* An implementation should not throw any exception, but use the add/setErrorMessages method of
|
||||
* Zend_Form. If the 'backend_force_creation' checkbox is set, this method won't be called.
|
||||
* An implementation should not throw any exception, but use the add/setErrorMessages method
|
||||
* of Zend_Form. If the 'force_creation' checkbox is set, this method won't be called.
|
||||
*
|
||||
* @return bool Whether validation succeeded or not
|
||||
*/
|
||||
abstract public function isValidAuthenticationBackend();
|
||||
|
||||
/**
|
||||
* Return the backend's configuration values and its name
|
||||
*
|
||||
* The first value is the name and the second one the values as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBackendConfig()
|
||||
{
|
||||
$values = $this->getValues();
|
||||
$name = $values['name'];
|
||||
unset($values['name']);
|
||||
return array($name, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the form with the given configuration values
|
||||
*
|
||||
* @param string $name The name of the backend
|
||||
* @param array $config The configuration values
|
||||
*/
|
||||
public function setBackendConfig($name, array $config)
|
||||
{
|
||||
$config['name'] = $name;
|
||||
$this->populate($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a checkbox to be displayed at the beginning of the form
|
||||
* which allows the user to skip the connection validation
|
||||
*/
|
||||
protected function addForceCreationCheckbox()
|
||||
{
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'force_creation',
|
||||
array(
|
||||
'order' => 0,
|
||||
'ignore' => true,
|
||||
'label' => t('Force Changes'),
|
||||
'helptext' => t('Check this box to enforce changes without connectivity validation')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,9 @@
|
||||
|
||||
namespace Icinga\Form\Config\Authentication;
|
||||
|
||||
use \Exception;
|
||||
use \Zend_Config;
|
||||
use Exception;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Authentication\DbConnection;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Authentication\Backend\DbUserBackend;
|
||||
|
||||
/**
|
||||
@ -16,89 +15,72 @@ use Icinga\Authentication\Backend\DbUserBackend;
|
||||
class DbBackendForm extends BaseBackendForm
|
||||
{
|
||||
/**
|
||||
* Return content of the resources.ini or previously set resources
|
||||
* The available database resources prepared to be used as select input data
|
||||
*
|
||||
* @return array
|
||||
* @var array
|
||||
*/
|
||||
public function getResources()
|
||||
protected $resources;
|
||||
|
||||
/**
|
||||
* Initialize this form
|
||||
*
|
||||
* Populates $this->resources.
|
||||
*
|
||||
* @throws ConfigurationError In case no database resources can be found
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if ($this->resources === null) {
|
||||
$res = ResourceFactory::getResourceConfigs('db')->toArray();
|
||||
$this->setName('form_config_authentication_db');
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
|
||||
foreach (array_keys($res) as $key) {
|
||||
$res[$key] = $key;
|
||||
}
|
||||
$dbResources = array_keys(
|
||||
ResourceFactory::getResourceConfigs('db')->toArray()
|
||||
);
|
||||
|
||||
return $res;
|
||||
} else {
|
||||
return $this->resources;
|
||||
if (empty($dbResources)) {
|
||||
throw new ConfigurationError(
|
||||
t('There are no database resources')
|
||||
);
|
||||
}
|
||||
|
||||
// array_combine() is necessary in order to use the array as select input data
|
||||
$this->resources = array_combine($dbResources, $dbResources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create this form and add all required elements
|
||||
*
|
||||
* @see Form::create()
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function create()
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$this->setName('form_modify_backend');
|
||||
$name = $this->filterName($this->getBackendName());
|
||||
$this->addElement(
|
||||
'text',
|
||||
'backend_' . $name . '_name',
|
||||
array(
|
||||
'required' => true,
|
||||
'allowEmpty' => false,
|
||||
'label' => t('Backend Name'),
|
||||
'helptext' => t('The name of this authentication provider'),
|
||||
'value' => $this->getBackendName()
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'name',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Backend Name'),
|
||||
'helptext' => t('The name of this authentication provider'),
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'select',
|
||||
'resource',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Database Connection'),
|
||||
'helptext' => t('The database connection to use for authenticating with this provider'),
|
||||
'multiOptions' => $this->resources
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'hidden',
|
||||
'backend',
|
||||
array(
|
||||
'required' => true,
|
||||
'value' => 'db'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'select',
|
||||
'backend_' . $name . '_resource',
|
||||
array(
|
||||
'required' => true,
|
||||
'allowEmpty' => false,
|
||||
'label' => t('Database Connection'),
|
||||
'helptext' => t('The database connection to use for authenticating with this provider'),
|
||||
'value' => $this->getBackend()->get('resource'),
|
||||
'multiOptions' => $this->getResources()
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'button',
|
||||
'btn_submit',
|
||||
array(
|
||||
'type' => 'submit',
|
||||
'value' => '1',
|
||||
'escape' => false,
|
||||
'class' => 'btn btn-cta btn-wide',
|
||||
'label' => '<i class="icinga-icon-save"></i> Save Backend'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the datatbase authentication backend configuration for this form
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @see BaseBackendForm::getConfig()
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
$prefix = 'backend_' . $this->filterName($this->getBackendName()) . '_';
|
||||
$section = $this->getValue($prefix . 'name');
|
||||
$cfg = array(
|
||||
'backend' => 'db',
|
||||
'resource' => $this->getValue($prefix . 'resource'),
|
||||
);
|
||||
|
||||
return array($section => $cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,23 +88,24 @@ class DbBackendForm extends BaseBackendForm
|
||||
*
|
||||
* @return bool Whether validation succeeded or not
|
||||
*
|
||||
* @see BaseBackendForm::isValidAuthenticationBackend
|
||||
* @see BaseBackendForm::isValidAuthenticationBackend()
|
||||
*/
|
||||
public function isValidAuthenticationBackend()
|
||||
{
|
||||
try {
|
||||
$testConnection = ResourceFactory::createResource(ResourceFactory::getResourceConfig(
|
||||
$this->getValue('backend_' . $this->filterName($this->getBackendName()) . '_resource')
|
||||
$this->getValue('resource')
|
||||
));
|
||||
$dbUserBackend = new DbUserBackend($testConnection);
|
||||
if ($dbUserBackend->count() < 1) {
|
||||
$this->addErrorMessage(t("No users found under the specified database backend"));
|
||||
$this->addErrorMessage(t('No users found under the specified database backend'));
|
||||
return false;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->addErrorMessage(sprintf(t('Using the specified backend failed: %s'), $e->getMessage()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,9 @@
|
||||
|
||||
namespace Icinga\Form\Config\Authentication;
|
||||
|
||||
use \Exception;
|
||||
use \Zend_Config;
|
||||
use Icinga\Web\Form;
|
||||
use Exception;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Authentication\Backend\LdapUserBackend;
|
||||
|
||||
/**
|
||||
@ -16,154 +15,122 @@ use Icinga\Authentication\Backend\LdapUserBackend;
|
||||
class LdapBackendForm extends BaseBackendForm
|
||||
{
|
||||
/**
|
||||
* Return content of the resources.ini or previously set resources
|
||||
* The available ldap resources prepared to be used as select input data
|
||||
*
|
||||
* @return array
|
||||
* @var array
|
||||
*/
|
||||
public function getResources()
|
||||
protected $resources;
|
||||
|
||||
/**
|
||||
* Initialize this form
|
||||
*
|
||||
* Populates $this->resources.
|
||||
*
|
||||
* @throws ConfigurationError In case no database resources can be found
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if ($this->resources === null) {
|
||||
$res = ResourceFactory::getResourceConfigs('ldap')->toArray();
|
||||
$this->setName('form_config_authentication_ldap');
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
|
||||
foreach (array_keys($res) as $key) {
|
||||
$res[$key] = $key;
|
||||
}
|
||||
$ldapResources = array_keys(
|
||||
ResourceFactory::getResourceConfigs('ldap')->toArray()
|
||||
);
|
||||
|
||||
return $res;
|
||||
} else {
|
||||
return $this->resources;
|
||||
if (empty($ldapResources)) {
|
||||
throw new ConfigurationError(
|
||||
t('There are no LDAP resources')
|
||||
);
|
||||
}
|
||||
|
||||
// array_combine() is necessary in order to use the array as select input data
|
||||
$this->resources = array_combine($ldapResources, $ldapResources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create this form and add all required elements
|
||||
*
|
||||
* @see Form::create()
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function create()
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$this->setName('form_modify_backend');
|
||||
$name = $this->filterName($this->getBackendName());
|
||||
$backend = $this->getBackend();
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'backend_' . $name . '_name',
|
||||
array(
|
||||
'required' => true,
|
||||
'allowEmpty' => false,
|
||||
'label' => t('Backend Name'),
|
||||
'helptext' => t('The name of this authentication backend'),
|
||||
'value' => $this->getBackendName()
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'select',
|
||||
'backend_' . $name . '_resource',
|
||||
array(
|
||||
'required' => true,
|
||||
'allowEmpty' => false,
|
||||
'label' => t('LDAP Resource'),
|
||||
'helptext' => t('The resource to use for authenticating with this provider'),
|
||||
'value' => $this->getBackend()->get('resource'),
|
||||
'multiOptions' => $this->getResources()
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'backend_' . $name . '_user_class',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('LDAP User Object Class'),
|
||||
'helptext' => t('The object class used for storing users on the ldap server'),
|
||||
'value' => $backend->get('user_class', 'inetOrgPerson')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'backend_' . $name . '_user_name_attribute',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('LDAP User Name Attribute'),
|
||||
'helptext' => t('The attribute name used for storing the user name on the ldap server'),
|
||||
'value' => $backend->get('user_name_attribute', 'uid')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'button',
|
||||
'btn_submit',
|
||||
array(
|
||||
'type' => 'submit',
|
||||
'value' => '1',
|
||||
'escape' => false,
|
||||
'class' => 'btn btn-cta btn-wide',
|
||||
'label' => '<i class="icinga-icon-save"></i> Save Backend'
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'name',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Backend Name'),
|
||||
'helptext' => t('The name of this authentication backend')
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'select',
|
||||
'resource',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('LDAP Resource'),
|
||||
'helptext' => t('The resource to use for authenticating with this provider'),
|
||||
'multiOptions' => $this->resources
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'user_class',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('LDAP User Object Class'),
|
||||
'helptext' => t('The object class used for storing users on the ldap server'),
|
||||
'value' => 'inetOrgPerson'
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'user_name_attribute',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('LDAP User Name Attribute'),
|
||||
'helptext' => t('The attribute name used for storing the user name on the ldap server'),
|
||||
'value' => 'uid'
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'hidden',
|
||||
'backend',
|
||||
array(
|
||||
'required' => true,
|
||||
'value' => 'ldap'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ldap authentication backend configuration for this form
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @see BaseBackendForm::getConfig()
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
$prefix = 'backend_' . $this->filterName($this->getBackendName()) . '_';
|
||||
$section = $this->getValue($prefix . 'name');
|
||||
$cfg = array(
|
||||
'backend' => 'ldap',
|
||||
'resource' => $this->getValue($prefix . 'resource'),
|
||||
'user_class' => $this->getValue($prefix . 'user_class'),
|
||||
'user_name_attribute' => $this->getValue($prefix . 'user_name_attribute')
|
||||
);
|
||||
return array($section => $cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the current configuration by creating a backend and requesting the user count
|
||||
* Validate the current configuration by connecting to a backend and requesting the user count
|
||||
*
|
||||
* @return bool Whether validation succeeded or not
|
||||
*
|
||||
* @see BaseBackendForm::isValidAuthenticationBacken
|
||||
* @see BaseBackendForm::isValidAuthenticationBacken()
|
||||
*/
|
||||
public function isValidAuthenticationBackend()
|
||||
{
|
||||
if (! ResourceFactory::ldapAvailable()) {
|
||||
/*
|
||||
* It should be possible to run icingaweb without the php ldap extension, when
|
||||
* no ldap backends are needed. When the user tries to create an ldap backend
|
||||
* without ldap installed we need to show him an error.
|
||||
*/
|
||||
if (false === ResourceFactory::ldapAvailable()) {
|
||||
// It should be possible to run icingaweb without the php ldap extension. When the user
|
||||
// tries to create an ldap backend without ldap being installed we display an error.
|
||||
$this->addErrorMessage(t('Using ldap is not possible, the php extension "ldap" is not installed.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$cfg = $this->getConfig();
|
||||
$backendName = 'backend_' . $this->filterName($this->getBackendName()) . '_name';
|
||||
$backendConfig = new Zend_Config($cfg[$this->getValue($backendName)]);
|
||||
$backend = ResourceFactory::createResource(ResourceFactory::getResourceConfig($backendConfig->resource));
|
||||
$backend = ResourceFactory::createResource(
|
||||
ResourceFactory::getResourceConfig($this->getValue('resource'))
|
||||
);
|
||||
$testConn = new LdapUserBackend(
|
||||
$backend,
|
||||
$backendConfig->user_class,
|
||||
$backendConfig->user_name_attribute
|
||||
$this->getValue('user_class'),
|
||||
$this->getValue('user_name_attribute')
|
||||
);
|
||||
$testConn->assertAuthenticationPossible();
|
||||
/*
|
||||
if ($testConn->count() === 0) {
|
||||
throw new Exception('No Users Found On Directory Server');
|
||||
}
|
||||
*/
|
||||
} catch (Exception $exc) {
|
||||
$this->addErrorMessage(
|
||||
t('Connection Validation Failed: ' . $exc->getMessage())
|
||||
);
|
||||
$this->addErrorMessage(sprintf(t('Connection validation failed: %s'), $exc->getMessage()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,233 +0,0 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Form\Config\Authentication;
|
||||
|
||||
use \Zend_Config;
|
||||
use Icinga\Web\Form;
|
||||
|
||||
/**
|
||||
* Form for modifying the authentication provider order
|
||||
*/
|
||||
class ReorderForm extends Form
|
||||
{
|
||||
/**
|
||||
* The name of the current backend which will get action buttons for up and down movement
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $backend;
|
||||
|
||||
/**
|
||||
* The current ordering of all backends, required to determine possible changes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $currentOrder = array();
|
||||
|
||||
/**
|
||||
* Set an array with the current order of all backends
|
||||
*
|
||||
* @param array $order An array containing backend names in the order
|
||||
* they are defined in the authentication.ini
|
||||
*/
|
||||
public function setCurrentOrder(array $order)
|
||||
{
|
||||
$this->currentOrder = $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the authentication backend for which to create the form
|
||||
*
|
||||
* @param string $backend The name of the authentication backend
|
||||
*/
|
||||
public function setBackendName($backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the currently set backend as it will appear in the form
|
||||
*
|
||||
* @return string The name of the backend
|
||||
*/
|
||||
public function getBackendName()
|
||||
{
|
||||
return $this->filterName($this->backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create this form
|
||||
*
|
||||
* @see Form::create
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if ($this->moveElementUp($this->backend, $this->currentOrder) !== $this->currentOrder) {
|
||||
$upForm = new Form();
|
||||
|
||||
$upForm->addElement(
|
||||
'hidden',
|
||||
'form_backend_order',
|
||||
array(
|
||||
'required' => true,
|
||||
'value' => join(',', $this->moveElementUp($this->backend, $this->currentOrder))
|
||||
)
|
||||
);
|
||||
$upForm->addElement(
|
||||
'button',
|
||||
'btn_' . $this->getBackendName() . '_reorder_up',
|
||||
array(
|
||||
'type' => 'submit',
|
||||
'escape' => false,
|
||||
'value' => 'btn_' . $this->getBackendName() . '_reorder_up',
|
||||
'name' => 'btn_' . $this->getBackendName() . '_reorder_up',
|
||||
'label' => $this->getView()->icon('up.png', t('Move up in authentication order'))
|
||||
)
|
||||
);
|
||||
|
||||
$this->addSubForm($upForm, 'btn_reorder_up');
|
||||
}
|
||||
|
||||
if ($this->moveElementDown($this->backend, $this->currentOrder) !== $this->currentOrder) {
|
||||
$downForm = new Form();
|
||||
|
||||
$downForm->addElement(
|
||||
'hidden',
|
||||
'form_backend_order',
|
||||
array(
|
||||
'required' => true,
|
||||
'value' => join(',', $this->moveElementDown($this->backend, $this->currentOrder))
|
||||
)
|
||||
);
|
||||
$downForm->addElement(
|
||||
'button',
|
||||
'btn_' . $this->getBackendName() . '_reorder_down',
|
||||
array(
|
||||
'type' => 'submit',
|
||||
'escape' => false,
|
||||
'value' => 'btn_' . $this->getBackendName() . '_reorder_down',
|
||||
'name' => 'btn_' . $this->getBackendName() . '_reorder_down',
|
||||
'label' => $this->getView()->icon('down.png', t('Move down in authentication order'))
|
||||
)
|
||||
);
|
||||
|
||||
$this->addSubForm($downForm, 'btn_reorder_down');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the flattened result of $this->getValues
|
||||
*
|
||||
* @return array The currently set values
|
||||
*
|
||||
* @see Form::getValues()
|
||||
*/
|
||||
protected function getFlattenedValues()
|
||||
{
|
||||
$result = array();
|
||||
foreach (parent::getValues() as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$result += $value;
|
||||
} else {
|
||||
$result[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether this form is submitted by testing the submit buttons of both subforms
|
||||
*
|
||||
* @return bool Whether the form has been submitted or not
|
||||
*/
|
||||
public function isSubmitted()
|
||||
{
|
||||
$checkData = $this->getRequest()->getParams();
|
||||
return isset($checkData['btn_' . $this->getBackendName() . '_reorder_up']) ||
|
||||
isset($checkData['btn_' . $this->getBackendName() . '_reorder_down']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the reordered configuration after a reorder button has been submitted
|
||||
*
|
||||
* @param Zend_Config $config The configuration to reorder
|
||||
*
|
||||
* @return array An array containing the reordered configuration
|
||||
*/
|
||||
public function getReorderedConfig(Zend_Config $config)
|
||||
{
|
||||
$originalConfig = $config->toArray();
|
||||
$newOrder = $this->getFlattenedValues();
|
||||
$order = explode(',', $newOrder['form_backend_order']);
|
||||
|
||||
$reordered = array();
|
||||
foreach ($order as $key) {
|
||||
if (isset($originalConfig[$key])) {
|
||||
$reordered[$key] = $originalConfig[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $reordered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static helper for moving an element in an array one slot up, if possible
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* <pre>
|
||||
* $array = array('first', 'second', 'third');
|
||||
* moveElementUp('third', $array); // returns ['first', 'third', 'second']
|
||||
* </pre>
|
||||
*
|
||||
* @param string $key The key to bubble up one slot
|
||||
* @param array $array The array to work with
|
||||
*
|
||||
* @return array The modified array
|
||||
*/
|
||||
protected static function moveElementUp($key, array $array)
|
||||
{
|
||||
for ($i = 0; $i < count($array) - 1; $i++) {
|
||||
if ($array[$i + 1] === $key) {
|
||||
$swap = $array[$i];
|
||||
$array[$i] = $array[$i + 1];
|
||||
$array[$i + 1] = $swap;
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static helper for moving an element in an array one slot down, if possible
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* <pre>
|
||||
* $array = array('first', 'second', 'third');
|
||||
* moveElementDown('first', $array); // returns ['second', 'first', 'third']
|
||||
* </pre>
|
||||
*
|
||||
* @param string $key The key to bubble up one slot
|
||||
* @param array $array The array to work with
|
||||
*
|
||||
* @return array The modified array
|
||||
*/
|
||||
protected static function moveElementDown($key, array $array)
|
||||
{
|
||||
for ($i = 0; $i < count($array) - 1; $i++) {
|
||||
if ($array[$i] === $key) {
|
||||
$swap = $array[$i + 1];
|
||||
$array[$i + 1] = $array[$i];
|
||||
$array[$i] = $swap;
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
@ -12,58 +12,11 @@ use Icinga\Web\Form;
|
||||
class ConfirmRemovalForm extends Form
|
||||
{
|
||||
/**
|
||||
* The value of the target to remove
|
||||
*
|
||||
* @var string
|
||||
* Initalize this form
|
||||
*/
|
||||
private $removeTarget;
|
||||
|
||||
/**
|
||||
* The name of the target parameter to remove
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $targetName;
|
||||
|
||||
/**
|
||||
* Set the remove target in this field to be a hidden field with $name and value $target
|
||||
*
|
||||
* @param string $name The name to be set in the hidden field
|
||||
* @param string $target The value to be set in the hidden field
|
||||
*/
|
||||
public function setRemoveTarget($name, $target)
|
||||
{
|
||||
$this->targetName = $name;
|
||||
$this->removeTarget = $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the confirmation form
|
||||
*
|
||||
* @see Form::create()
|
||||
*/
|
||||
public function create()
|
||||
public function init()
|
||||
{
|
||||
$this->setName('form_confirm_removal');
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
$this->targetName,
|
||||
array(
|
||||
'value' => $this->removeTarget,
|
||||
'required' => true
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'button',
|
||||
'btn_submit',
|
||||
array(
|
||||
'type' => 'submit',
|
||||
'escape' => false,
|
||||
'value' => '1',
|
||||
'class' => 'btn btn-cta btn-common',
|
||||
'label' => '<i class="icinga-icon-remove"></i> Confirm Removal'
|
||||
)
|
||||
);
|
||||
$this->setSubmitLabel(t('Confirm Removal'));
|
||||
}
|
||||
}
|
||||
|
@ -4,15 +4,13 @@
|
||||
|
||||
namespace Icinga\Form\Config;
|
||||
|
||||
use Icinga\Application\Config as IcingaConfig;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use DateTimeZone;
|
||||
use Zend_Config;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Util\Translator;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Web\Form\Validator\WritablePathValidator;
|
||||
use Icinga\Web\Form\Decorator\ConditionalHidden;
|
||||
use DateTimeZone;
|
||||
use Zend_Form_Element_Select;
|
||||
use Zend_Config;
|
||||
|
||||
/**
|
||||
* Configuration form for general, application-wide settings
|
||||
@ -20,251 +18,295 @@ use Zend_Config;
|
||||
class GeneralForm extends Form
|
||||
{
|
||||
/**
|
||||
* The base directory of the icingaweb configuration
|
||||
*
|
||||
* @var string
|
||||
* Initialize this configuration form
|
||||
*/
|
||||
private $configDir = null;
|
||||
|
||||
/**
|
||||
* The resources to use instead of the factory provided ones (use for testing)
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private $resources;
|
||||
|
||||
/**
|
||||
* Set a specific configuration directory to use for configuration specific default paths
|
||||
*
|
||||
* @param string $dir
|
||||
*/
|
||||
public function setConfigDir($dir)
|
||||
public function init()
|
||||
{
|
||||
$this->configDir = $dir;
|
||||
$this->setName('form_config_general');
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the config path set for this form or the application wide config path if none is set
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @see IcingaConfig::configDir
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function getConfigDir()
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
return $this->configDir === null ? IcingaConfig::$configDir : $this->configDir;
|
||||
$elements = array(
|
||||
$this->getLanguageSelection(),
|
||||
$this->getTimezoneSelection(),
|
||||
$this->getModulePathInput()
|
||||
);
|
||||
|
||||
return array_merge(
|
||||
$elements,
|
||||
$this->getPreferencesElements($formData),
|
||||
$this->getLoggingElements($formData)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an alternative array of resources that should be used instead of the DBFactory resource set
|
||||
* (used for testing)
|
||||
* Populate this form with the given configuration
|
||||
*
|
||||
* @param array $resources The resources to use for populating the db selection field
|
||||
*/
|
||||
public function setResources(array $resources)
|
||||
{
|
||||
$this->resources = $resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return content of the resources.ini or previously set resources for displaying in the database selection field
|
||||
* @param Zend_Config $config The configuration to populate this form with
|
||||
*
|
||||
* @return array
|
||||
* @return self
|
||||
*/
|
||||
public function getResources()
|
||||
public function setConfiguration(Zend_Config $config)
|
||||
{
|
||||
if ($this->resources === null) {
|
||||
return ResourceFactory::getResourceConfigs()->toArray();
|
||||
} else {
|
||||
return $this->resources;
|
||||
$defaults = array();
|
||||
foreach ($config as $section => $properties) {
|
||||
foreach ($properties as $name => $value) {
|
||||
$defaults[$section . '_' . $name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$this->populate($defaults);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a select field for setting the default language
|
||||
* Return the configured configuration values
|
||||
*
|
||||
* @return Zend_Config
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
$config = array();
|
||||
$values = $this->getValues();
|
||||
foreach ($values as $sectionAndPropertyName => $value) {
|
||||
list($section, $property) = explode('_', $sectionAndPropertyName);
|
||||
$config[$section][$property] = $value;
|
||||
}
|
||||
|
||||
return new Zend_Config($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a select field for setting the default language
|
||||
*
|
||||
* Possible values are determined by Translator::getAvailableLocaleCodes.
|
||||
*
|
||||
* @param Zend_Config $cfg The "global" section of the config.ini
|
||||
* @return Zend_Form_Element
|
||||
*/
|
||||
private function addLanguageSelection(Zend_Config $cfg)
|
||||
protected function getLanguageSelection()
|
||||
{
|
||||
$languages = array();
|
||||
foreach (Translator::getAvailableLocaleCodes() as $language) {
|
||||
$languages[$language] = $language;
|
||||
}
|
||||
|
||||
$this->addElement(
|
||||
return $this->createElement(
|
||||
'select',
|
||||
'language',
|
||||
'global_language',
|
||||
array(
|
||||
'label' => t('Default Language'),
|
||||
'required' => true,
|
||||
'multiOptions' => $languages,
|
||||
'helptext' => t(
|
||||
'Select the language to use by default. Can be overwritten by a user in his preferences.'
|
||||
),
|
||||
'value' => $cfg->get('language', Translator::DEFAULT_LOCALE)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a select field for setting the default timezone.
|
||||
* Return a select field for setting the default timezone
|
||||
*
|
||||
* Possible values are determined by DateTimeZone::listIdentifiers
|
||||
* Possible values are determined by DateTimeZone::listIdentifiers.
|
||||
*
|
||||
* @param Zend_Config $cfg The "global" section of the config.ini
|
||||
* @return Zend_Form_Element
|
||||
*/
|
||||
private function addTimezoneSelection(Zend_Config $cfg)
|
||||
protected function getTimezoneSelection()
|
||||
{
|
||||
$tzList = array();
|
||||
foreach (DateTimeZone::listIdentifiers() as $tz) {
|
||||
$tzList[$tz] = $tz;
|
||||
}
|
||||
$helptext = 'Select the timezone to be used as the default. User\'s can set their own timezone if'
|
||||
. ' they like to, but this is the timezone to be used as the default setting .';
|
||||
|
||||
$this->addElement(
|
||||
'select',
|
||||
'timezone',
|
||||
'global_timezone',
|
||||
array(
|
||||
'label' => 'Default Application Timezone',
|
||||
'required' => true,
|
||||
'multiOptions' => $tzList,
|
||||
'helptext' => $helptext,
|
||||
'value' => $cfg->get('timezone', date_default_timezone_get())
|
||||
'label' => t('Default Application Timezone'),
|
||||
'required' => true,
|
||||
'multiOptions' => $tzList,
|
||||
'helptext' => t(
|
||||
'Select the timezone to be used as the default. User\'s can set their own timezone if'
|
||||
. ' they like to, but this is the timezone to be used as the default setting .'
|
||||
),
|
||||
'value' => date_default_timezone_get()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add configuration settings for module paths
|
||||
*
|
||||
* @param Zend_Config $cfg The "global" section of the config.ini
|
||||
* Return a input field for setting the module path
|
||||
*/
|
||||
private function addModuleSettings(Zend_Config $cfg)
|
||||
protected function getModulePathInput()
|
||||
{
|
||||
$this->addElement(
|
||||
'text',
|
||||
'module_path',
|
||||
'global_modulePath',
|
||||
array(
|
||||
'label' => 'Module Path',
|
||||
'label' => t('Module Path'),
|
||||
'required' => true,
|
||||
'helptext' => 'Contains the directories that will be searched for available modules, separated by ' .
|
||||
' colons. Modules that don\'t exist in these directories can still be symlinked in the module ' .
|
||||
' folder, but won\'t show up in the list of disabled modules.',
|
||||
'value' => $cfg->get('modulePath', realpath(ICINGAWEB_APPDIR . '/../modules'))
|
||||
'helptext' => t(
|
||||
'Contains the directories that will be searched for available modules, separated by '
|
||||
. 'colons. Modules that don\'t exist in these directories can still be symlinked in '
|
||||
. 'the module folder, but won\'t show up in the list of disabled modules.'
|
||||
),
|
||||
'value' => realpath(ICINGAWEB_APPDIR . '/../modules')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add form elements for setting the user preference storage backend
|
||||
* Return form elements for setting the user preference storage backend
|
||||
*
|
||||
* @param Zend_Config $cfg The Zend_config object of preference section
|
||||
* @param array $formData The data sent by the user
|
||||
*/
|
||||
public function addUserPreferencesDialog(Zend_Config $cfg)
|
||||
protected function getPreferencesElements(array $formData)
|
||||
{
|
||||
$backend = $cfg->get('type', 'ini');
|
||||
if ($this->getRequest()->get('preferences_type', null) !== null) {
|
||||
$backend = $this->getRequest()->get('preferences_type');
|
||||
}
|
||||
$this->addElement(
|
||||
'select',
|
||||
'preferences_type',
|
||||
array(
|
||||
'label' => 'User Preference Storage Type',
|
||||
'required' => true,
|
||||
'value' => $backend,
|
||||
'multiOptions' => array(
|
||||
'ini' => 'File System (INI Files)',
|
||||
'db' => 'Database',
|
||||
'null' => 'Don\'t Store Preferences'
|
||||
$elements = array(
|
||||
$this->createElement(
|
||||
'select',
|
||||
'preferences_type',
|
||||
array(
|
||||
'required' => true,
|
||||
'class' => 'autosubmit',
|
||||
'label' => t('User Preference Storage Type'),
|
||||
'multiOptions' => array(
|
||||
'ini' => t('File System (INI Files)'),
|
||||
'db' => t('Database'),
|
||||
'null' => t('Don\'t Store Preferences')
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$backends = array();
|
||||
foreach ($this->getResources() as $name => $resource) {
|
||||
if ($resource['type'] !== 'db') {
|
||||
continue;
|
||||
if (isset($formData['preferences_type']) && $formData['preferences_type'] === 'db') {
|
||||
$backends = array();
|
||||
foreach (ResourceFactory::getResourceConfigs()->toArray() as $name => $resource) {
|
||||
if ($resource['type'] === 'db') {
|
||||
$backends[$name] = $name;
|
||||
}
|
||||
}
|
||||
$backends[$name] = $name;
|
||||
|
||||
$elements[] = $this->createElement(
|
||||
'select',
|
||||
'preferences_resource',
|
||||
array(
|
||||
'required' => true,
|
||||
'multiOptions' => $backends,
|
||||
'label' => t('Database Connection')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$txtPreferencesDbResource = new Zend_Form_Element_Select(
|
||||
array(
|
||||
'name' => 'preferences_db_resource',
|
||||
'label' => 'Database Connection',
|
||||
'required' => $backend === 'db',
|
||||
'condition' => $backend === 'db',
|
||||
'value' => $cfg->get('resource'),
|
||||
'multiOptions' => $backends
|
||||
)
|
||||
);
|
||||
$validator = new WritablePathValidator();
|
||||
$validator->setRequireExistence();
|
||||
$this->addElement($txtPreferencesDbResource);
|
||||
|
||||
$txtPreferencesDbResource->addDecorator(new ConditionalHidden());
|
||||
$this->enableAutoSubmit(
|
||||
array(
|
||||
'preferences_type'
|
||||
)
|
||||
);
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the general form, using the provided configuration
|
||||
* Return form elements to setup the application's logging
|
||||
*
|
||||
* @see Form::create()
|
||||
* @param array $formData The data sent by the user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function create()
|
||||
protected function getLoggingElements(array $formData)
|
||||
{
|
||||
$config = $this->getConfiguration();
|
||||
$global = $config->global;
|
||||
if ($global === null) {
|
||||
$global = new Zend_Config(array());
|
||||
}
|
||||
$preferences = $config->preferences;
|
||||
if ($preferences === null) {
|
||||
$preferences = new Zend_Config(array());
|
||||
}
|
||||
$this->setName('form_config_general');
|
||||
$this->addLanguageSelection($global);
|
||||
$this->addTimezoneSelection($global);
|
||||
$this->addModuleSettings($global);
|
||||
$this->addUserPreferencesDialog($preferences);
|
||||
$elements = array();
|
||||
|
||||
$this->setSubmitLabel('Save Changes');
|
||||
$elements[] = $this->createElement(
|
||||
'select',
|
||||
'logging_level',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Logging Level'),
|
||||
'helptext' => t('The maximum loglevel to emit.'),
|
||||
'multiOptions' => array(
|
||||
0 => t('None'),
|
||||
1 => t('Error'),
|
||||
2 => t('Warning'),
|
||||
3 => t('Information'),
|
||||
4 => t('Debug')
|
||||
)
|
||||
)
|
||||
);
|
||||
$elements[] = $this->createElement(
|
||||
'select',
|
||||
'logging_type',
|
||||
array(
|
||||
'required' => true,
|
||||
'class' => 'autosubmit',
|
||||
'label' => t('Logging Type'),
|
||||
'helptext' => t('The type of logging to utilize.'),
|
||||
'multiOptions' => array(
|
||||
'syslog' => 'Syslog',
|
||||
'file' => t('File')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (false === isset($formData['logging_type']) || $formData['logging_type'] === 'syslog') {
|
||||
$elements[] = $this->createElement(
|
||||
'text',
|
||||
'logging_application',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Application Prefix'),
|
||||
'helptext' => t('The name of the application by which to prefix syslog messages.'),
|
||||
'value' => 'icingaweb',
|
||||
'validators' => array(
|
||||
array(
|
||||
'Regex',
|
||||
false,
|
||||
array(
|
||||
'pattern' => '/^[^\W]+$/',
|
||||
'messages' => array(
|
||||
'regexNotMatch' => 'The application prefix cannot contain any whitespaces.'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$elements[] = $this->createElement(
|
||||
'select',
|
||||
'logging_facility',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Facility'),
|
||||
'helptext' => t('The Syslog facility to utilize.'),
|
||||
'multiOptions' => array(
|
||||
'LOG_USER' => 'LOG_USER'
|
||||
)
|
||||
)
|
||||
);
|
||||
} elseif ($formData['logging_type'] === 'file') {
|
||||
$elements[] = $this->createElement(
|
||||
'text',
|
||||
'logging_target',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'helptext' => t('The logfile to write messages to.'),
|
||||
'value' => $this->getDefaultLogDir(),
|
||||
'validators' => array(new WritablePathValidator())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an Zend_Config object containing the configuration set in this form
|
||||
* Return the default logging directory for type "file"
|
||||
*
|
||||
* @return Zend_Config
|
||||
* @return string
|
||||
*/
|
||||
public function getConfig()
|
||||
protected function getDefaultLogDir()
|
||||
{
|
||||
$config = $this->getConfiguration();
|
||||
if ($config->global === null) {
|
||||
$config->global = new Zend_Config(array(), true);
|
||||
}
|
||||
if ($config->preferences === null) {
|
||||
$config->preferences = new Zend_Config(array(), true);
|
||||
}
|
||||
|
||||
$values = $this->getValues();
|
||||
$cfg = clone $config;
|
||||
$cfg->global->language = $values['language'];
|
||||
$cfg->global->timezone = $values['timezone'];
|
||||
$cfg->global->modulePath = $values['module_path'];
|
||||
$cfg->preferences->type = $values['preferences_type'];
|
||||
if ($cfg->preferences->type === 'db') {
|
||||
$cfg->preferences->resource = $values['preferences_db_resource'];
|
||||
}
|
||||
|
||||
return $cfg;
|
||||
return realpath(Icinga::app()->getApplicationDir('../var/log/icingaweb.log'));
|
||||
}
|
||||
}
|
||||
|
@ -1,178 +0,0 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Form\Config;
|
||||
|
||||
use \Zend_Config;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Web\Form\Validator\WritablePathValidator;
|
||||
|
||||
/**
|
||||
* Form class for setting the application wide logging configuration
|
||||
*/
|
||||
class LoggingForm extends Form
|
||||
{
|
||||
/**
|
||||
* Return the default logging directory for type "file"
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultLogDir()
|
||||
{
|
||||
return realpath(Icinga::app()->getApplicationDir() . '/../var/log/icingaweb.log');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create this logging configuration form
|
||||
*
|
||||
* @see Form::create()
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->setName('form_config_logging');
|
||||
|
||||
$config = $this->getConfiguration();
|
||||
if (($loggingConfig = $config->logging) === null) {
|
||||
$loggingConfig = new Zend_Config(array());
|
||||
}
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'logging_enable',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Logging Enabled'),
|
||||
'helptext' => t('Check this to enable logging.'),
|
||||
'value' => $loggingConfig->enable ? 1 : 0
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'select',
|
||||
'logging_level',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Logging Level'),
|
||||
'helptext' => t('The maximum loglevel to emit.'),
|
||||
'value' => intval($loggingConfig->get('level', 0)),
|
||||
'multiOptions' => array(
|
||||
0 => t('Error'),
|
||||
1 => t('Warning'),
|
||||
2 => t('Information'),
|
||||
3 => t('Debug')
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'select',
|
||||
'logging_type',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Logging Type'),
|
||||
'helptext' => t('The type of logging to utilize.'),
|
||||
'value' => $loggingConfig->get('type', 'file'),
|
||||
'multiOptions' => array(
|
||||
'file' => t('File'),
|
||||
'syslog' => 'Syslog'
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->enableAutoSubmit(array('logging_type'));
|
||||
|
||||
switch ($this->getRequest()->getParam('logging_type', $loggingConfig->get('type', 'file')))
|
||||
{
|
||||
case 'syslog':
|
||||
$this->addElement(
|
||||
'text',
|
||||
'logging_application',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Application Prefix'),
|
||||
'helptext' => t('The name of the application by which to prefix syslog messages.'),
|
||||
'value' => $loggingConfig->get('application', 'icingaweb'),
|
||||
'validators' => array(
|
||||
array(
|
||||
'Regex',
|
||||
false,
|
||||
array(
|
||||
'pattern' => '/^[^\W]+$/',
|
||||
'messages' => array(
|
||||
'regexNotMatch' => 'The application prefix cannot contain any whitespaces.'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'select',
|
||||
'logging_facility',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Facility'),
|
||||
'helptext' => t('The Syslog facility to utilize.'),
|
||||
'value' => $loggingConfig->get('facility', 'LOG_USER'),
|
||||
'multiOptions' => array(
|
||||
'LOG_USER' => 'LOG_USER'
|
||||
)
|
||||
)
|
||||
);
|
||||
break;
|
||||
case 'file':
|
||||
default:
|
||||
$this->addElement(
|
||||
'text',
|
||||
'logging_target',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'helptext' => t('The logfile to write messages to.'),
|
||||
'value' => $loggingConfig->target ? $loggingConfig->target : $this->getDefaultLogDir(),
|
||||
'validators' => array(new WritablePathValidator())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->setSubmitLabel('{{SAVE_ICON}} Save Changes');
|
||||
}
|
||||
|
||||
public function isValid($data) {
|
||||
foreach ($this->getElements() as $key => $element) {
|
||||
// Initialize all empty elements with their default values.
|
||||
if (!isset($data[$key])) {
|
||||
$data[$key] = $element->getValue();
|
||||
}
|
||||
}
|
||||
return parent::isValid($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Zend_Config object containing the state defined in this form
|
||||
*
|
||||
* @return Zend_Config The config defined in this form
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
$values = $this->getValues();
|
||||
$cfg = $this->getConfiguration()->toArray();
|
||||
|
||||
$cfg['logging']['enable'] = $values['logging_enable'] == 1;
|
||||
$cfg['logging']['level'] = $values['logging_level'];
|
||||
|
||||
switch ($values['logging_type'])
|
||||
{
|
||||
case 'file':
|
||||
$cfg['logging']['type'] = 'file';
|
||||
$cfg['logging']['target'] = $values['logging_target'];
|
||||
break;
|
||||
case 'syslog':
|
||||
$cfg['logging']['type'] = 'syslog';
|
||||
$cfg['logging']['application'] = $values['logging_application'];
|
||||
$cfg['logging']['facility'] = $values['logging_facility'];
|
||||
break;
|
||||
}
|
||||
|
||||
return new Zend_Config($cfg);
|
||||
}
|
||||
}
|
@ -6,350 +6,47 @@ namespace Icinga\Form\Config;
|
||||
|
||||
use Exception;
|
||||
use Zend_Config;
|
||||
use Zend_Form_Element_Checkbox;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Web\Form\Element\Number;
|
||||
use Icinga\Web\Form\Decorator\HelpText;
|
||||
use Icinga\Web\Form\Decorator\ElementWrapper;
|
||||
|
||||
class ResourceForm extends Form
|
||||
{
|
||||
/**
|
||||
* The resource
|
||||
*
|
||||
* @var Zend_Config
|
||||
* Initialize this form
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* The (new) name of the resource
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* The old name of the resource
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $oldName;
|
||||
|
||||
/**
|
||||
* Set the current resource name
|
||||
*
|
||||
* @param string $name The name to set
|
||||
*/
|
||||
public function setName($name)
|
||||
public function init()
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->setName('form_config_resource');
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current resource name
|
||||
*
|
||||
* @return null|string
|
||||
* @see Form::createElemeents()
|
||||
*/
|
||||
public function getName()
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$name = $this->getValue('resource_all_name');
|
||||
if (!$name) {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the original name of the resource
|
||||
*
|
||||
* @param string $name The name to set
|
||||
*/
|
||||
public function setOldName($name)
|
||||
{
|
||||
$this->oldName = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource name that was initially set
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getOldName()
|
||||
{
|
||||
$oldName = $this->getValue('resource_all_name_old');
|
||||
if (!$oldName) {
|
||||
return $this->oldName;
|
||||
}
|
||||
|
||||
return $oldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the resource configuration to edit.
|
||||
*
|
||||
* @param Zend_Config $resource The config to set
|
||||
*/
|
||||
public function setResource(Zend_Config $resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current resource configuration.
|
||||
*
|
||||
* @return Zend_Config
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
if (!isset($this->resource)) {
|
||||
$this->resource = new Zend_Config(array('type' => 'db'));
|
||||
}
|
||||
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
protected function addDbForm()
|
||||
{
|
||||
$this->addElement(
|
||||
'select',
|
||||
'resource_db_db',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Database Type'),
|
||||
'helptext' => t('The type of SQL database you want to create.'),
|
||||
'value' => $this->getResource()->get('db', 'mysql'),
|
||||
'multiOptions' => array(
|
||||
'mysql' => 'MySQL',
|
||||
'pgsql' => 'PostgreSQL'
|
||||
//'oracle' => 'Oracle'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
$elements = array();
|
||||
$elements[] = $this->createElement(
|
||||
'text',
|
||||
'resource_db_host',
|
||||
array (
|
||||
'required' => true,
|
||||
'label' => t('Host'),
|
||||
'helptext' => t('The hostname of the database.'),
|
||||
'value' => $this->getResource()->get('host', 'localhost')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
new Number(
|
||||
array(
|
||||
'name' => 'resource_db_port',
|
||||
'required' => true,
|
||||
'label' => t('Port'),
|
||||
'helptext' => t('The port to use.'),
|
||||
'value' => $this->getResource()->get('port', 3306)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_db_dbname',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Database Name'),
|
||||
'helptext' => t('The name of the database to use'),
|
||||
'value' => $this->getResource()->get('dbname', '')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_db_username',
|
||||
array (
|
||||
'required' => true,
|
||||
'label' => t('Username'),
|
||||
'helptext' => t('The user name to use for authentication.'),
|
||||
'value' => $this->getResource()->get('username', '')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'password',
|
||||
'resource_db_password',
|
||||
array(
|
||||
'required' => true,
|
||||
'renderPassword' => true,
|
||||
'label' => t('Password'),
|
||||
'helptext' => t('The password to use for authentication'),
|
||||
'value' => $this->getResource()->get('password', '')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function addStatusdatForm()
|
||||
{
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_statusdat_status_file',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'helptext' => t('Location of your icinga status.dat file'),
|
||||
'value' => $this->getResource()->get('status_file', '/usr/local/icinga/var/status.dat')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_statusdat_object_file',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'helptext' => t('Location of your icinga objects.cache file'),
|
||||
'value' => $this->getResource()->get('status_file', '/usr/local/icinga/var/objects.cache')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function addLivestatusForm()
|
||||
{
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_livestatus_socket',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Socket'),
|
||||
'helptext' => t('The path to your livestatus socket used for querying monitoring data'),
|
||||
'value' => $this->getResource()->get('socket', '/usr/local/icinga/var/rw/livestatus')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function addLdapForm()
|
||||
{
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_ldap_hostname',
|
||||
array(
|
||||
'required' => true,
|
||||
'allowEmpty' => false,
|
||||
'label' => t('Host'),
|
||||
'helptext' => t('The hostname or address of the LDAP server to use for authentication'),
|
||||
'value' => $this->getResource()->get('hostname', 'localhost')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_ldap_root_dn',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Root DN'),
|
||||
'helptext' => t('The path where users can be found on the ldap server'),
|
||||
'value' => $this->getResource()->get('root_dn', 'ou=people,dc=icinga,dc=org')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_ldap_bind_dn',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Bind DN'),
|
||||
'helptext' => t('The user dn to use for querying the ldap server'),
|
||||
'value' => $this->getResource()->get('bind_dn', 'cn=admin,cn=config')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'password',
|
||||
'resource_ldap_bind_pw',
|
||||
array(
|
||||
'required' => true,
|
||||
'renderPassword' => true,
|
||||
'label' => t('Bind Password'),
|
||||
'helptext' => t('The password to use for querying the ldap server'),
|
||||
'value' => $this->getResource()->get('bind_pw', '')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function addFileForm()
|
||||
{
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_file_filename',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'helptext' => t('The filename to fetch information from'),
|
||||
'value' => $this->getResource()->get('filename', '')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_file_fields',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Pattern'),
|
||||
'helptext' => t('The regular expression by which to identify columns'),
|
||||
'value' => $this->getResource()->get('fields', '')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function addNameFields()
|
||||
{
|
||||
$this->addElement(
|
||||
'text',
|
||||
'resource_all_name',
|
||||
'name',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Resource Name'),
|
||||
'helptext' => t('The unique name of this resource'),
|
||||
'value' => $this->getName()
|
||||
'helptext' => t('The unique name of this resource')
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
'resource_all_name_old',
|
||||
array(
|
||||
'value' => $this->getOldName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add checkbox at the beginning of the form which allows to skip connection validation
|
||||
*/
|
||||
protected function addForceCreationCheckbox()
|
||||
{
|
||||
$checkbox = new Zend_Form_Element_Checkbox(
|
||||
array(
|
||||
'order' => 0,
|
||||
'name' => 'resource_force_creation',
|
||||
'label' => t('Force Changes'),
|
||||
'helptext' => t('Check this box to enforce changes without connectivity validation')
|
||||
)
|
||||
);
|
||||
$checkbox->addDecorator(new HelpText());
|
||||
$this->addElement($checkbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a select box for choosing the type to use for this backend
|
||||
*/
|
||||
protected function addTypeSelectionBox()
|
||||
{
|
||||
$this->addElement(
|
||||
$elements[] = $this->createElement(
|
||||
'select',
|
||||
'resource_type',
|
||||
'type',
|
||||
array(
|
||||
'required' => true,
|
||||
'class' => 'autosubmit',
|
||||
'label' => t('Resource Type'),
|
||||
'helptext' => t('The type of resource'),
|
||||
'value' => $this->getResource()->type,
|
||||
'multiOptions' => array(
|
||||
'db' => t('SQL Database'),
|
||||
'ldap' => 'LDAP',
|
||||
@ -359,60 +56,76 @@ class ResourceForm extends Form
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->enableAutoSubmit(array('resource_type'));
|
||||
|
||||
if (isset($formData['force_creation']) && $formData['force_creation']) {
|
||||
// In case the resource name already exists and the checkbox was displayed before
|
||||
$elements[] = $this->getForceCreationCheckbox();
|
||||
}
|
||||
|
||||
if (false === isset($formData['type']) || $formData['type'] === 'db') {
|
||||
return array_merge($elements, $this->getDbElements());
|
||||
} elseif ($formData['type'] === 'statusdat') {
|
||||
return array_merge($elements, $this->getStatusdatElements());
|
||||
} elseif ($formData['type'] === 'livestatus') {
|
||||
return array_merge($elements, $this->getLivestatusElements());
|
||||
} elseif ($formData['type'] === 'ldap') {
|
||||
return array_merge($elements, $this->getLdapElements());
|
||||
} elseif ($formData['type'] === 'file') {
|
||||
return array_merge($elements, $this->getFileElements());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate this form with the Zend validation mechanism and perform a validation of the connection
|
||||
* Return whether the given values are complete/valid and check whether it is possible to connect to the resource
|
||||
*
|
||||
* If validation fails, the 'resource_force_creation' checkbox is prepended to the form to allow users to
|
||||
* skip the connection validation
|
||||
* If connection validation fails, a checkbox is prepended to the form to allow users to skip it.
|
||||
*
|
||||
* @param array $data The form input to validate
|
||||
* @param array $data The data to validate
|
||||
*
|
||||
* @return bool True when validation succeeded, false if not
|
||||
* @return bool Whether the validation succeeded or not
|
||||
*/
|
||||
public function isValid($data)
|
||||
{
|
||||
if (!parent::isValid($data)) {
|
||||
if (false === parent::isValid($data)) {
|
||||
return false;
|
||||
}
|
||||
if (isset($data['resource_force_creation']) && $data['resource_force_creation']) {
|
||||
return true;
|
||||
}
|
||||
if (!$this->isValidResource()) {
|
||||
$this->addForceCreationCheckbox();
|
||||
|
||||
if (
|
||||
(false === isset($data['force_creation']) || false == $data['force_creation'])
|
||||
&& false === $this->isValidResource()
|
||||
) {
|
||||
$this->addElement($this->getForceCreationCheckbox());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the changed resource is a valid resource, by instantiating it and
|
||||
* checking if a connection is possible
|
||||
* Return whether a connection can be established with the current resource configuration values
|
||||
*
|
||||
* @return bool True when a connection to the resource is possible
|
||||
* @return bool Whether the connection validation was successful or not
|
||||
*/
|
||||
public function isValidResource()
|
||||
{
|
||||
$config = $this->getConfig();
|
||||
list($name, $config) = $this->getResourceConfig();
|
||||
|
||||
try {
|
||||
switch ($config->type) {
|
||||
switch ($config['type']) {
|
||||
case 'db':
|
||||
/*
|
||||
* It should be possible to run icingaweb without the pgsql or mysql extension or Zend-Pdo-Classes,
|
||||
* in case they aren't actually used. When the user tries to create a resource that depends on an
|
||||
* uninstalled extension, an error should be displayed.
|
||||
*/
|
||||
if ($config->db === 'mysql' && !ResourceFactory::mysqlAvailable()) {
|
||||
if ($config['db'] === 'mysql' && false === ResourceFactory::mysqlAvailable()) {
|
||||
$this->addErrorMessage(
|
||||
t('You need to install the php extension "mysql" and the ' .
|
||||
'Zend_Pdo_Mysql classes to use MySQL database resources.')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($config->db === 'pgsql' && !ResourceFactory::pgsqlAvailable()) {
|
||||
if ($config['db'] === 'pgsql' && false === ResourceFactory::pgsqlAvailable()) {
|
||||
$this->addErrorMessage(
|
||||
t('You need to install the php extension "pgsql" and the ' .
|
||||
'Zend_Pdo_Pgsql classes to use PostgreSQL database resources.')
|
||||
@ -420,30 +133,31 @@ class ResourceForm extends Form
|
||||
return false;
|
||||
}
|
||||
|
||||
$resource = ResourceFactory::createResource($config);
|
||||
$resource = ResourceFactory::createResource(new Zend_Config($config));
|
||||
$resource->getConnection()->getConnection();
|
||||
break;
|
||||
case 'statusdat':
|
||||
if (!file_exists($config->object_file) || !file_exists($config->status_file)) {
|
||||
if (
|
||||
false === file_exists($config['object_file'])
|
||||
|| false === file_exists($config['status_file'])
|
||||
) {
|
||||
$this->addErrorMessage(
|
||||
t('Connectivity validation failed, the provided file does not exist.')
|
||||
t('Connectivity validation failed. At least one of the provided files does not exist.')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'livestatus':
|
||||
$resource = ResourceFactory::createResource($config);
|
||||
$resource = ResourceFactory::createResource(new Zend_Config($config));
|
||||
$resource->connect()->disconnect();
|
||||
break;
|
||||
case 'ldap':
|
||||
$resource = ResourceFactory::createResource($config);
|
||||
$resource = ResourceFactory::createResource(new Zend_Config($config));
|
||||
$resource->connect();
|
||||
break;
|
||||
case 'file':
|
||||
if (!file_exists($config->filename)) {
|
||||
$this->addErrorMessage(
|
||||
t('Connectivity validation failed, the provided file does not exist.')
|
||||
);
|
||||
if (false === file_exists($config['filename'])) {
|
||||
$this->addErrorMessage(t('Connectivity validation failed. The provided file does not exist.'));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -456,51 +170,274 @@ class ResourceForm extends Form
|
||||
return true;
|
||||
}
|
||||
|
||||
public function create()
|
||||
/**
|
||||
* Return the resource configuration values and its name
|
||||
*
|
||||
* The first value is the name and the second one the values as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResourceConfig()
|
||||
{
|
||||
$this->addNameFields();
|
||||
$this->addTypeSelectionBox();
|
||||
|
||||
switch ($this->getRequest()->getParam('resource_type', $this->getResource()->type)) {
|
||||
case 'db':
|
||||
$this->addDbForm();
|
||||
break;
|
||||
case 'statusdat':
|
||||
$this->addStatusdatForm();
|
||||
break;
|
||||
case 'livestatus':
|
||||
$this->addLivestatusForm();
|
||||
break;
|
||||
case 'ldap':
|
||||
$this->addLdapForm();
|
||||
break;
|
||||
case 'file':
|
||||
$this->addFileForm();
|
||||
break;
|
||||
}
|
||||
|
||||
$this->setSubmitLabel('{{SAVE_ICON}} Save Changes');
|
||||
$values = $this->getValues();
|
||||
$name = $values['name'];
|
||||
unset($values['name']);
|
||||
return array($name, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a configuration containing the backend settings entered in this form
|
||||
* Populate the form with the given configuration values
|
||||
*
|
||||
* @return Zend_Config The updated configuration for this backend
|
||||
* @param string $name The name of the resource
|
||||
* @param array $config The configuration values
|
||||
*/
|
||||
public function getConfig()
|
||||
public function setResourceConfig($name, array $config)
|
||||
{
|
||||
$values = $this->getValues();
|
||||
$config['name'] = $name;
|
||||
$this->populate($config);
|
||||
}
|
||||
|
||||
$result = array('type' => $values['resource_type']);
|
||||
foreach ($values as $key => $value) {
|
||||
if ($key !== 'resource_type' && $key !== 'resource_all_name' && $key !== 'resource_all_name_old') {
|
||||
$configKey = explode('_', $key, 3);
|
||||
if (count($configKey) === 3) {
|
||||
$result[$configKey[2]] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return a checkbox to be displayed at the beginning of the form
|
||||
* which allows the user to skip the connection validation
|
||||
*
|
||||
* @return Zend_Form_Element
|
||||
*/
|
||||
protected function getForceCreationCheckbox()
|
||||
{
|
||||
return $this->createElement(
|
||||
'checkbox',
|
||||
'force_creation',
|
||||
array(
|
||||
'order' => 0,
|
||||
'ignore' => true,
|
||||
'label' => t('Force Changes'),
|
||||
'helptext' => t('Check this box to enforce changes without connectivity validation')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new Zend_Config($result);
|
||||
/**
|
||||
* Return all required elements to define a resource of type "db"
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDbElements()
|
||||
{
|
||||
return array(
|
||||
$this->createElement(
|
||||
'select',
|
||||
'db',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Database Type'),
|
||||
'helptext' => t('The type of SQL database'),
|
||||
'multiOptions' => array(
|
||||
'mysql' => 'MySQL',
|
||||
'pgsql' => 'PostgreSQL'
|
||||
//'oracle' => 'Oracle'
|
||||
)
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'host',
|
||||
array (
|
||||
'required' => true,
|
||||
'label' => t('Host'),
|
||||
'helptext' => t('The hostname of the database'),
|
||||
'value' => 'localhost'
|
||||
)
|
||||
),
|
||||
new Number(
|
||||
array(
|
||||
'required' => true,
|
||||
'name' => 'port',
|
||||
'label' => t('Port'),
|
||||
'helptext' => t('The port to use'),
|
||||
'value' => 3306,
|
||||
'decorators' => array( // The order is important!
|
||||
'ViewHelper',
|
||||
'Errors',
|
||||
new ElementWrapper(),
|
||||
new HelpText()
|
||||
)
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'dbname',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Database Name'),
|
||||
'helptext' => t('The name of the database to use')
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'username',
|
||||
array (
|
||||
'required' => true,
|
||||
'label' => t('Username'),
|
||||
'helptext' => t('The user name to use for authentication')
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'password',
|
||||
'password',
|
||||
array(
|
||||
'required' => true,
|
||||
'renderPassword' => true,
|
||||
'label' => t('Password'),
|
||||
'helptext' => t('The password to use for authentication')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all required elements to define a resource of type "statusdat"
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getStatusdatElements()
|
||||
{
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'status_file',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'helptext' => t('Location of your icinga status.dat file'),
|
||||
'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/status.dat')
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'object_file',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'helptext' => t('Location of your icinga objects.cache file'),
|
||||
'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/objects.cache')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all required elements to define a resource of type "livestatus"
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getLivestatusElements()
|
||||
{
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'socket',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Socket'),
|
||||
'helptext' => t('The path to your livestatus socket used for querying monitoring data'),
|
||||
'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/rw/livestatus')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all required elements to define a resource of type "ldap"
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getLdapElements()
|
||||
{
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'hostname',
|
||||
array(
|
||||
'required' => true,
|
||||
'allowEmpty' => false,
|
||||
'label' => t('Host'),
|
||||
'helptext' => t('The hostname or address of the LDAP server to use for authentication'),
|
||||
'value' => 'localhost'
|
||||
)
|
||||
),
|
||||
new Number(
|
||||
array(
|
||||
'required' => true,
|
||||
'name' => 'port',
|
||||
'label' => t('Port'),
|
||||
'helptext' => t('The port of the LDAP server to use for authentication'),
|
||||
'value' => 389,
|
||||
'decorators' => array( // The order is important!
|
||||
'ViewHelper',
|
||||
'Errors',
|
||||
new ElementWrapper(),
|
||||
new HelpText()
|
||||
)
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'root_dn',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Root DN'),
|
||||
'helptext' => t('The path where users can be found on the ldap server')
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'bind_dn',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Bind DN'),
|
||||
'helptext' => t('The user dn to use for querying the ldap server')
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'password',
|
||||
'bind_pw',
|
||||
array(
|
||||
'required' => true,
|
||||
'renderPassword' => true,
|
||||
'label' => t('Bind Password'),
|
||||
'helptext' => t('The password to use for querying the ldap server')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all required elements to define a resource of type "file"
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFileElements()
|
||||
{
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'filename',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'helptext' => t('The filename to fetch information from')
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'text',
|
||||
'fields',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Pattern'),
|
||||
'helptext' => t('The regular expression by which to identify columns')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,8 @@
|
||||
namespace Icinga\Form\Dashboard;
|
||||
|
||||
use Icinga\Application\Config as IcingaConfig;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Widget\Dashboard;
|
||||
use Zend_Form_Element_Text;
|
||||
use Zend_Form_Element_Submit;
|
||||
use Zend_Form_Element_Hidden;
|
||||
use Zend_Form_Element_Select;
|
||||
use Icinga\Web\Form;
|
||||
|
||||
/**
|
||||
* Form to add an url a dashboard pane
|
||||
@ -18,124 +14,106 @@ use Zend_Form_Element_Select;
|
||||
class AddUrlForm extends Form
|
||||
{
|
||||
/**
|
||||
* Add a selection box for different panes to the form
|
||||
*
|
||||
* @param Dashboard $dashboard The dashboard to retrieve the panes from
|
||||
* Initialize this form
|
||||
*/
|
||||
private function addPaneSelectionBox(Dashboard $dashboard)
|
||||
public function init()
|
||||
{
|
||||
$selectPane = new Zend_Form_Element_Select(
|
||||
'pane',
|
||||
array(
|
||||
'label' => 'Dashboard',
|
||||
'required' => true,
|
||||
'style' => 'display:inline-block;',
|
||||
|
||||
'multiOptions' => $dashboard->getPaneKeyTitleArray()
|
||||
)
|
||||
);
|
||||
|
||||
$newDashboardBtn = new Zend_Form_Element_Submit(
|
||||
'create_new_pane',
|
||||
array(
|
||||
'label' => 'Create A New Pane',
|
||||
'required' => false,
|
||||
'class' => 'btn btn-default',
|
||||
'style' => 'display:inline-block'
|
||||
)
|
||||
);
|
||||
|
||||
$newDashboardBtn->removeDecorator('DtDdWrapper');
|
||||
$selectPane->removeDecorator('DtDdWrapper');
|
||||
$selectPane->removeDecorator('htmlTag');
|
||||
|
||||
$this->addElement($selectPane);
|
||||
$this->addElement($newDashboardBtn);
|
||||
$this->enableAutoSubmit(array('create_new_pane'));
|
||||
$this->setName('form_dashboard_addurl');
|
||||
$this->setSubmitLabel(t('Add To Dashboard'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a textfield for creating a new pane to this form
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
private function addNewPaneTextField($showExistingButton = true)
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$txtCreatePane = new Zend_Form_Element_Text(
|
||||
'pane',
|
||||
array(
|
||||
'label' => 'New Dashboard Title',
|
||||
'required' => true,
|
||||
'style' => 'display:inline-block'
|
||||
$elements = array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'url',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Url'),
|
||||
'helptext' => t('The url being loaded in the dashlet')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Marks this field as a new pane (and prevents the checkbox being displayed when validation errors occur)
|
||||
$markAsNewPane = new Zend_Form_Element_Hidden(
|
||||
'create_new_pane',
|
||||
array(
|
||||
'required' => true,
|
||||
'value' => 1
|
||||
)
|
||||
);
|
||||
|
||||
$cancelDashboardBtn = new Zend_Form_Element_Submit(
|
||||
'use_existing_dashboard',
|
||||
array(
|
||||
'class' => 'btn',
|
||||
'escape' => false,
|
||||
'label' => 'Use An Existing Dashboard',
|
||||
'required' => false
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$cancelDashboardBtn->removeDecorator('DtDdWrapper');
|
||||
$txtCreatePane->removeDecorator('DtDdWrapper');
|
||||
$txtCreatePane->removeDecorator('htmlTag');
|
||||
|
||||
$this->addElement($txtCreatePane);
|
||||
if ($showExistingButton) {
|
||||
$this->addElement($cancelDashboardBtn);
|
||||
}
|
||||
$this->addElement($markAsNewPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add elements to this form (used by extending classes)
|
||||
*/
|
||||
protected function create()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$this->setName('form_dashboard_add');
|
||||
$dashboard->readConfig(IcingaConfig::app('dashboard/dashboard'));
|
||||
$this->addElement(
|
||||
'text',
|
||||
'url',
|
||||
array(
|
||||
'label' => 'Url',
|
||||
'required' => true,
|
||||
'value' => htmlspecialchars_decode($this->getRequest()->getParam('url', ''))
|
||||
)
|
||||
);
|
||||
$elems = $dashboard->getPaneKeyTitleArray();
|
||||
|
||||
if (empty($elems) || // show textfield instead of combobox when no pane is available
|
||||
($this->getRequest()->getPost('create_new_pane', '0') && // or when a new pane should be created (+ button)
|
||||
!$this->getRequest()->getPost('use_existing_dashboard', '0')) // and the user didn't click the 'use
|
||||
// existing' button
|
||||
$paneSelectionValues = $this->getDashboardPaneSelectionValues();
|
||||
if (empty($paneSelectionValues) ||
|
||||
((isset($formData['create_new_pane']) && $formData['create_new_pane'] != false) &&
|
||||
(false === isset($formData['use_existing_dashboard']) || $formData['use_existing_dashboard'] != true))
|
||||
) {
|
||||
$this->addNewPaneTextField(!empty($elems));
|
||||
$elements[] = $this->createElement(
|
||||
'text',
|
||||
'pane',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t("The New Pane's Title"),
|
||||
'style' => 'display: inline-block'
|
||||
)
|
||||
);
|
||||
$elements[] = $this->createElement( // Prevent the button from being displayed again on validation errors
|
||||
'hidden',
|
||||
'create_new_pane',
|
||||
array(
|
||||
'value' => 1
|
||||
)
|
||||
);
|
||||
if (false === empty($paneSelectionValues)) {
|
||||
$elements[] = $this->createElement(
|
||||
'submit',
|
||||
'use_existing_dashboard',
|
||||
array(
|
||||
'ignore' => true,
|
||||
'label' => t('Use An Existing Pane'),
|
||||
'style' => 'display: inline-block'
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$this->addPaneSelectionBox($dashboard);
|
||||
$elements[] = $this->createElement(
|
||||
'select',
|
||||
'pane',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Pane'),
|
||||
'style' => 'display: inline-block;',
|
||||
'multiOptions' => $paneSelectionValues
|
||||
)
|
||||
);
|
||||
$elements[] = $this->createElement(
|
||||
'submit',
|
||||
'create_new_pane',
|
||||
array(
|
||||
'ignore' => true,
|
||||
'label' => t('Create A New Pane'),
|
||||
'style' => 'display: inline-block'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->addElement(
|
||||
$elements[] = $this->createElement(
|
||||
'text',
|
||||
'component',
|
||||
array(
|
||||
'label' => 'Title',
|
||||
'required' => true,
|
||||
'required' => true,
|
||||
'label' => t('Title'),
|
||||
'helptext' => t('The title for the dashlet')
|
||||
)
|
||||
);
|
||||
$this->setSubmitLabel("Add To Dashboard");
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the names and titles of the available dashboard panes as key-value array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDashboardPaneSelectionValues()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->readConfig(IcingaConfig::app('dashboard/dashboard'));
|
||||
return $dashboard->getPaneKeyTitleArray();
|
||||
}
|
||||
}
|
||||
|
@ -1,65 +0,0 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Form\Install;
|
||||
|
||||
use Zend_Config;
|
||||
use Icinga\Web\Wizard\Page;
|
||||
use Icinga\Form\Config\LoggingForm;
|
||||
|
||||
class LoggingPage extends Page
|
||||
{
|
||||
/**
|
||||
* The logging form
|
||||
*
|
||||
* @var LoggingForm
|
||||
*/
|
||||
protected $loggingForm;
|
||||
|
||||
/**
|
||||
* Initialize this LoggingPage
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('logging');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return the logging form
|
||||
*
|
||||
* @return LoggingForm
|
||||
*/
|
||||
protected function createForm()
|
||||
{
|
||||
if ($this->loggingForm === null) {
|
||||
$this->loggingForm = new LoggingForm();
|
||||
$this->loggingForm->hideButtons();
|
||||
$this->loggingForm->setTokenDisabled();
|
||||
$this->loggingForm->setRequest($this->getRequest());
|
||||
$this->loggingForm->setConfiguration($this->getConfiguration());
|
||||
}
|
||||
|
||||
return $this->loggingForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create this wizard page
|
||||
*/
|
||||
protected function create()
|
||||
{
|
||||
$loggingForm = $this->createForm();
|
||||
$loggingForm->buildForm(); // Needs to get called manually as it's nothing that Zend knows about
|
||||
$this->addSubForm($loggingForm, $loggingForm->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a config containing all values provided by the user
|
||||
*
|
||||
* @return Zend_Config
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
return $this->createForm()->getConfig();
|
||||
}
|
||||
}
|
@ -4,147 +4,168 @@
|
||||
|
||||
namespace Icinga\Form\Preference;
|
||||
|
||||
use \DateTimeZone;
|
||||
use \Zend_Config;
|
||||
use \Zend_Form_Element_Text;
|
||||
use \Zend_Form_Element_Select;
|
||||
use \Zend_View_Helper_DateFormat;
|
||||
use \Icinga\Web\Form;
|
||||
use \Icinga\Web\Form\Validator\TimeFormatValidator;
|
||||
use \Icinga\Web\Form\Validator\DateFormatValidator;
|
||||
use \Icinga\Util\Translator;
|
||||
use DateTimeZone;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Util\Translator;
|
||||
use Icinga\User\Preferences;
|
||||
|
||||
/**
|
||||
* General user preferences
|
||||
*/
|
||||
class GeneralForm extends Form
|
||||
{
|
||||
/**
|
||||
* Initialize this preferences config form
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('form_config_preferences');
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a select field for setting the user's language
|
||||
*
|
||||
* Possible values are determined by Translator::getAvailableLocaleCodes.
|
||||
* Also, a 'use default format' checkbox is added in order to allow a user to discard his overwritten setting
|
||||
* Also, a 'use browser language' checkbox is added in order to allow a user to discard his setting
|
||||
*
|
||||
* @param Zend_Config $cfg The "global" section of the config.ini to be used as default value
|
||||
* @param array $formData The data sent by the user
|
||||
*/
|
||||
private function addLanguageSelection(Zend_Config $cfg)
|
||||
protected function getLanguageElements(array $formData)
|
||||
{
|
||||
$languages = array();
|
||||
foreach (Translator::getAvailableLocaleCodes() as $language) {
|
||||
$languages[$language] = $language;
|
||||
}
|
||||
$prefs = $this->getUserPreferences();
|
||||
$useDefaultLanguage = $this->getRequest()->getParam('default_language', !$prefs->has('app.language'));
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'default_language',
|
||||
array(
|
||||
'label' => t('Use Default Language'),
|
||||
'value' => $useDefaultLanguage,
|
||||
'required' => true
|
||||
)
|
||||
);
|
||||
$useBrowserLanguage = isset($formData['browser_language']) ? $formData['browser_language'] == 1 : true;
|
||||
$selectOptions = array(
|
||||
'label' => t('Your Current Language'),
|
||||
'required' => !$useDefaultLanguage,
|
||||
'required' => false === $useBrowserLanguage,
|
||||
'multiOptions' => $languages,
|
||||
'helptext' => t('Use the following language to display texts and messages'),
|
||||
'value' => $prefs->get('app.language', $cfg->get('language', Translator::DEFAULT_LOCALE))
|
||||
'value' => substr(setlocale(LC_ALL, 0), 0, 5)
|
||||
);
|
||||
if ($useDefaultLanguage) {
|
||||
if ($useBrowserLanguage) {
|
||||
$selectOptions['disabled'] = 'disabled';
|
||||
}
|
||||
$this->addElement('select', 'language', $selectOptions);
|
||||
$this->enableAutoSubmit(array('default_language'));
|
||||
|
||||
return array(
|
||||
$this->createElement(
|
||||
'checkbox',
|
||||
'browser_language',
|
||||
array(
|
||||
'required' => true,
|
||||
'class' => 'autosubmit',
|
||||
'label' => t('Use your browser\'s language suggestions'),
|
||||
'value' => $useBrowserLanguage
|
||||
)
|
||||
),
|
||||
$this->createElement('select', 'language', $selectOptions)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a select field for setting the user's timezone.
|
||||
* Add a select field for setting the user's timezone
|
||||
*
|
||||
* Possible values are determined by DateTimeZone::listIdentifiers
|
||||
* Also, a 'use default format' checkbox is added in order to allow a user to discard his overwritten setting
|
||||
* Possible values are determined by DateTimeZone::listIdentifiers.
|
||||
* Also, a 'use local timezone' checkbox is added in order to allow a user to discard his overwritten setting
|
||||
*
|
||||
* @param Zend_Config $cfg The "global" section of the config.ini to be used as default value
|
||||
* @param array $formData The data sent by the user
|
||||
*/
|
||||
private function addTimezoneSelection(Zend_Config $cfg)
|
||||
protected function getTimezoneElements(array $formData)
|
||||
{
|
||||
$tzList = array();
|
||||
foreach (DateTimeZone::listIdentifiers() as $tz) {
|
||||
$tzList[$tz] = $tz;
|
||||
}
|
||||
$helptext = 'Use the following timezone for dates and times';
|
||||
$prefs = $this->getUserPreferences();
|
||||
$useGlobalTimezone = $this->getRequest()->getParam('default_timezone', !$prefs->has('app.timezone'));
|
||||
|
||||
$selectTimezone = new Zend_Form_Element_Select(
|
||||
array(
|
||||
'name' => 'timezone',
|
||||
'label' => 'Your Current Timezone',
|
||||
'required' => !$useGlobalTimezone,
|
||||
'multiOptions' => $tzList,
|
||||
'helptext' => $helptext,
|
||||
'value' => $prefs->get('app.timezone', $cfg->get('timezone', date_default_timezone_get()))
|
||||
)
|
||||
$useLocalTimezone = isset($formData['local_timezone']) ? $formData['local_timezone'] == 1 : true;
|
||||
$selectOptions = array(
|
||||
'label' => 'Your Current Timezone',
|
||||
'required' => false === $useLocalTimezone,
|
||||
'multiOptions' => $tzList,
|
||||
'helptext' => t('Use the following timezone for dates and times'),
|
||||
'value' => date_default_timezone_get()
|
||||
);
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'default_timezone',
|
||||
array(
|
||||
'label' => 'Use Default Timezone',
|
||||
'value' => $useGlobalTimezone,
|
||||
'required' => true
|
||||
)
|
||||
);
|
||||
if ($useGlobalTimezone) {
|
||||
$selectTimezone->setAttrib('disabled', 1);
|
||||
if ($useLocalTimezone) {
|
||||
$selectOptions['disabled'] = 'disabled';
|
||||
}
|
||||
$this->addElement($selectTimezone);
|
||||
$this->enableAutoSubmit(array('default_timezone'));
|
||||
|
||||
return array(
|
||||
$this->createElement(
|
||||
'checkbox',
|
||||
'local_timezone',
|
||||
array(
|
||||
'required' => true,
|
||||
'class' => 'autosubmit',
|
||||
'label' => t('Use your local timezone'),
|
||||
'value' => $useLocalTimezone,
|
||||
)
|
||||
),
|
||||
$this->createElement('select', 'timezone', $selectOptions)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the general form, using the global configuration as fallback values for preferences
|
||||
*
|
||||
* @see Form::create()
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function create()
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$this->setName('form_preference_set');
|
||||
|
||||
$config = $this->getConfiguration();
|
||||
$global = $config->global;
|
||||
if ($global === null) {
|
||||
$global = new Zend_Config(array());
|
||||
}
|
||||
|
||||
$this->addLanguageSelection($global);
|
||||
$this->addTimezoneSelection($global);
|
||||
|
||||
$this->setSubmitLabel('Save Changes');
|
||||
|
||||
$this->addElement(
|
||||
$elements = array_merge($this->getLanguageElements($formData), $this->getTimezoneElements($formData));
|
||||
$elements[] = $this->createElement(
|
||||
'checkbox',
|
||||
'show_benchmark',
|
||||
array(
|
||||
'label' => 'Use benchmark',
|
||||
'value' => $this->getUserPreferences()->get('app.show_benchmark')
|
||||
'label' => t('Use benchmark')
|
||||
)
|
||||
);
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array containing the preferences set in this form
|
||||
* Populate the form with the given preferences
|
||||
*
|
||||
* @return array
|
||||
* @param Preferences $preferences The preferences to populate the form with
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPreferences(Preferences $preferences)
|
||||
{
|
||||
$defaults = array(
|
||||
'browser_language' => $preferences->get('app.language') === null,
|
||||
'local_timezone' => $preferences->get('app.timezone') === null
|
||||
);
|
||||
|
||||
if ($preferences->get('app.language') !== null) {
|
||||
$defaults['language'] = $preferences->get('app.language');
|
||||
}
|
||||
if ($preferences->get('app.timezone') !== null) {
|
||||
$defaults['timezone'] = $preferences->get('app.timezone');
|
||||
}
|
||||
if ($preferences->get('app.show_benchmark')) {
|
||||
$defaults['show_benchmark'] = $preferences->get('app.show_benchmark');
|
||||
}
|
||||
|
||||
$this->setDefaults($defaults);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured preferences
|
||||
*
|
||||
* @return Preferences
|
||||
*/
|
||||
public function getPreferences()
|
||||
{
|
||||
$values = $this->getValues();
|
||||
return array(
|
||||
'app.language' => $values['default_language'] ? null : $values['language'],
|
||||
'app.timezone' => $values['default_timezone'] ? null : $values['timezone'],
|
||||
'app.show_benchmark' => $values['show_benchmark'] === '1' ? true : false
|
||||
return new Preferences(
|
||||
array(
|
||||
'app.language' => $values['browser_language'] ? null : $values['language'],
|
||||
'app.timezone' => $values['local_timezone'] ? null : $values['timezone'],
|
||||
'app.show_benchmark' => $values['show_benchmark'] ? $values['show_benchmark'] : null
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,57 @@
|
||||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
<?= $tabs; ?>
|
||||
</div>
|
||||
|
||||
<div class="content" data-base-target="_next">
|
||||
<?php
|
||||
|
||||
if (isset($this->messageBox)) {
|
||||
// TODO: Get rid of such boxes -> notifications?
|
||||
echo $this->messageBox->render();
|
||||
}
|
||||
?>
|
||||
|
||||
<p>
|
||||
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'ldap')) ?>"><?= $this->icon('create.png'); ?> Create A New LDAP Authentication Backend</a>
|
||||
<br />
|
||||
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'db')) ?>"><?= $this->icon('create.png'); ?> Create A New DB Authentication Backend</a>
|
||||
</p>
|
||||
|
||||
<table class="action">
|
||||
<thead>
|
||||
<th>Resource</th>
|
||||
<th style="width: 5em">Remove</th>
|
||||
<th style="width: 5em">Order</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($this->backends as $backend): ?>
|
||||
<tr>
|
||||
<td class="action">
|
||||
<a href="<?= $this->href('config/editAuthenticationBackend', array('auth_backend' => $backend->name)) ?>">
|
||||
<?= $this->icon('edit.png') ?> <?= $this->escape($backend->name); ?>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?= $this->href('config/removeAuthenticationBackend', array('auth_backend' => $backend->name)) ?>">
|
||||
<?= $this->icon('remove.png', 'Remove') ?>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<?= $backend->reorderForm; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
<?= $messageBox; ?>
|
||||
<p>
|
||||
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'ldap')); ?>">
|
||||
<?= $this->icon('create.png'); ?><?= $this->translate('Create A New LDAP Authentication Backend'); ?>
|
||||
</a>
|
||||
<br>
|
||||
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'db')); ?>">
|
||||
<?= $this->icon('create.png'); ?><?= $this->translate('Create A New DB Authentication Backend'); ?>
|
||||
</a>
|
||||
<br>
|
||||
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'autologin')); ?>">
|
||||
<?= $this->icon('create.png'); ?><?= $this->translate('Create A New Autologin Authentication Backend'); ?>
|
||||
</a>
|
||||
</p>
|
||||
<form id="<?= $form->getName(); ?>" name="<?= $form->getName(); ?>" enctype="<?= $form->getEncType(); ?>" method="<?= $form->getMethod(); ?>">
|
||||
<?= $form->getElement($form->getTokenElementName()); ?>
|
||||
<table class="action">
|
||||
<thead>
|
||||
<th>Backend</th>
|
||||
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
|
||||
<th style="width: 5em"><?= $this->translate('Order'); ?></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php for ($i = 0; $i < count($backendNames); $i++): ?>
|
||||
<tr>
|
||||
<td class="action">
|
||||
<a href="<?= $this->href('config/editAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
|
||||
<?= $this->icon('edit.png'); ?> <?= $this->escape($backendNames[$i]); ?>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?= $this->href('config/removeAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
|
||||
<?= $this->icon('remove.png', $this->translate('Remove')); ?>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($i > 0): ?>
|
||||
<button type="submit" name="<?= $backendNames[$i]; ?>" value="<?= $i - 1; ?>">
|
||||
<?= $this->icon('up.png', $this->translate('Move up in authentication order')); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if ($i + 1 < count($backendNames)): ?>
|
||||
<button type="submit" name="<?= $backendNames[$i]; ?>" value="<?= $i + 1; ?>">
|
||||
<?= $this->icon('down.png', $this->translate('Move down in authentication order')); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endfor; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -1,18 +1,8 @@
|
||||
<h4>
|
||||
<i class="icinga-icon-edit"></i>
|
||||
Edit Backend "<?= $this->escape($this->name); ?>"
|
||||
<?php printf(
|
||||
$this->translate('Edit Backend "%s"'),
|
||||
$this->escape($this->name)
|
||||
); ?>
|
||||
</h4>
|
||||
|
||||
<?php if (isset($this->messageBox)): ?>
|
||||
<?= $this->messageBox->render() ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($this->form->getErrorMessages()): ?>
|
||||
<div>
|
||||
<?php foreach ($this->form->getErrorMessages() as $error): ?>
|
||||
<?= $this->escape($error); ?><br/>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?= $this->form ?>
|
||||
<?= $messageBox; ?>
|
||||
<?= $this->form; ?>
|
||||
|
@ -1,10 +1,8 @@
|
||||
<h4>
|
||||
<i class="icinga-icon-remove"></i>
|
||||
Remove Backend "<?= $this->escape($this->name); ?>"
|
||||
<?php printf(
|
||||
$this->translate('Remove Backend "%s"'),
|
||||
$this->escape($name)
|
||||
); ?>
|
||||
</h4>
|
||||
|
||||
<?php if (isset($this->messageBox)): ?>
|
||||
<?= $this->messageBox->render() ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?= $this->form ?>
|
||||
<?= $messageBox ?>
|
||||
<?= $form ?>
|
||||
|
@ -1,30 +1,33 @@
|
||||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
<?= $tabs; ?>
|
||||
</div>
|
||||
|
||||
<div class="content" data-base-target="_next">
|
||||
<?php
|
||||
|
||||
if (isset($this->messageBox)) {
|
||||
// TODO: Get rid of messageBoxes in favour of notifications
|
||||
echo $this->messageBox->render();
|
||||
}
|
||||
|
||||
?>
|
||||
<p><a href="<?= $this->href('/config/createresource') ?>"><?= $this->icon('create.png'); ?> Create A New Resource</a></p>
|
||||
|
||||
<table class="action">
|
||||
<thead>
|
||||
<th>Resource</th>
|
||||
<th style="width: 5em">Remove</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?= $messageBox; ?>
|
||||
<p>
|
||||
<a href="<?= $this->href('/config/createresource') ?>">
|
||||
<?= $this->icon('create.png'); ?> <?= $this->translate('Create a new resource'); ?>
|
||||
</a>
|
||||
</p>
|
||||
<table class="action">
|
||||
<thead>
|
||||
<th><?= $this->translate('Resource'); ?></th>
|
||||
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($this->resources as $name => $resource): ?>
|
||||
<tr>
|
||||
<td><a href="<?= $this->href('config/editresource', array('resource' => $name)) ?>"><?= $this->icon('edit.png') ?> <?= $this->escape($name); ?></td>
|
||||
<td style="text-align: center"><a href="<?= $this->href('config/removeresource', array('resource' => $name)) ?>"><?= $this->icon('remove.png'); ?></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="<?= $this->href('config/editresource', array('resource' => $name)) ?>">
|
||||
<?= $this->icon('edit.png') ?> <?= $this->escape($name); ?>
|
||||
</a>
|
||||
</td>
|
||||
<td style="text-align: center">
|
||||
<a href="<?= $this->href('config/removeresource', array('resource' => $name)) ?>">
|
||||
<?= $this->icon('remove.png'); ?>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
@ -1,14 +1,4 @@
|
||||
<h4>
|
||||
<i class="icinga-icon-create"></i>
|
||||
Create New Resource
|
||||
</h4>
|
||||
|
||||
<?php if (isset($this->messageBox)): ?>
|
||||
<?= $this->messageBox->render() ?>
|
||||
<?php endif ?>
|
||||
|
||||
<p>
|
||||
Resources are entities that provide data to Icingaweb.
|
||||
</p>
|
||||
|
||||
<?= $this->form ?>
|
||||
<?= $messageBox; ?>
|
||||
<h4><?= $this->translate('Create a new resource'); ?></h4>
|
||||
<p><?= $this->translate('Resources are entities that provide data to Icingaweb.'); ?></p>
|
||||
<?= $form; ?>
|
@ -1,18 +1,3 @@
|
||||
<h4>
|
||||
<i class="icinga-icon-edit"></i>
|
||||
Edit Resource "<?= $this->escape($this->name); ?>"
|
||||
</h4>
|
||||
|
||||
<?php if (isset($this->messageBox)): ?>
|
||||
<?= $this->messageBox->render() ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($this->form->getErrorMessages()): ?>
|
||||
<div>
|
||||
<?php foreach ($this->form->getErrorMessages() as $error): ?>
|
||||
<?= $this->escape($error); ?><br/>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<?= $this->form ?>
|
||||
<h4><?= $this->translate('Edit Existing Resource'); ?></h4>
|
||||
<?= $messageBox; ?>
|
||||
<?= $form; ?>
|
@ -1,10 +1,3 @@
|
||||
<h4>
|
||||
<i class="icinga-icon-remove"></i>
|
||||
Remove Resource "<?= $this->escape($this->name); ?>"
|
||||
</h4>
|
||||
|
||||
<?php if (isset($this->messageBox)): ?>
|
||||
<?= $this->messageBox->render() ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?= $this->form ?>
|
||||
<h4><?= $this->translate('Remove Existing Resource'); ?></h4>
|
||||
<?= $messageBox; ?>
|
||||
<?= $form; ?>
|
@ -6,6 +6,7 @@ namespace Icinga\Logger;
|
||||
|
||||
use Exception;
|
||||
use Zend_Config;
|
||||
use LogicException;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
|
||||
/**
|
||||
@ -37,10 +38,11 @@ class Logger
|
||||
/**
|
||||
* The supported severities
|
||||
*/
|
||||
public static $ERROR = 0;
|
||||
public static $WARNING = 1;
|
||||
public static $INFO = 2;
|
||||
public static $DEBUG = 3;
|
||||
public static $NONE = 0;
|
||||
public static $ERROR = 1;
|
||||
public static $WARNING = 2;
|
||||
public static $INFO = 3;
|
||||
public static $DEBUG = 4;
|
||||
|
||||
/**
|
||||
* Create a new logger object
|
||||
@ -93,9 +95,15 @@ class Logger
|
||||
*
|
||||
* @param string $message The message to write
|
||||
* @param int $severity The severity to use
|
||||
*
|
||||
* @throws LogicException In case $severity equals self::$NONE
|
||||
*/
|
||||
public function log($message, $severity)
|
||||
{
|
||||
if ($severity === static::$NONE) {
|
||||
throw new LogicException("`None' (0) is not a valid severity to log messages");
|
||||
}
|
||||
|
||||
if ($this->writer !== null && $this->verbosity >= $severity) {
|
||||
$this->writer->log($severity, $message);
|
||||
}
|
||||
|
@ -315,14 +315,7 @@ namespace Icinga\Test {
|
||||
public function createForm($formClass, array $requestData = array())
|
||||
{
|
||||
$form = new $formClass;
|
||||
// If the form has CSRF protection enabled, add the token to the request data, else all calls to
|
||||
// isSubmittedAndValid will fail
|
||||
$form->setSessionId('1234');
|
||||
$form->initCsrfToken();
|
||||
$token = $form->getValue($form->getTokenElementName());
|
||||
if ($token !== null) {
|
||||
$requestData[$form->getTokenElementName()] = $token;
|
||||
}
|
||||
$form->setTokenDisabled(); // Disable CSRF protection else all calls to isSubmittedAndValid will fail
|
||||
$request = $this->getRequest();
|
||||
$request->setMethod('POST');
|
||||
$request->setPost($requestData);
|
||||
|
@ -47,6 +47,20 @@ class BaseConfigController extends ActionController
|
||||
Session::getSession()->write();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message with the logging level Zend_Log::WARN to the current user and
|
||||
* commit the changes to the underlying session.
|
||||
*
|
||||
* @param $msg The message content
|
||||
*/
|
||||
protected function addWarningMessage($msg)
|
||||
{
|
||||
AuthenticationManager::getInstance()->getUser()->addMessage(
|
||||
new Message($msg, Zend_Log::WARN)
|
||||
);
|
||||
Session::getSession()->write();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return an array of tabs provided by this configuration controller.
|
||||
*
|
||||
|
@ -4,19 +4,12 @@
|
||||
|
||||
namespace Icinga\Web;
|
||||
|
||||
use Zend_Controller_Request_Abstract;
|
||||
use Zend_Form;
|
||||
use Zend_Config;
|
||||
use Zend_Form_Element_Submit;
|
||||
use Zend_Form_Element_Reset;
|
||||
use Zend_View_Interface;
|
||||
use Icinga\Web\Session;
|
||||
use Icinga\Web\Form\Element\Note;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Web\Form\Decorator\HelpText;
|
||||
use Icinga\Web\Form\Decorator\BootstrapForm;
|
||||
use Icinga\Web\Form\InvalidCSRFTokenException;
|
||||
use Icinga\Application\Config as IcingaConfig;
|
||||
use Icinga\Web\Form\Decorator\ElementWrapper;
|
||||
use Icinga\Web\Form\Element\CsrfCounterMeasure;
|
||||
|
||||
/**
|
||||
* Base class for forms providing CSRF protection, confirmation logic and auto submission
|
||||
@ -24,27 +17,32 @@ use Icinga\Application\Config as IcingaConfig;
|
||||
class Form extends Zend_Form
|
||||
{
|
||||
/**
|
||||
* The form's request object
|
||||
* Whether this form has been created
|
||||
*
|
||||
* @var Zend_Controller_Request_Abstract
|
||||
* @var bool
|
||||
*/
|
||||
protected $request;
|
||||
protected $created = false;
|
||||
|
||||
/**
|
||||
* Main configuration
|
||||
* Label to use for the standard submit button
|
||||
*
|
||||
* Used as fallback if user preferences are not available.
|
||||
*
|
||||
* @var IcingaConfig
|
||||
* @var string
|
||||
*/
|
||||
protected $config;
|
||||
protected $submitLabel;
|
||||
|
||||
/**
|
||||
* The preference object to use instead of the one from the user (used for testing)
|
||||
* The url to redirect to upon success
|
||||
*
|
||||
* @var Zend_Config
|
||||
* @var string|Url
|
||||
*/
|
||||
protected $preferences;
|
||||
protected $redirectUrl;
|
||||
|
||||
/**
|
||||
* The view script to use when rendering this form
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $viewScript;
|
||||
|
||||
/**
|
||||
* Whether this form should NOT add random generated "challenge" tokens that are associated with the user's current
|
||||
@ -56,83 +54,129 @@ class Form extends Zend_Form
|
||||
protected $tokenDisabled = false;
|
||||
|
||||
/**
|
||||
* Name of the CSRF token element (used to create non-colliding hashes)
|
||||
* Name of the CSRF token element
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tokenElementName = 'CSRFToken';
|
||||
|
||||
/**
|
||||
* Flag to indicate that form is already build
|
||||
* Set the label to use for the standard submit button
|
||||
*
|
||||
* @var bool
|
||||
* @param string $label The label to use for the submit button
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected $created = false;
|
||||
public function setSubmitLabel($label)
|
||||
{
|
||||
$this->submitLabel = $label;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Session id used for CSRF token generation
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sessionId;
|
||||
|
||||
/**
|
||||
* Label for submit button
|
||||
*
|
||||
* If omitted, no button will be shown
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $submitLabel;
|
||||
|
||||
/**
|
||||
* Label for cancel button
|
||||
*
|
||||
* If omitted, no button will be shown
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $cancelLabel;
|
||||
|
||||
/**
|
||||
* Last used note-id
|
||||
*
|
||||
* Helper to generate unique names for note elements
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $last_note_id = 0;
|
||||
|
||||
/**
|
||||
* Getter for the session ID
|
||||
*
|
||||
* If the ID has never been set, the ID from session_id() is returned
|
||||
* Return the label being used for the standard submit button
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSessionId()
|
||||
public function getSubmitLabel()
|
||||
{
|
||||
if (!$this->sessionId) {
|
||||
$this->sessionId = Session::getSession()->getId();
|
||||
return $this->submitLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the url to redirect to upon success
|
||||
*
|
||||
* @param string|Url $url The url to redirect to
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setRedirectUrl($url)
|
||||
{
|
||||
$this->redirectUrl = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the url to redirect to upon success
|
||||
*
|
||||
* @return string|Url
|
||||
*/
|
||||
public function getRedirectUrl()
|
||||
{
|
||||
if ($this->redirectUrl === null) {
|
||||
// Be sure to remove all form dependent params because we do not want to submit it again
|
||||
$this->redirectUrl = Url::fromRequest()->without(array_keys($this->getElements()));
|
||||
}
|
||||
|
||||
return $this->sessionId;
|
||||
return $this->redirectUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the session ID
|
||||
* Set the view script to use when rendering this form
|
||||
*
|
||||
* This method should be used for testing purposes only
|
||||
* @param string $viewScript The view script to use
|
||||
*
|
||||
* @param string $sessionId
|
||||
* @return self
|
||||
*/
|
||||
public function setSessionId($sessionId)
|
||||
public function setViewScript($viewScript)
|
||||
{
|
||||
$this->sessionId = $sessionId;
|
||||
$this->viewScript = $viewScript;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the HTML element name of the CSRF token field
|
||||
* Return the view script being used when rendering this form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getViewScript()
|
||||
{
|
||||
return $this->viewScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable CSRF counter measure and remove its field if already added
|
||||
*
|
||||
* @param bool $disabled Set true in order to disable CSRF protection for this form, otherwise false
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setTokenDisabled($disabled = true)
|
||||
{
|
||||
$this->tokenDisabled = (bool) $disabled;
|
||||
|
||||
if ($disabled && $this->getElement($this->tokenElementName) !== null) {
|
||||
$this->removeElement($this->tokenElementName);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether CSRF counter measures are disabled for this form
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getTokenDisabled()
|
||||
{
|
||||
return $this->tokenDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name to use for the CSRF element
|
||||
*
|
||||
* @param string $name The name to set
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setTokenElementName($name)
|
||||
{
|
||||
$this->tokenElementName = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the CSRF element
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -142,427 +186,284 @@ class Form extends Zend_Form
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the form to HTML
|
||||
* Create this form
|
||||
*
|
||||
* @param Zend_View_Interface $view
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(Zend_View_Interface $view = null)
|
||||
{
|
||||
// Elements must be there to render the form
|
||||
$this->buildForm();
|
||||
return parent::render($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add elements to this form (used by extending classes)
|
||||
*/
|
||||
protected function create()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called before validation
|
||||
*/
|
||||
protected function preValidation(array $data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the request
|
||||
*
|
||||
* @param Zend_Controller_Request_Abstract $request
|
||||
*/
|
||||
public function setRequest(Zend_Controller_Request_Abstract $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the request
|
||||
*
|
||||
* @return Zend_Controller_Request_Abstract
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configuration to be used for this form when no preferences are set yet
|
||||
*
|
||||
* @param IcingaConfig $cfg
|
||||
* @param array $formData The data sent by the user
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setConfiguration($cfg)
|
||||
public function create(array $formData = array())
|
||||
{
|
||||
$this->config = $cfg;
|
||||
return $this;
|
||||
}
|
||||
if (false === $this->created) {
|
||||
$this->addElements($this->createElements($formData));
|
||||
$this->addFormIdentification()
|
||||
->addCsrfCounterMeasure()
|
||||
->addSubmitButton();
|
||||
|
||||
/**
|
||||
* Get the main configuration
|
||||
*
|
||||
* Returns the set configuration or an empty default one.
|
||||
*
|
||||
* @return Zend_Config
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
if ($this->config === null) {
|
||||
$this->config = new Zend_Config(array(), true);
|
||||
}
|
||||
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set preferences to be used instead of the one from the user object (used for testing)
|
||||
*
|
||||
* @param Zend_Config $prefs
|
||||
*/
|
||||
public function setUserPreferences($prefs)
|
||||
{
|
||||
$this->preferences = $prefs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the preferences of the user or the overwritten ones
|
||||
*
|
||||
* @return Zend_Config
|
||||
*/
|
||||
public function getUserPreferences()
|
||||
{
|
||||
if ($this->preferences) {
|
||||
return $this->preferences;
|
||||
}
|
||||
|
||||
return $this->getRequest()->getUser()->getPreferences();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the form if not done already
|
||||
*
|
||||
* Adds all elements to the form
|
||||
*/
|
||||
public function buildForm()
|
||||
{
|
||||
if ($this->created === false) {
|
||||
$this->initCsrfToken();
|
||||
$this->create();
|
||||
|
||||
if ($this->submitLabel) {
|
||||
$this->addSubmitButton();
|
||||
}
|
||||
|
||||
if ($this->cancelLabel) {
|
||||
$this->addCancelButton();
|
||||
}
|
||||
|
||||
// Empty action if not safe
|
||||
if (!$this->getAction() && $this->getRequest()) {
|
||||
$this->setAction($this->getRequest()->getRequestUri());
|
||||
if ($this->getAction() === '') {
|
||||
// We MUST set an action as JS gets confused otherwise, if
|
||||
// this form is being displayed in an additional column
|
||||
$this->setAction(Url::fromRequest()->getUrlWithout(array_keys($this->getElements())));
|
||||
}
|
||||
|
||||
$this->created = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the cancel label
|
||||
* Create and return the elements to add to this form
|
||||
*
|
||||
* @param string $cancelLabel
|
||||
*/
|
||||
public function setCancelLabel($cancelLabel)
|
||||
{
|
||||
$this->cancelLabel = $cancelLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add cancel button to form
|
||||
*/
|
||||
protected function addCancelButton()
|
||||
{
|
||||
$this->addElement(
|
||||
new Zend_Form_Element_Reset(
|
||||
array(
|
||||
'name' => 'btn_reset',
|
||||
'label' => $this->cancelLabel,
|
||||
'class' => 'btn pull-right'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the submit label
|
||||
* Intended to be implemented by concrete form classes.
|
||||
*
|
||||
* @param string $submitLabel
|
||||
*/
|
||||
public function setSubmitLabel($submitLabel)
|
||||
{
|
||||
$this->submitLabel = $submitLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add submit button to form
|
||||
*/
|
||||
protected function addSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
new Zend_Form_Element_Submit(
|
||||
array(
|
||||
'name' => 'btn_submit',
|
||||
'label' => $this->submitLabel
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add message to form
|
||||
*
|
||||
* @param string $message The message to be displayed
|
||||
* @param int $headingType Whether it should be displayed as heading (1-6) or not (null)
|
||||
*/
|
||||
public function addNote($message, $headingType = null)
|
||||
{
|
||||
$this->addElement(
|
||||
new Note(
|
||||
array(
|
||||
'escape' => $headingType === null ? false : true,
|
||||
'name' => sprintf('note_%s', $this->last_note_id++),
|
||||
'value' => $headingType === null ? $message : sprintf(
|
||||
'<h%1$s>%2$s</h%1$s>',
|
||||
$headingType,
|
||||
$message
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable automatic form submission on the given elements
|
||||
*
|
||||
* Enables automatic submission of this form once the user edits specific elements
|
||||
*
|
||||
* @param array $triggerElements The element names which should auto-submit the form
|
||||
*
|
||||
* @throws ProgrammingError When an element is found which does not yet exist
|
||||
*/
|
||||
public function enableAutoSubmit($triggerElements)
|
||||
{
|
||||
foreach ($triggerElements as $elementName) {
|
||||
$element = $this->getElement($elementName);
|
||||
if ($element !== null) {
|
||||
$class = $element->getAttrib('class');
|
||||
if ($class === null) {
|
||||
$class = 'autosubmit';
|
||||
} else {
|
||||
$class .= ' autosubmit';
|
||||
}
|
||||
$element->setAttrib('class', $class);
|
||||
} else {
|
||||
throw new ProgrammingError(
|
||||
'You need to add the element "%s" to the form before automatic submission can be enabled!',
|
||||
$elementName
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the form was submitted with a valid request
|
||||
*
|
||||
* Ensures that the current request method is POST, that the form was manually submitted and that the data provided
|
||||
* in the request is valid and gets repopulated in case its invalid.
|
||||
*
|
||||
* @return bool True when the form is submitted and valid, otherwise false
|
||||
*/
|
||||
public function isSubmittedAndValid()
|
||||
{
|
||||
if ($this->getRequest()->isPost() === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->buildForm();
|
||||
$checkData = $this->getRequest()->getParams();
|
||||
$this->assertValidCsrfToken($checkData);
|
||||
|
||||
if ($this->isSubmitted()) {
|
||||
// perform full validation if submitted
|
||||
$this->preValidation($checkData);
|
||||
return $this->isValid($checkData);
|
||||
} else {
|
||||
// only populate if not submitted
|
||||
$this->populate($checkData);
|
||||
$this->setAttrib('data-icinga-form-modified', 'true');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this form has been submitted
|
||||
*
|
||||
* Per default, this checks whether the button set with the 'setSubmitLabel' method
|
||||
* is being submitted. For custom submission logic, this method must be overwritten
|
||||
*
|
||||
* @return bool True when the form is marked as submitted, otherwise false
|
||||
*/
|
||||
public function isSubmitted()
|
||||
{
|
||||
// TODO: There are some missunderstandings and missconceptions to be
|
||||
// found in this class. If populate() etc would have been used as
|
||||
// designed this function would read as simple as:
|
||||
// return $this->getElement('btn_submit')->isChecked();
|
||||
|
||||
if ($this->submitLabel) {
|
||||
$checkData = $this->getRequest()->getParams();
|
||||
return isset($checkData['btn_submit']) && $checkData['btn_submit'];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable CSRF counter measure and remove its field if already added
|
||||
*
|
||||
* This method should be used for testing purposes only
|
||||
*
|
||||
* @param bool $disabled Set true in order to disable CSRF tokens in
|
||||
* this form (default: true), otherwise false
|
||||
*/
|
||||
public function setTokenDisabled($disabled = true)
|
||||
{
|
||||
$this->tokenDisabled = (boolean) $disabled;
|
||||
|
||||
if ($disabled === true) {
|
||||
$this->removeElement($this->tokenElementName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add CSRF counter measure field to form
|
||||
*/
|
||||
public function initCsrfToken()
|
||||
{
|
||||
if (!$this->tokenDisabled && $this->getElement($this->tokenElementName) === null) {
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
$this->tokenElementName,
|
||||
array(
|
||||
'value' => $this->generateCsrfTokenAsString()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the submitted data for a correct CSRF token
|
||||
*
|
||||
* @param array $checkData The POST data send by the user
|
||||
*
|
||||
* @throws InvalidCSRFTokenException When CSRF Validation fails
|
||||
*/
|
||||
public function assertValidCsrfToken(array $checkData)
|
||||
{
|
||||
if (!$this->tokenDisabled) {
|
||||
if (!isset($checkData[$this->tokenElementName])
|
||||
|| !$this->hasValidCsrfToken($checkData[$this->tokenElementName])
|
||||
) {
|
||||
throw new InvalidCSRFTokenException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the form's CSRF token-field has a valid value
|
||||
*
|
||||
* @param string $elementValue Value from the form element
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasValidCsrfToken($elementValue)
|
||||
{
|
||||
if ($this->getElement($this->tokenElementName) === null || strpos($elementValue, '|') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
list($seed, $token) = explode('|', $elementValue);
|
||||
|
||||
if (!is_numeric($seed)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $token === hash('sha256', $this->getSessionId() . $seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new (seed, token) pair
|
||||
* @param array $formData The data sent by the user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function generateCsrfToken()
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$seed = mt_rand();
|
||||
$hash = hash('sha256', $this->getSessionId() . $seed);
|
||||
|
||||
return array($seed, $hash);
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string representation of the CSRF seed/token pair
|
||||
* Perform actions after this form was submitted using a valid request
|
||||
*
|
||||
* @return string
|
||||
* Intended to be implemented by concrete form classes. The base implementation returns always FALSE.
|
||||
*
|
||||
* @param Request $request The valid request used to process this form
|
||||
*
|
||||
* @return bool Whether any redirection should take place
|
||||
*/
|
||||
public function generateCsrfTokenAsString()
|
||||
public function onSuccess(Request $request)
|
||||
{
|
||||
list ($seed, $token) = $this->generateCsrfToken($this->getSessionId());
|
||||
return sprintf('%s|%s', $seed, $token);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new element
|
||||
* Perform actions when no form dependent data was sent
|
||||
*
|
||||
* Additionally, all DtDd tags will be removed and the Bootstrap compatible
|
||||
* BootstrapForm decorator will be added to the elements
|
||||
* Intended to be implemented by concrete form classes.
|
||||
*
|
||||
* @param string|Zend_Form_Element $element String element type, or an object of type Zend_Form_Element
|
||||
* @param string $name The name of the element to add if $element is a string
|
||||
* @param array $options The settings for the element if $element is a string
|
||||
* @param Request $request The current request
|
||||
*/
|
||||
public function onShow(Request $request)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a submit button to this form
|
||||
*
|
||||
* Uses the label previously set with Form::setSubmitLabel(). Overwrite this
|
||||
* method in order to add multiple submit buttons or one with a custom name.
|
||||
*
|
||||
* @return self
|
||||
* @see Zend_Form::addElement()
|
||||
*/
|
||||
public function addElement($element, $name = null, $options = null)
|
||||
public function addSubmitButton()
|
||||
{
|
||||
parent::addElement($element, $name, $options);
|
||||
$el = $name !== null ? $this->getElement($name) : $element;
|
||||
if ($this->submitLabel !== null) {
|
||||
$this->addElement(
|
||||
'submit',
|
||||
'btn_submit',
|
||||
array(
|
||||
'ignore' => true,
|
||||
'label' => $this->submitLabel
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new element
|
||||
*
|
||||
* Additionally, all structural form element decorators by Zend are replaced with our own ones.
|
||||
*
|
||||
* @param string $type String element type
|
||||
* @param string $name The name of the element to add
|
||||
* @param array $options The options for the element
|
||||
*
|
||||
* @return Zend_Form_Element
|
||||
*
|
||||
* @see Zend_Form::createElement()
|
||||
*/
|
||||
public function createElement($type, $name, $options = null)
|
||||
{
|
||||
$el = parent::createElement($type, $name, $options);
|
||||
|
||||
if ($el) {
|
||||
if (strpos(strtolower(get_class($el)), 'hidden') !== false) {
|
||||
// Do not add structural elements to invisible elements which produces ugly views
|
||||
$el->setDecorators(array('ViewHelper'));
|
||||
} else {
|
||||
$el->removeDecorator('HtmlTag');
|
||||
$el->removeDecorator('Label');
|
||||
$el->removeDecorator('DtDdWrapper');
|
||||
$el->addDecorator(new BootstrapForm());
|
||||
$el->addDecorator(new ElementWrapper());
|
||||
$el->addDecorator(new HelpText());
|
||||
}
|
||||
}
|
||||
|
||||
return $el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a field with a unique and form specific ID
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addFormIdentification()
|
||||
{
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
'form_uid',
|
||||
array(
|
||||
'ignore' => true,
|
||||
'value' => $this->getName()
|
||||
)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add CSRF counter measure field to this form
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addCsrfCounterMeasure()
|
||||
{
|
||||
if (false === $this->tokenDisabled && $this->getElement($this->tokenElementName) === null) {
|
||||
$element = new CsrfCounterMeasure($this->tokenElementName);
|
||||
$element->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($element);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the elements with the given values
|
||||
*
|
||||
* @param array $defaults The values to populate the elements with
|
||||
*/
|
||||
public function setDefaults(array $defaults)
|
||||
{
|
||||
$this->create($defaults);
|
||||
return parent::setDefaults($defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the given request using this form
|
||||
*
|
||||
* Redirects to the url set with setRedirectUrl() upon success. See onSuccess()
|
||||
* and onShow() wherewith you can customize the processing logic.
|
||||
*
|
||||
* @param Request $request The request to be processed
|
||||
*
|
||||
* @return Request The request supposed to be processed
|
||||
*/
|
||||
public function handleRequest(Request $request = null)
|
||||
{
|
||||
if ($request === null) {
|
||||
$request = $this->getRequest();
|
||||
}
|
||||
|
||||
$formData = $this->getRequestData($request);
|
||||
if ($this->wasSent($formData)) {
|
||||
$this->populate($formData); // Necessary to get isSubmitted() to work
|
||||
if ($this->isSubmitted() || ! $this->getSubmitLabel()) {
|
||||
if ($this->isValid($formData) && $this->onSuccess($request)) {
|
||||
$this->getResponse()->redirectAndExit($this->getRedirectUrl());
|
||||
}
|
||||
} else {
|
||||
// The form can't be processed but we want to show validation errors though
|
||||
$this->isValidPartial($formData);
|
||||
}
|
||||
} else {
|
||||
$this->onShow($request);
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the submit button of this form was pressed
|
||||
*
|
||||
* When overwriting Form::addSubmitButton() be sure to overwrite this method as well.
|
||||
*
|
||||
* @return bool True in case it was pressed, False otherwise or no submit label was set
|
||||
*/
|
||||
public function isSubmitted()
|
||||
{
|
||||
if ($this->submitLabel !== null) {
|
||||
return $this->getElement('btn_submit')->isChecked();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the data sent by the user refers to this form
|
||||
*
|
||||
* Ensures that the correct form gets processed in case there are multiple forms
|
||||
* with equal submit button names being posted against the same route.
|
||||
*
|
||||
* @param array $formData The data sent by the user
|
||||
*
|
||||
* @return bool Whether the given data refers to this form
|
||||
*/
|
||||
public function wasSent(array $formData)
|
||||
{
|
||||
return isset($formData['form_uid']) && $formData['form_uid'] === $this->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given values (possibly incomplete) are valid
|
||||
*
|
||||
* Unlike Zend_Form::isValid() this will not set NULL as value for
|
||||
* an element that is not present in the given data.
|
||||
*
|
||||
* @param array $formData The data to validate
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidPartial(array $formData)
|
||||
{
|
||||
$this->create($formData);
|
||||
return parent::isValidPartial($formData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given values are valid
|
||||
*
|
||||
* @param array $formData The data to validate
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($formData)
|
||||
{
|
||||
$this->create($formData);
|
||||
return parent::isValid($formData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all elements of this form
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function clearElements()
|
||||
{
|
||||
$this->created = false;
|
||||
return parent::clearElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the default decorators
|
||||
*
|
||||
* Overwrites Zend_Form::loadDefaultDecorators to avoid having the HtmlTag-Decorator added
|
||||
* Overwrites Zend_Form::loadDefaultDecorators to avoid having
|
||||
* the HtmlTag-Decorator added and to provide viewscript usage
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
@ -574,11 +475,83 @@ class Form extends Zend_Form
|
||||
|
||||
$decorators = $this->getDecorators();
|
||||
if (empty($decorators)) {
|
||||
$this->addDecorator('FormElements')
|
||||
//->addDecorator('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form'))
|
||||
->addDecorator('Form');
|
||||
if ($this->viewScript) {
|
||||
$this->addDecorator('ViewScript', array(
|
||||
'viewScript' => $this->viewScript,
|
||||
'form' => $this
|
||||
));
|
||||
} else {
|
||||
$this->addDecorator('FormElements')
|
||||
//->addDecorator('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form'))
|
||||
->addDecorator('Form');
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
$name = parent::getName();
|
||||
if (! $name) {
|
||||
$name = get_class($this);
|
||||
$this->setName($name);
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the request data based on this form's request method
|
||||
*
|
||||
* @param Request $request The request to fetch the data from
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestData(Request $request)
|
||||
{
|
||||
if (strtolower($request->getMethod()) === $this->getMethod()) {
|
||||
return $request->{'get' . ($request->isPost() ? 'Post' : 'Query')}();
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current request
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return Icinga::app()->getFrontController()->getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current Response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return Icinga::app()->getFrontController()->getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render this form
|
||||
*
|
||||
* @param Zend_View_Interface $view The view context to use
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(Zend_View_Interface $view = null)
|
||||
{
|
||||
$this->create();
|
||||
return parent::render($view);
|
||||
}
|
||||
}
|
||||
|
@ -7,23 +7,21 @@ namespace Icinga\Web\Form\Decorator;
|
||||
use Zend_Form_Decorator_Abstract;
|
||||
|
||||
/**
|
||||
* Decorator that styles forms in the DOM Bootstrap wants for it's forms
|
||||
* Decorator that wraps form elements with their labels to allow easier styling
|
||||
*
|
||||
* This component replaces the dt/dd wrapping of elements with the approach used by bootstrap.
|
||||
*
|
||||
* Labels are drawn for all elements, except hidden, button and submit elements. If you want a
|
||||
* placeholder for this elements, set the 'addLabelPlaceholder' property. This can be useful in
|
||||
* cases where you want to put inputs with and inputs without labels on the same line and don't
|
||||
* want buttons to 'jump'
|
||||
* Labels are drawn for all elements, except hidden, button and submit elements. If you want a
|
||||
* placeholder for these elements, set the 'addLabelPlaceholder' property. This can be useful in
|
||||
* cases where you want to put inputs with and inputs without labels on the same line and don't
|
||||
* want buttons to 'jump'
|
||||
*/
|
||||
class BootstrapForm extends Zend_Form_Decorator_Abstract
|
||||
class ElementWrapper extends Zend_Form_Decorator_Abstract
|
||||
{
|
||||
/**
|
||||
* An array of elements that won't get a <label> dom added per default
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $noLabel = array(
|
||||
protected static $noLabel = array(
|
||||
'Zend_Form_Element_Hidden',
|
||||
'Zend_Form_Element_Button',
|
||||
'Zend_Form_Element_Submit'
|
||||
@ -32,18 +30,19 @@ class BootstrapForm extends Zend_Form_Decorator_Abstract
|
||||
/**
|
||||
* Return the DOM for the element label
|
||||
*
|
||||
* @param String $elementName The name of the element
|
||||
* @param String $elementName The name of the element
|
||||
*
|
||||
* @return String The DOM for the form element's label
|
||||
*/
|
||||
public function getLabel($elementName)
|
||||
{
|
||||
$label = $this->getElement()->getLabel();
|
||||
if (!$label) {
|
||||
if (! $label) {
|
||||
$label = ' ';
|
||||
}
|
||||
|
||||
if (in_array($this->getElement()->getType(), self::$noLabel)
|
||||
&& !$this->getElement()->getAttrib('addLabelPlaceholder', false)) {
|
||||
&& false === $this->getElement()->getAttrib('addLabelPlaceholder', false)) {
|
||||
$label = '';
|
||||
} else {
|
||||
if (in_array($this->getElement()->getType(), self::$noLabel)) {
|
||||
@ -51,30 +50,21 @@ class BootstrapForm extends Zend_Form_Decorator_Abstract
|
||||
}
|
||||
$label = '<label for="' . $elementName . '">' . $label . '</label>';
|
||||
}
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render this element
|
||||
*
|
||||
* Renders as the following:
|
||||
* <div class="form-group">
|
||||
* $dtLabel
|
||||
* $dtElement
|
||||
* </div>
|
||||
* @param String $content The content of the form element
|
||||
*
|
||||
* @param String $content The content of the form element
|
||||
*
|
||||
* @return String The decorated form element
|
||||
* @return String The decorated form element
|
||||
*/
|
||||
public function render($content)
|
||||
{
|
||||
$el = $this->getElement();
|
||||
$elementName = $el->getName();
|
||||
$elementName = $this->getElement()->getName();
|
||||
$label = $this->getLabel($elementName);
|
||||
return '<div class="form-group" id="' . $elementName . '-element">'
|
||||
. $label
|
||||
. $content
|
||||
. '</div>';
|
||||
return '<div class="form-element" id="' . $elementName . '-element">' . $label . $content . '</div>';
|
||||
}
|
||||
}
|
87
library/Icinga/Web/Form/Element/CsrfCounterMeasure.php
Normal file
87
library/Icinga/Web/Form/Element/CsrfCounterMeasure.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Web\Form\Element;
|
||||
|
||||
use Zend_Form_Element_Xhtml;
|
||||
use Icinga\Web\Session;
|
||||
use Icinga\Web\Form\InvalidCSRFTokenException;
|
||||
|
||||
/**
|
||||
* CSRF counter measure element
|
||||
*
|
||||
* You must not set a value to successfully use this element, just give it a name and you're good to go.
|
||||
*/
|
||||
class CsrfCounterMeasure extends Zend_Form_Element_Xhtml
|
||||
{
|
||||
/**
|
||||
* Default form view helper to use for rendering
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $helper = 'formHidden';
|
||||
|
||||
/**
|
||||
* Initialize this form element
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setRequired(true); // Not requiring this element would not make any sense
|
||||
$this->setIgnore(true); // We do not want this element's value being retrieved by Form::getValues()
|
||||
$this->setValue($this->generateCsrfToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether $value is a valid CSRF token
|
||||
*
|
||||
* @param string $value The value to check
|
||||
* @param mixed $context Context to use
|
||||
*
|
||||
* @return bool True, in case the CSRF token is valid
|
||||
*
|
||||
* @throws InvalidCSRFTokenException In case the CSRF token is not valid
|
||||
*/
|
||||
public function isValid($value, $context = null)
|
||||
{
|
||||
if (parent::isValid($value, $context) && $this->isValidCsrfToken($value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
throw new InvalidCSRFTokenException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given value is a valid CSRF token for the current session
|
||||
*
|
||||
* @param string $token The CSRF token
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isValidCsrfToken($token)
|
||||
{
|
||||
if (strpos($token, '|') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
list($seed, $hash) = explode('|', $token);
|
||||
|
||||
if (false === is_numeric($seed)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $hash === hash('sha256', Session::getSession()->getId() . $seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new (seed, token) pair
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateCsrfToken()
|
||||
{
|
||||
$seed = mt_rand();
|
||||
$hash = hash('sha256', Session::getSession()->getId() . $seed);
|
||||
return sprintf('%s|%s', $seed, $hash);
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ namespace Icinga\Web\Widget;
|
||||
|
||||
use Zend_Log;
|
||||
use Zend_Form;
|
||||
use Zend_View_Abstract;
|
||||
use Icinga\User;
|
||||
use Icinga\User\Message;
|
||||
use Icinga\Web\Session;
|
||||
|
@ -132,7 +132,6 @@ class SortBox extends AbstractWidget
|
||||
$sort = $form->getElement('sort')->setDecorators(array('ViewHelper'));
|
||||
$dir = $form->getElement('dir')->setDecorators(array('ViewHelper'));
|
||||
if ($this->request) {
|
||||
$form->setAction($this->request->getRequestUri());
|
||||
$form->populate($this->request->getParams());
|
||||
}
|
||||
return $form;
|
||||
|
@ -2,15 +2,8 @@
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Logger\Logger;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Module\Monitoring\Controller;
|
||||
use Icinga\Chart\SVGRenderer;
|
||||
use Icinga\Chart\GridChart;
|
||||
use Icinga\Chart\Palette;
|
||||
use Icinga\Chart\Axis;
|
||||
use Icinga\Chart\PieChart;
|
||||
use Icinga\Chart\Unit\StaticAxis;
|
||||
|
||||
@ -140,7 +133,7 @@ class Monitoring_ChartController extends Controller
|
||||
}
|
||||
$this->view->chart = new GridChart();
|
||||
$this->view->chart->setAxisLabel('', t('Services'))
|
||||
->setXAxis(new \Icinga\Chart\Unit\StaticAxis())
|
||||
->setXAxis(new StaticAxis())
|
||||
->setAxisMin(null, 0);
|
||||
|
||||
$this->view->chart->drawBars(
|
||||
|
@ -3,19 +3,14 @@
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
use \Exception;
|
||||
|
||||
use \Zend_Config;
|
||||
use Icinga\Config\PreservingIniWriter;
|
||||
use Icinga\Web\Controller\ModuleActionController;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
use Icinga\Module\Monitoring\Form\Config\ConfirmRemovalForm;
|
||||
use Icinga\Module\Monitoring\Form\Config\Backend\EditBackendForm;
|
||||
use Icinga\Module\Monitoring\Form\Config\Backend\CreateBackendForm;
|
||||
use Icinga\Module\Monitoring\Form\Config\Instance\EditInstanceForm;
|
||||
use Icinga\Module\Monitoring\Form\Config\Instance\CreateInstanceForm;
|
||||
use Icinga\Form\Config\ConfirmRemovalForm;
|
||||
use Icinga\Module\Monitoring\Form\Config\BackendForm;
|
||||
use Icinga\Module\Monitoring\Form\Config\InstanceForm;
|
||||
use Icinga\Module\Monitoring\Form\Config\SecurityForm;
|
||||
|
||||
use Icinga\Exception\NotReadableError;
|
||||
|
||||
/**
|
||||
@ -23,7 +18,6 @@ use Icinga\Exception\NotReadableError;
|
||||
*/
|
||||
class Monitoring_ConfigController extends ModuleActionController
|
||||
{
|
||||
|
||||
/**
|
||||
* Display a list of available backends and instances
|
||||
*/
|
||||
@ -49,52 +43,63 @@ class Monitoring_ConfigController extends ModuleActionController
|
||||
*/
|
||||
public function editbackendAction()
|
||||
{
|
||||
// Fetch the backend to be edited
|
||||
$backend = $this->getParam('backend');
|
||||
if (!$this->isExistingBackend($backend)) {
|
||||
$this->view->error = 'Unknown backend ' . $backend;
|
||||
return;
|
||||
$backendsConfig = $this->Config('backends')->toArray();
|
||||
if (false === array_key_exists($backend, $backendsConfig)) {
|
||||
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
|
||||
Notification::error(sprintf($this->translate('Cannot edit "%s". Backend not found.'), $backend));
|
||||
$this->redirectNow('monitoring/config');
|
||||
}
|
||||
$backendForm = new EditBackendForm();
|
||||
$backendForm->setRequest($this->getRequest());
|
||||
$backendForm->setBackendConfiguration($this->Config('backends')->get($backend));
|
||||
|
||||
if ($backendForm->isSubmittedAndValid()) {
|
||||
$newConfig = $backendForm->getConfig();
|
||||
$config = $this->Config('backends');
|
||||
$config->$backend = $newConfig;
|
||||
if ($this->writeConfiguration($config, 'backends')) {
|
||||
Notification::success('Backend ' . $backend . ' Modified.');
|
||||
$form = new BackendForm();
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost()) {
|
||||
if ($form->isValid($request->getPost())) {
|
||||
list($newName, $config) = $form->getBackendConfig();
|
||||
|
||||
if ($newName !== $backend) {
|
||||
// Backend name has changed
|
||||
unset($backendsConfig[$backend]); // We can safely use unset as all values are part of the form
|
||||
}
|
||||
|
||||
$backendsConfig[$newName] = $config;
|
||||
if ($this->writeConfiguration($backendsConfig, 'backends')) {
|
||||
Notification::success(sprintf($this->translate('Backend "%s" successfully modified.'), $backend));
|
||||
$this->redirectNow('monitoring/config');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$form->setBackendConfig($backend, $backendsConfig[$backend]);
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a form to create a new backend
|
||||
*/
|
||||
public function createbackendAction()
|
||||
{
|
||||
$form = new BackendForm();
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost() && $form->isValid($request->getPost())) {
|
||||
list($name, $config) = $form->getBackendConfig();
|
||||
$backendsConfig = $this->Config('backends')->toArray();
|
||||
$backendsConfig[$name] = $config;
|
||||
if ($this->writeConfiguration($backendsConfig, 'backends')) {
|
||||
Notification::success(sprintf($this->translate('Backend "%s" created successfully.'), $name));
|
||||
$this->redirectNow('monitoring/config');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->view->name = $backend;
|
||||
$this->view->form = $backendForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a form to create a new backends
|
||||
*/
|
||||
public function createbackendAction()
|
||||
{
|
||||
$form = new CreateBackendForm();
|
||||
$form->setRequest($this->getRequest());
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$configArray = $this->Config('backends')->toArray();
|
||||
$configArray[$form->getBackendName()] = $form->getConfig();
|
||||
|
||||
if ($this->writeConfiguration(new Zend_Config($configArray), 'backends')) {
|
||||
Notification::success('Backend Creation Succeeded');
|
||||
$this->redirectNow('monitoring/config');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
}
|
||||
return;
|
||||
}
|
||||
$this->view->form = $form;
|
||||
$this->render('editbackend');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,57 +108,53 @@ class Monitoring_ConfigController extends ModuleActionController
|
||||
public function removebackendAction()
|
||||
{
|
||||
$backend = $this->getParam('backend');
|
||||
if (!$this->isExistingBackend($backend)) {
|
||||
$this->view->error = 'Unknown backend ' . $backend;
|
||||
return;
|
||||
$backendsConfig = $this->Config('backends')->toArray();
|
||||
if (false === array_key_exists($backend, $backendsConfig)) {
|
||||
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
|
||||
Notification::error(sprintf($this->translate('Cannot remove "%s". Backend not found.'), $backend));
|
||||
$this->redirectNow('monitoring/config');
|
||||
}
|
||||
|
||||
$form = new ConfirmRemovalForm();
|
||||
$form->setRequest($this->getRequest());
|
||||
$form->setRemoveTarget('backend', $backend);
|
||||
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$configArray = $this->Config('backends')->toArray();
|
||||
unset($configArray[$backend]);
|
||||
|
||||
if ($this->writeConfiguration(new Zend_Config($configArray), 'backends')) {
|
||||
Notification::success('Backend "' . $backend . '" Removed');
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost() && $form->isValid($request->getPost())) {
|
||||
unset($backendsConfig[$backend]);
|
||||
if ($this->writeConfiguration($backendsConfig, 'backends')) {
|
||||
Notification::success(sprintf($this->translate('Backend "%s" successfully removed.'), $backend));
|
||||
$this->redirectNow('monitoring/config');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
$this->view->name = $backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a form to remove the instance identified by the 'instance' parameter
|
||||
* Display a confirmation form to remove the instance identified by the 'instance' parameter
|
||||
*/
|
||||
public function removeinstanceAction()
|
||||
{
|
||||
$instance = $this->getParam('instance');
|
||||
if (!$this->isExistingInstance($instance)) {
|
||||
$this->view->error = 'Unknown instance ' . $instance;
|
||||
return;
|
||||
$instancesConfig = $this->Config('instances')->toArray();
|
||||
if (false === array_key_exists($instance, $instancesConfig)) {
|
||||
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
|
||||
Notification::error(sprintf($this->translate('Cannot remove "%s". Instance not found.'), $instance));
|
||||
$this->redirectNow('monitoring/config');
|
||||
}
|
||||
|
||||
$form = new ConfirmRemovalForm();
|
||||
$form->setRequest($this->getRequest());
|
||||
$form->setRemoveTarget('instance', $instance);
|
||||
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$configArray = $this->Config('instances')->toArray();
|
||||
unset($configArray[$instance]);
|
||||
|
||||
if ($this->writeConfiguration(new Zend_Config($configArray), 'instances')) {
|
||||
Notification::success('Instance "' . $instance . '" Removed');
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost() && $form->isValid($request->getPost())) {
|
||||
unset($instancesConfig[$instance]);
|
||||
if ($this->writeConfiguration($instancesConfig, 'instances')) {
|
||||
Notification::success(sprintf($this->translate('Instance "%s" successfully removed.'), $instance));
|
||||
$this->redirectNow('monitoring/config');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
@ -166,24 +167,36 @@ class Monitoring_ConfigController extends ModuleActionController
|
||||
public function editinstanceAction()
|
||||
{
|
||||
$instance = $this->getParam('instance');
|
||||
if (!$this->isExistingInstance($instance)) {
|
||||
$this->view->error = 'Unknown instance ' . htmlentities($instance);
|
||||
return;
|
||||
$instancesConfig = $this->Config('instances')->toArray();
|
||||
if (false === array_key_exists($instance, $instancesConfig)) {
|
||||
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
|
||||
Notification::error(sprintf($this->translate('Cannot edit "%s". Instance not found.'), $instance));
|
||||
$this->redirectNow('monitoring/config');
|
||||
}
|
||||
$form = new EditInstanceForm();
|
||||
$form->setInstanceConfiguration($this->Config('instances')->get($instance));
|
||||
$form->setRequest($this->getRequest());
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$instanceConfig = $this->Config('instances')->toArray();
|
||||
$instanceConfig[$instance] = $form->getConfig();
|
||||
if ($this->writeConfiguration(new Zend_Config($instanceConfig), 'instances')) {
|
||||
Notification::success('Instance Modified');
|
||||
$this->redirectNow('monitoring/config');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
|
||||
$form = new InstanceForm();
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost()) {
|
||||
if ($form->isValid($request->getPost())) {
|
||||
list($newName, $config) = $form->getInstanceConfig();
|
||||
|
||||
if ($newName !== $instance) {
|
||||
unset($instancesConfig[$instance]); // We can safely use unset as all values are part of the form
|
||||
}
|
||||
|
||||
$instancesConfig[$newName] = $config;
|
||||
if ($this->writeConfiguration($instancesConfig, 'instances')) {
|
||||
Notification::success(sprintf($this->translate('Instance "%s" successfully modified.'), $instance));
|
||||
$this->redirectNow('monitoring/config');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$form->setInstanceConfig($instance, $instancesConfig[$instance]);
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
@ -192,33 +205,37 @@ class Monitoring_ConfigController extends ModuleActionController
|
||||
*/
|
||||
public function createinstanceAction()
|
||||
{
|
||||
$form = new CreateInstanceForm();
|
||||
$form->setRequest($this->getRequest());
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$instanceConfig = $this->Config('instances');
|
||||
if ($instanceConfig === null) {
|
||||
$instanceConfig = array();
|
||||
} else {
|
||||
$instanceConfig = $instanceConfig->toArray();
|
||||
}
|
||||
$instanceConfig[$form->getInstanceName()] = $form->getConfig()->toArray();
|
||||
if ($this->writeConfiguration(new Zend_Config($instanceConfig), 'instances')) {
|
||||
Notification::success('Instance Creation Succeeded');
|
||||
$form = new InstanceForm();
|
||||
$request = $this->getRequest();
|
||||
if ($request->isPost() && $form->isValid($request->getPost())) {
|
||||
list($name, $config) = $form->getInstanceConfig();
|
||||
$instancesConfig = $this->Config('instances')->toArray();
|
||||
$instancesConfig[$name] = $config;
|
||||
if ($this->writeConfiguration($instancesConfig, 'instances')) {
|
||||
Notification::success(sprintf($this->translate('Instance "%s" created successfully.'), $name));
|
||||
$this->redirectNow('monitoring/config');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
$this->render('editinstance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a form to remove the instance identified by the 'instance' parameter
|
||||
* Write configuration to an ini file
|
||||
*
|
||||
* @param Zend_Config $config The configuration to write
|
||||
* @param string $file The config file to write to
|
||||
*
|
||||
* @return bool Whether the configuration was written or not
|
||||
*/
|
||||
private function writeConfiguration($config, $file = null)
|
||||
protected function writeConfiguration($config, $file = null)
|
||||
{
|
||||
if (is_array($config)) {
|
||||
$config = new Zend_Config($config);
|
||||
}
|
||||
$target = $this->Config($file)->getConfigFile();
|
||||
$writer = new PreservingIniWriter(array('filename' => $target, 'config' => $config));
|
||||
|
||||
@ -235,49 +252,30 @@ class Monitoring_ConfigController extends ModuleActionController
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the backend exists in the current configuration
|
||||
*
|
||||
* @param string $backend The name of the backend to check for existence
|
||||
*
|
||||
* @return bool True if the backend name exists, otherwise false
|
||||
* Display a form to adjust security relevant settings
|
||||
*/
|
||||
private function isExistingBackend($backend)
|
||||
{
|
||||
$backendCfg = $this->Config('backends');
|
||||
return $backend && $backendCfg->get($backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the instance exists in the current configuration
|
||||
*
|
||||
* @param string $instance The name of the instance to check for existence
|
||||
*
|
||||
* @return bool True if the instance name exists, otherwise false
|
||||
*/
|
||||
private function isExistingInstance($instance)
|
||||
{
|
||||
$instanceCfg = $this->Config('instances');
|
||||
return $instanceCfg && $instanceCfg->get($instance);
|
||||
}
|
||||
|
||||
public function securityAction()
|
||||
{
|
||||
$this->view->tabs = $this->Module()->getConfigTabs()->activate('security');
|
||||
|
||||
$form = new SecurityForm();
|
||||
$form->setConfiguration($this->Config()->get('security'));
|
||||
$form->setRequest($this->getRequest());
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
$config = $this->Config()->toArray();
|
||||
$config['security'] = $form->getConfig();
|
||||
if ($this->writeConfiguration(new Zend_Config($config))) {
|
||||
Notification::success('Configuration modified successfully');
|
||||
$this->redirectNow('monitoring/config/security');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
$request = $this->getRequest();
|
||||
$config = $this->Config()->toArray();
|
||||
if ($request->isPost()) {
|
||||
if ($form->isValid($request->getPost())) {
|
||||
$config['security'] = $form->getValues();
|
||||
if ($this->writeConfiguration(new Zend_Config($config))) {
|
||||
Notification::success('Configuration modified successfully');
|
||||
$this->redirectNow('monitoring/config/security');
|
||||
} else {
|
||||
$this->render('show-configuration');
|
||||
return;
|
||||
}
|
||||
}
|
||||
} elseif (isset($config['security'])) {
|
||||
$form->populate($config['security']);
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,7 @@
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Module\Monitoring\Controller;
|
||||
use Icinga\Module\Monitoring\Backend;
|
||||
use Icinga\Data\SimpleQuery;
|
||||
use Icinga\Web\Widget\Chart\InlinePie;
|
||||
use Icinga\Module\Monitoring\Form\Command\MultiCommandFlagForm;
|
||||
use Icinga\Web\Widget;
|
||||
|
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Form\Config\Backend;
|
||||
|
||||
use \Zend_Config;
|
||||
|
||||
/**
|
||||
* Extended EditBackendForm for creating new Backends
|
||||
*
|
||||
* @see EditBackendForm
|
||||
*/
|
||||
class CreateBackendForm extends EditBackendForm
|
||||
{
|
||||
/**
|
||||
* Create this form
|
||||
*
|
||||
* @see EditBackendForm::create()
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->setBackendConfiguration(new Zend_Config(array('type' => 'ido')));
|
||||
$this->addElement(
|
||||
'text',
|
||||
'backend_name',
|
||||
array(
|
||||
'label' => 'Backend Name',
|
||||
'required' => true,
|
||||
'helptext' => 'This will be the identifier of this backend'
|
||||
)
|
||||
);
|
||||
parent::create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the backend that is to be created
|
||||
*
|
||||
* @return string The name of the backend as entered in the form
|
||||
*/
|
||||
public function getBackendName()
|
||||
{
|
||||
return $this->getValue('backend_name');
|
||||
}
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Form\Config\Backend;
|
||||
|
||||
use Zend_Config;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
|
||||
/**
|
||||
* Form for modifying a monitoring backend
|
||||
*/
|
||||
class EditBackendForm extends Form
|
||||
{
|
||||
/**
|
||||
* Database resources to use instead of the one's from ResourceFactory (used for testing)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $resources;
|
||||
|
||||
/**
|
||||
* The Backend configuration to use for populating the form
|
||||
*
|
||||
* @var Zend_Config
|
||||
*/
|
||||
protected $backend;
|
||||
|
||||
/**
|
||||
* Set the configuration to be used for initial population of the form
|
||||
*
|
||||
* @param Zend_Form $config
|
||||
*/
|
||||
public function setBackendConfiguration($config)
|
||||
{
|
||||
$this->backend = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom array of resources to be used in this form instead of the ones from ResourceFactory
|
||||
* (used for testing)
|
||||
*/
|
||||
public function setResources($resources)
|
||||
{
|
||||
$this->resources = $resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return content of the resources.ini or previously set resources for displaying in the database selection field
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResources()
|
||||
{
|
||||
if ($this->resources === null) {
|
||||
return ResourceFactory::getResourceConfigs()->toArray();
|
||||
} else {
|
||||
return $this->resources;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all resources of the given type ready to be used as content for a select input
|
||||
*
|
||||
* @param string $type The type of resources to return
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getResourcesByType($type)
|
||||
{
|
||||
$backends = array();
|
||||
foreach ($this->getResources() as $name => $resource) {
|
||||
if ($resource['type'] === $type) {
|
||||
$backends[$name] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $backends;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create this form
|
||||
*
|
||||
* @see Icinga\Web\Form::create()
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$backendType = $this->getRequest()->getParam('backend_type', $this->backend->type);
|
||||
|
||||
$this->addElement(
|
||||
'select',
|
||||
'backend_type',
|
||||
array(
|
||||
'label' => 'Backend Type',
|
||||
'value' => $this->backend->type,
|
||||
'required' => true,
|
||||
'helptext' => 'The data source used for retrieving monitoring information',
|
||||
'multiOptions' => array(
|
||||
'ido' => 'IDO Backend',
|
||||
'statusdat' => 'Status.dat',
|
||||
'livestatus' => 'Livestatus'
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'select',
|
||||
'backend_resource',
|
||||
array(
|
||||
'label' => 'Resource',
|
||||
'value' => $this->backend->resource,
|
||||
'required' => true,
|
||||
'multiOptions' => $this->getResourcesByType($backendType === 'ido' ? 'db' : $backendType),
|
||||
'helptext' => 'The resource to use'
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'backend_disable',
|
||||
array(
|
||||
'label' => 'Disable This Backend',
|
||||
'required' => true,
|
||||
'value' => $this->backend->disabled
|
||||
)
|
||||
);
|
||||
|
||||
$this->enableAutoSubmit(array('backend_type'));
|
||||
$this->setSubmitLabel('{{SAVE_ICON}} Save Changes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a configuration containing the backend settings entered in this form
|
||||
*
|
||||
* @return Zend_Config The updated configuration for this backend
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
$values = $this->getValues();
|
||||
return new Zend_Config(
|
||||
array(
|
||||
'type' => $values['backend_type'],
|
||||
'disabled' => $values['backend_disable'],
|
||||
'resource' => $values['backend_resource']
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
125
modules/monitoring/application/forms/Config/BackendForm.php
Normal file
125
modules/monitoring/application/forms/Config/BackendForm.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Form\Config;
|
||||
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
|
||||
/**
|
||||
* Form for modifying a monitoring backend
|
||||
*/
|
||||
class BackendForm extends Form
|
||||
{
|
||||
/**
|
||||
* Initialize this form
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('form_config_monitoring_backends');
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'name',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Backend Name'),
|
||||
'helptext' => t('The identifier of this backend')
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'select',
|
||||
'type',
|
||||
array(
|
||||
'required' => true,
|
||||
'class' => 'autosubmit',
|
||||
'label' => t('Backend Type'),
|
||||
'helptext' => t('The data source used for retrieving monitoring information'),
|
||||
'multiOptions' => array(
|
||||
'ido' => 'IDO Backend',
|
||||
'statusdat' => 'Status.dat',
|
||||
'livestatus' => 'Livestatus'
|
||||
)
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'select',
|
||||
'resource',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Resource'),
|
||||
'helptext' => t('The resource to use'),
|
||||
'multiOptions' => $this->getResourcesByType(
|
||||
false === isset($formData['type']) || $formData['type'] === 'ido' ? 'db' : $formData['type']
|
||||
)
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'checkbox',
|
||||
'disabled',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Disable This Backend')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the backend configuration values and its name
|
||||
*
|
||||
* The first value is the name and the second one the values as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBackendConfig()
|
||||
{
|
||||
$values = $this->getValues();
|
||||
$name = $values['name'];
|
||||
|
||||
if ($values['disabled'] == '0') {
|
||||
unset($values['disabled']);
|
||||
}
|
||||
|
||||
unset($values['name']);
|
||||
return array($name, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the form with the given configuration values
|
||||
*
|
||||
* @param string $name The name of the backend
|
||||
* @param array $config The configuration values
|
||||
*/
|
||||
public function setBackendConfig($name, array $config)
|
||||
{
|
||||
$config['name'] = $name;
|
||||
$this->populate($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all resources of the given type ready to be used as content for a select input
|
||||
*
|
||||
* @param string $type The type of resources to return
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getResourcesByType($type)
|
||||
{
|
||||
$backends = array();
|
||||
foreach (array_keys(ResourceFactory::getResourceConfigs($type)->toArray()) as $name) {
|
||||
$backends[$name] = $name;
|
||||
}
|
||||
|
||||
return $backends;
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Form\Config;
|
||||
|
||||
use Icinga\Web\Form;
|
||||
|
||||
/**
|
||||
* Form for confirming removal of an object
|
||||
*/
|
||||
class ConfirmRemovalForm extends Form
|
||||
{
|
||||
/**
|
||||
* The value of the target to remove
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $removeTarget;
|
||||
|
||||
/**
|
||||
* The name of the target parameter to remove
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $targetName;
|
||||
|
||||
/**
|
||||
* Set the remove target in this field to be a hidden field with $name and value $target
|
||||
*
|
||||
* @param string $name The name to be set in the hidden field
|
||||
* @param string $target The value to be set in the hidden field
|
||||
*/
|
||||
public function setRemoveTarget($name, $target)
|
||||
{
|
||||
$this->targetName = $name;
|
||||
$this->removeTarget = $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the confirmation form
|
||||
*
|
||||
* @see Form::create()
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
$this->targetName,
|
||||
array(
|
||||
'value' => $this->removeTarget,
|
||||
'required' => true
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'button',
|
||||
'btn_submit',
|
||||
array(
|
||||
'type' => 'submit',
|
||||
'escape' => false,
|
||||
'value' => '1',
|
||||
'class' => 'btn btn-cta btn-common',
|
||||
'label' => $this->getView()->icon('remove.png') . ' Confirm Removal'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Form\Config\Instance;
|
||||
|
||||
use \Icinga\Web\Form;
|
||||
use \Zend_Config;
|
||||
|
||||
/**
|
||||
* Form for creating new instances
|
||||
*
|
||||
* @see EditInstanceForm
|
||||
*/
|
||||
class CreateInstanceForm extends EditInstanceForm
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the form elements
|
||||
*
|
||||
* @see EditInstanceForm::create()
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->setInstanceConfiguration(new Zend_Config(array()));
|
||||
$this->addElement(
|
||||
'text',
|
||||
'instance_name',
|
||||
array(
|
||||
'label' => 'Instance Name',
|
||||
'helptext' => 'Please enter the name for the instance to create'
|
||||
)
|
||||
);
|
||||
parent::create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the instance to be created
|
||||
*
|
||||
* @return string The name of the instance as entered in the form
|
||||
*/
|
||||
public function getInstanceName()
|
||||
{
|
||||
return $this->getValue('instance_name');
|
||||
}
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Form\Config\Instance;
|
||||
|
||||
use \Zend_Config;
|
||||
use \Icinga\Web\Form;
|
||||
|
||||
/**
|
||||
* Form for editing existing instances
|
||||
*/
|
||||
class EditInstanceForm extends Form
|
||||
{
|
||||
/**
|
||||
* The instance to edit
|
||||
*
|
||||
* @var Zend_Config
|
||||
*/
|
||||
private $instance;
|
||||
|
||||
/**
|
||||
* The type of the instance
|
||||
*
|
||||
* 'local' when no host is given, otherwise 'remote'
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $instanceType = 'local';
|
||||
|
||||
/**
|
||||
* Set instance configuration to be used for initial form population
|
||||
*
|
||||
* @param Zend_Config $config
|
||||
*/
|
||||
public function setInstanceConfiguration($config)
|
||||
{
|
||||
$this->instance = $config;
|
||||
if (isset($this->instance->host)) {
|
||||
$this->instanceType = 'remote';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a form field for selecting the command pipe type (local or remote)
|
||||
*/
|
||||
private function addTypeSelection()
|
||||
{
|
||||
$this->addElement(
|
||||
'select',
|
||||
'instance_type',
|
||||
array(
|
||||
'value' => $this->instanceType,
|
||||
'multiOptions' => array(
|
||||
'local' => 'Local Command Pipe',
|
||||
'remote' => 'Remote Command Pipe'
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->enableAutoSubmit(array('instance_type'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add form elements for remote instance
|
||||
*/
|
||||
private function addRemoteInstanceForm()
|
||||
{
|
||||
$this->addNote('When configuring a remote host, you need to setup passwordless key authentication');
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'instance_remote_host',
|
||||
array(
|
||||
'label' => 'Remote Host',
|
||||
'required' => true,
|
||||
'value' => $this->instance->host,
|
||||
'helptext' => 'Enter the hostname or address of the machine on which the icinga instance is running'
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'instance_remote_port',
|
||||
array(
|
||||
'label' => 'Remote SSH Port',
|
||||
'required' => true,
|
||||
'value' => $this->instance->get('port', 22),
|
||||
'helptext' => 'Enter the ssh port to use for connecting to the remote icigna instance'
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'instance_remote_user',
|
||||
array(
|
||||
'label' => 'Remote SSH User',
|
||||
'value' => $this->instance->user,
|
||||
'helptext' => 'Enter the username to use for connecting '
|
||||
. 'to the remote machine or leave blank for default'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create this form
|
||||
*
|
||||
* @see Icinga\Web\Form::create
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->addTypeSelection();
|
||||
if ($this->getRequest()->getParam('instance_type', $this->instanceType) === 'remote') {
|
||||
$this->addRemoteInstanceForm();
|
||||
}
|
||||
$this->addElement(
|
||||
'text',
|
||||
'instance_path',
|
||||
array(
|
||||
'label' => 'Remote Pipe Filepath',
|
||||
'required' => true,
|
||||
'value' => $this->instance->get('path', '/usr/local/icinga/var/rw/icinga.cmd'),
|
||||
'helptext' => 'The file path where the icinga commandpipe can be found'
|
||||
)
|
||||
);
|
||||
$this->setSubmitLabel('{{SAVE_ICON}} Save');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration set by this form
|
||||
*
|
||||
* @return Zend_Config The configuration set in this form
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
$values = $this->getValues();
|
||||
$config = array(
|
||||
'path' => $values['instance_path']
|
||||
);
|
||||
if ($values['instance_type'] === 'remote') {
|
||||
$config['host'] = $values['instance_remote_host'];
|
||||
$config['port'] = $values['instance_remote_port'];
|
||||
if (isset($values['instance_remote_user']) && $values['instance_remote_user'] != '') {
|
||||
$config['user'] = $values['instance_remote_user'];
|
||||
}
|
||||
}
|
||||
return new Zend_Config($config);
|
||||
}
|
||||
}
|
156
modules/monitoring/application/forms/Config/InstanceForm.php
Normal file
156
modules/monitoring/application/forms/Config/InstanceForm.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Form\Config;
|
||||
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Form\Element\Number;
|
||||
use Icinga\Web\Form\Decorator\HelpText;
|
||||
use Icinga\Web\Form\Decorator\ElementWrapper;
|
||||
|
||||
/**
|
||||
* Form for modifying/creating monitoring instances
|
||||
*/
|
||||
class InstanceForm extends Form
|
||||
{
|
||||
/**
|
||||
* Initialize this form
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('form_config_monitoring_instances');
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$elements = array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'name',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Instance Name')
|
||||
)
|
||||
),
|
||||
$this->createElement(
|
||||
'select',
|
||||
'type',
|
||||
array(
|
||||
'required' => true,
|
||||
'ignore' => true,
|
||||
'label' => t('Instance Type'),
|
||||
'class' => 'autosubmit',
|
||||
'helptext' => t(
|
||||
'When configuring a remote host, you need to setup passwordless key authentication'
|
||||
),
|
||||
'multiOptions' => array(
|
||||
'local' => t('Local Command Pipe'),
|
||||
'remote' => t('Remote Command Pipe')
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (isset($formData['type']) && $formData['type'] === 'remote') {
|
||||
$elements[] = $this->createElement(
|
||||
'text',
|
||||
'host',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Remote Host'),
|
||||
'helptext' => t(
|
||||
'Enter the hostname or address of the machine on which the icinga instance is running'
|
||||
)
|
||||
)
|
||||
);
|
||||
$elements[] = new Number(
|
||||
array(
|
||||
'required' => true,
|
||||
'name' => 'port',
|
||||
'label' => t('Remote SSH Port'),
|
||||
'helptext' => t('Enter the ssh port to use for connecting to the remote icinga instance'),
|
||||
'value' => 22,
|
||||
'decorators' => array( // The order is important!
|
||||
'ViewHelper',
|
||||
'Errors',
|
||||
new ElementWrapper(),
|
||||
new HelpText()
|
||||
)
|
||||
)
|
||||
);
|
||||
$elements[] = $this->createElement(
|
||||
'text',
|
||||
'user',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Remote SSH User'),
|
||||
'helptext' => t(
|
||||
'Enter the username to use for connecting to the remote machine or leave blank for default'
|
||||
)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// TODO(5967,5525): Without this element, switching the type to "local" causes
|
||||
// the form to be processed as it's complete in that case.
|
||||
$elements[] = $this->createElement(
|
||||
'hidden',
|
||||
'hitchhiker',
|
||||
array(
|
||||
'required' => true,
|
||||
'ignore' => true,
|
||||
'value' => 'Arthur'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$elements[] = $this->createElement(
|
||||
'text',
|
||||
'path',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Pipe Filepath'),
|
||||
'value' => '/usr/local/icinga/var/rw/icinga.cmd',
|
||||
'helptext' => t('The file path where the icinga commandpipe can be found')
|
||||
)
|
||||
);
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the instance configuration values and its name
|
||||
*
|
||||
* The first value is the name and the second one the values as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getInstanceConfig()
|
||||
{
|
||||
$values = $this->getValues();
|
||||
$name = $values['name'];
|
||||
unset($values['name']);
|
||||
return array($name, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the form with the given configuration values
|
||||
*
|
||||
* @param string $name The name of the instance
|
||||
* @param array $config The configuration values
|
||||
*/
|
||||
public function setInstanceConfig($name, array $config)
|
||||
{
|
||||
$config['name'] = $name;
|
||||
|
||||
if (isset($config['host'])) {
|
||||
// Necessary as we have no config directive for setting the instance's type
|
||||
$config['type'] = 'remote';
|
||||
}
|
||||
|
||||
$this->populate($config);
|
||||
}
|
||||
}
|
@ -4,57 +4,39 @@
|
||||
|
||||
namespace Icinga\Module\Monitoring\Form\Config;
|
||||
|
||||
use Zend_Config;
|
||||
use Icinga\Web\Form;
|
||||
|
||||
/**
|
||||
* Form for modifying security relevant settings
|
||||
*/
|
||||
class SecurityForm extends Form
|
||||
{
|
||||
/**
|
||||
* The configuration to use for populating the form
|
||||
* Initialize this form
|
||||
*/
|
||||
protected $config;
|
||||
public function init()
|
||||
{
|
||||
$this->setName('form_config_monitoring_security');
|
||||
$this->setSubmitLabel(t('Save Changes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create this form
|
||||
*
|
||||
* @see Icinga\Web\Form::create
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function create()
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$default = '*pw*,*pass*,community';
|
||||
$this->addElement(
|
||||
'text',
|
||||
'protected_customvars',
|
||||
array(
|
||||
'label' => 'Protected Custom Variables',
|
||||
'required' => true,
|
||||
'value' => $this->config ? $this->config->get('protected_customvars', $default) : $default,
|
||||
'helptext' => 'Comma separated case insensitive list of protected custom variables.'
|
||||
. ' Use * as a placeholder for zero or more wildcard characters.'
|
||||
. ' Existance of those custom variables will be shown, but their values will be masked.'
|
||||
return array(
|
||||
$this->createElement(
|
||||
'text',
|
||||
'protected_customvars',
|
||||
array(
|
||||
'label' => 'Protected Custom Variables',
|
||||
'required' => true,
|
||||
'helptext' => 'Comma separated case insensitive list of protected custom variables.'
|
||||
. ' Use * as a placeholder for zero or more wildcard characters.'
|
||||
. ' Existance of those custom variables will be shown, but their values will be masked.'
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->setSubmitLabel('Save');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configuration to be used for initial population of the form
|
||||
*/
|
||||
public function setConfiguration($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration set by this form
|
||||
*
|
||||
* @return Zend_Config The configuration set in this form
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
$values = $this->getValues();
|
||||
return new Zend_Config(array(
|
||||
'protected_customvars' => $values['protected_customvars']
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
<h4><?= $this->translate('Add New Backend'); ?></h4>
|
||||
<?= $form; ?>
|
@ -0,0 +1,2 @@
|
||||
<h4><?= $this->translate('Add New Instance'); ?></h4>
|
||||
<?= $form; ?>
|
@ -1,13 +1,2 @@
|
||||
<?php if ($this->name): ?>
|
||||
<h4><i> <i class="icinga-icon-edit"></i> Edit Backend "<?= $this->escape($this->name) ?>"</h4>
|
||||
<?php else: ?>
|
||||
<h4> <i class="icinga-icon-create"></i> Create New Backend</h4>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($this->error): ?>
|
||||
<div class="alert alert-danger">
|
||||
<?= $this->escape($this->error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?= $this->form; ?>
|
||||
<h4><?= $this->translate('Edit Existing Backend'); ?></h4>
|
||||
<?= $form; ?>
|
@ -1,14 +1,2 @@
|
||||
|
||||
<?php if (isset($this->name)): ?>
|
||||
<h4><i class="icinga-icon-edit"></i> } Edit Instance Configuration for "<?= $this->escape($this->name) ?>"</h4>
|
||||
<?php else: ?>
|
||||
<h4><i class="icinga-icon-create"></i> Configure New Icinga Instance</h4>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($this->error): ?>
|
||||
<div class="alert alert-danger">
|
||||
<?= $this->escape($this->error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?= $this->form; ?>
|
||||
<h4><?= $this->translate('Edit Existing Instance'); ?></h4>
|
||||
<?= $form; ?>
|
@ -1,8 +1,2 @@
|
||||
|
||||
<h4><i class="icinga-icon-remove"></i> Remove Backend "<?= $this->escape($this->name) ?>"</h4>
|
||||
|
||||
<p>
|
||||
Are you sure you want to remove the backend <?= $this->escape($this->name) ?>?
|
||||
</p>
|
||||
|
||||
<?= $this->form; ?>
|
||||
<h4><?= $this->translate('Remove Existing Backend'); ?></h4>
|
||||
<?= $form; ?>
|
@ -1,13 +1,4 @@
|
||||
|
||||
<h4><i class="icinga-icon-remove"></i> Remove Instance "<?= $this->escape($this->name) ?>"</h4>
|
||||
|
||||
<p>
|
||||
Are you sure you want to remove the instance <?= $this->escape($this->name) ?>?
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<i class="icinga-icon-warning"></i> If you have still any environments or views refering to this instance, you won't be able to send commands anymore
|
||||
after deletion.
|
||||
</p>
|
||||
|
||||
<?= $this->form; ?>
|
||||
<h4><?= $this->translate('Remove Existing Instance'); ?></h4>
|
||||
<p>Are you sure you want to remove the instance <?= $this->escape($name); ?>?</p>
|
||||
<p><i class="icinga-icon-warning"></i> If you have still any environments or views referring to this instance, you won't be able to send commands anymore after deletion.</p>
|
||||
<?= $form; ?>
|
@ -97,7 +97,6 @@ class TimelineIntervalBox extends AbstractWidget
|
||||
);
|
||||
|
||||
if ($this->request) {
|
||||
$form->setAction($this->request->getRequestUri());
|
||||
$form->populate($this->request->getParams());
|
||||
}
|
||||
|
||||
|
@ -17,11 +17,7 @@ td.configTable {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
div.config-form-group {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
.form-element {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user