diff --git a/library/Icinga/Authentication/User/UserBackend.php b/library/Icinga/Authentication/User/UserBackend.php
index 63b5bbcd7..3b8e21071 100644
--- a/library/Icinga/Authentication/User/UserBackend.php
+++ b/library/Icinga/Authentication/User/UserBackend.php
@@ -207,12 +207,7 @@ class UserBackend implements ConfigAwareFactory
);
}
- if ($backendConfig->resource instanceof ConfigObject) {
- $resource = ResourceFactory::createResource($backendConfig->resource);
- } else {
- $resource = ResourceFactory::create($backendConfig->resource);
- }
-
+ $resource = ResourceFactory::create($backendConfig->resource);
switch ($backendType) {
case 'db':
$backend = new DbUserBackend($resource);
diff --git a/modules/monitoring/application/forms/Setup/IdoResourcePage.php b/modules/monitoring/application/forms/Setup/IdoResourcePage.php
index ea244d057..e0b74c3ac 100644
--- a/modules/monitoring/application/forms/Setup/IdoResourcePage.php
+++ b/modules/monitoring/application/forms/Setup/IdoResourcePage.php
@@ -21,6 +21,7 @@ class IdoResourcePage extends Form
$this->addDescription($this->translate(
'Please fill out the connection details below to access the IDO database of your monitoring environment.'
));
+ $this->setValidatePartial(true);
}
/**
@@ -96,6 +97,52 @@ class IdoResourcePage extends Form
return true;
}
+ /**
+ * Run the configured backend's inspection checks and show the result, if necessary
+ *
+ * This will only run any validation if the user pushed the 'backend_validation' button.
+ *
+ * @param array $formData
+ *
+ * @return bool
+ */
+ public function isValidPartial(array $formData)
+ {
+ if (isset($formData['backend_validation']) && parent::isValid($formData)) {
+ $inspection = ResourceConfigForm::inspectResource($this);
+ if ($inspection !== null) {
+ $join = function ($e) use (& $join) {
+ return is_string($e) ? $e : join("\n", array_map($join, $e));
+ };
+ $this->addElement(
+ 'note',
+ 'inspection_output',
+ array(
+ 'order' => 0,
+ 'value' => '' . $this->translate('Validation Log') . "\n\n"
+ . join("\n", array_map($join, $inspection->toArray())),
+ 'decorators' => array(
+ 'ViewHelper',
+ array('HtmlTag', array('tag' => 'pre', 'class' => 'log-output')),
+ )
+ )
+ );
+
+ if ($inspection->hasError()) {
+ $this->warning(sprintf(
+ $this->translate('Failed to successfully validate the configuration: %s'),
+ $inspection->getError()
+ ));
+ return false;
+ }
+ }
+
+ $this->info($this->translate('The configuration has been successfully validated.'));
+ }
+
+ return true;
+ }
+
/**
* Add a checkbox to the form by which the user can skip the resource validation
*
diff --git a/modules/monitoring/library/Monitoring/MonitoringWizard.php b/modules/monitoring/library/Monitoring/MonitoringWizard.php
index b91129d10..0a224610c 100644
--- a/modules/monitoring/library/Monitoring/MonitoringWizard.php
+++ b/modules/monitoring/library/Monitoring/MonitoringWizard.php
@@ -114,6 +114,19 @@ class MonitoringWizard extends Wizard implements SetupWizard
mt('monitoring', 'Setup the monitoring module for Icinga Web 2', 'setup.summary.btn.finish')
);
}
+
+ if ($page->getName() === 'setup_monitoring_ido') {
+ $page->addElement(
+ 'submit',
+ 'backend_validation',
+ array(
+ 'ignore' => true,
+ 'label' => t('Validate Configuration'),
+ 'decorators' => array('ViewHelper')
+ )
+ );
+ $page->getDisplayGroup('buttons')->addElement($page->getElement('backend_validation'));
+ }
}
/**
diff --git a/modules/setup/application/forms/AuthBackendPage.php b/modules/setup/application/forms/AuthBackendPage.php
index c9116fbb5..dfd185a70 100644
--- a/modules/setup/application/forms/AuthBackendPage.php
+++ b/modules/setup/application/forms/AuthBackendPage.php
@@ -3,7 +3,8 @@
namespace Icinga\Module\Setup\Forms;
-use Icinga\Data\ConfigObject;
+use Icinga\Application\Config;
+use Icinga\Data\ResourceFactory;
use Icinga\Forms\Config\UserBackendConfigForm;
use Icinga\Forms\Config\UserBackend\DbBackendForm;
use Icinga\Forms\Config\UserBackend\LdapBackendForm;
@@ -29,6 +30,7 @@ class AuthBackendPage extends Form
{
$this->setName('setup_authentication_backend');
$this->setTitle($this->translate('Authentication Backend', 'setup.page.title'));
+ $this->setValidatePartial(true);
}
/**
@@ -40,22 +42,18 @@ class AuthBackendPage extends Form
*/
public function setResourceConfig(array $config)
{
+ $resourceConfig = new Config();
+ $resourceConfig->setSection($config['name'], $config);
+ ResourceFactory::setConfig($resourceConfig);
+
$this->config = $config;
return $this;
}
/**
- * Return the resource configuration as Config object
+ * Create and add elements to this form
*
- * @return ConfigObject
- */
- public function getResourceConfig()
- {
- return new ConfigObject($this->config);
- }
-
- /**
- * @see Form::createElements()
+ * @param array $formData
*/
public function createElements(array $formData)
{
@@ -74,7 +72,9 @@ class AuthBackendPage extends Form
));
} elseif ($this->config['type'] === 'ldap') {
$backendForm = new LdapBackendForm();
- $backendForm->create($formData)->removeElement('resource');
+ $backendForm->setResources(array($this->config['name']));
+ $backendForm->create($formData);
+ $backendForm->getElement('resource')->setIgnore(true);
$this->addDescription($this->translate(
'Before you are able to authenticate using the LDAP connection defined earlier you need to'
. ' provide some more information so that Icinga Web 2 is able to locate account details.'
@@ -140,13 +140,7 @@ class AuthBackendPage extends Form
if ($this->config['type'] === 'ldap' && (! isset($data['skip_validation']) || $data['skip_validation'] == 0)) {
$self = clone $this;
- $self->addElement(
- 'text',
- 'resource',
- array(
- 'value' => $this->getResourceConfig()
- )
- );
+ $self->getSubForm('backend_form')->getElement('resource')->setIgnore(false);
$inspection = UserBackendConfigForm::inspectUserBackend($self);
if ($inspection && $inspection->hasError()) {
$this->error($inspection->getError());
@@ -158,6 +152,54 @@ class AuthBackendPage extends Form
return true;
}
+ /**
+ * Run the configured backend's inspection checks and show the result, if necessary
+ *
+ * This will only run any validation if the user pushed the 'backend_validation' button.
+ *
+ * @param array $formData
+ *
+ * @return bool
+ */
+ public function isValidPartial(array $formData)
+ {
+ if (isset($formData['backend_validation']) && parent::isValid($formData)) {
+ $self = clone $this;
+ $self->getSubForm('backend_form')->getElement('resource')->setIgnore(false);
+ $inspection = UserBackendConfigForm::inspectUserBackend($self);
+ if ($inspection !== null) {
+ $join = function ($e) use (& $join) {
+ return is_string($e) ? $e : join("\n", array_map($join, $e));
+ };
+ $this->addElement(
+ 'note',
+ 'inspection_output',
+ array(
+ 'order' => 0,
+ 'value' => '' . $this->translate('Validation Log') . "\n\n"
+ . join("\n", array_map($join, $inspection->toArray())),
+ 'decorators' => array(
+ 'ViewHelper',
+ array('HtmlTag', array('tag' => 'pre', 'class' => 'log-output')),
+ )
+ )
+ );
+
+ if ($inspection->hasError()) {
+ $this->warning(sprintf(
+ $this->translate('Failed to successfully validate the configuration: %s'),
+ $inspection->getError()
+ ));
+ return false;
+ }
+ }
+
+ $this->info($this->translate('The configuration has been successfully validated.'));
+ }
+
+ return true;
+ }
+
/**
* Add a checkbox to this form by which the user can skip the authentication validation
*/
diff --git a/modules/setup/application/forms/DbResourcePage.php b/modules/setup/application/forms/DbResourcePage.php
index e9967f350..a0faf932d 100644
--- a/modules/setup/application/forms/DbResourcePage.php
+++ b/modules/setup/application/forms/DbResourcePage.php
@@ -23,6 +23,7 @@ class DbResourcePage extends Form
'Now please configure your database resource. Note that the database itself does not need to'
. ' exist at this time as it is going to be created once the wizard is about to be finished.'
));
+ $this->setValidatePartial(true);
}
/**
@@ -84,6 +85,35 @@ class DbResourcePage extends Form
return true;
}
+ /**
+ * Check whether it's possible to connect to the database server
+ *
+ * This will only run the check if the user pushed the 'backend_validation' button.
+ *
+ * @param array $formData
+ *
+ * @return bool
+ */
+ public function isValidPartial(array $formData)
+ {
+ if (isset($formData['backend_validation']) && parent::isValid($formData)) {
+ try {
+ $db = new DbTool($this->getValues());
+ $db->checkConnectivity();
+ } catch (PDOException $e) {
+ $this->warning(sprintf(
+ $this->translate('Failed to successfully validate the configuration: %s'),
+ $e->getMessage()
+ ));
+ return false;
+ }
+
+ $this->info($this->translate('The configuration has been successfully validated.'));
+ }
+
+ return true;
+ }
+
/**
* Add a checkbox to the form by which the user can skip the connection validation
*/
diff --git a/modules/setup/application/forms/LdapResourcePage.php b/modules/setup/application/forms/LdapResourcePage.php
index 316b66f31..2c558dfbb 100644
--- a/modules/setup/application/forms/LdapResourcePage.php
+++ b/modules/setup/application/forms/LdapResourcePage.php
@@ -23,6 +23,7 @@ class LdapResourcePage extends Form
'Now please configure your AD/LDAP resource. This will later '
. 'be used to authenticate users logging in to Icinga Web 2.'
));
+ $this->setValidatePartial(true);
}
/**
@@ -82,6 +83,52 @@ class LdapResourcePage extends Form
return true;
}
+ /**
+ * Run the configured backend's inspection checks and show the result, if necessary
+ *
+ * This will only run any validation if the user pushed the 'backend_validation' button.
+ *
+ * @param array $formData
+ *
+ * @return bool
+ */
+ public function isValidPartial(array $formData)
+ {
+ if (isset($formData['backend_validation']) && parent::isValid($formData)) {
+ $inspection = ResourceConfigForm::inspectResource($this);
+ if ($inspection !== null) {
+ $join = function ($e) use (& $join) {
+ return is_string($e) ? $e : join("\n", array_map($join, $e));
+ };
+ $this->addElement(
+ 'note',
+ 'inspection_output',
+ array(
+ 'order' => 0,
+ 'value' => '' . $this->translate('Validation Log') . "\n\n"
+ . join("\n", array_map($join, $inspection->toArray())),
+ 'decorators' => array(
+ 'ViewHelper',
+ array('HtmlTag', array('tag' => 'pre', 'class' => 'log-output')),
+ )
+ )
+ );
+
+ if ($inspection->hasError()) {
+ $this->warning(sprintf(
+ $this->translate('Failed to successfully validate the configuration: %s'),
+ $inspection->getError()
+ ));
+ return false;
+ }
+ }
+
+ $this->info($this->translate('The configuration has been successfully validated.'));
+ }
+
+ return true;
+ }
+
/**
* Add a checkbox to the form by which the user can skip the connection validation
*/
diff --git a/modules/setup/library/Setup/WebWizard.php b/modules/setup/library/Setup/WebWizard.php
index 6c73a933f..72faa801a 100644
--- a/modules/setup/library/Setup/WebWizard.php
+++ b/modules/setup/library/Setup/WebWizard.php
@@ -320,6 +320,27 @@ class WebWizard extends Wizard implements SetupWizard
} elseif ($index === count($pages) - 1) {
$page->getElement(static::BTN_NEXT)->setLabel(mt('setup', 'Setup Icinga Web 2', 'setup.summary.btn.finish'));
}
+
+ $authData = $this->getPageData('setup_authentication_type');
+ $veto = $page->getName() === 'setup_authentication_backend' && $authData['type'] === 'db';
+ if (! $veto && in_array($page->getName(), array(
+ 'setup_authentication_backend',
+ 'setup_auth_db_resource',
+ 'setup_config_db_resource',
+ 'setup_ldap_resource',
+ 'setup_monitoring_ido'
+ ))) {
+ $page->addElement(
+ 'submit',
+ 'backend_validation',
+ array(
+ 'ignore' => true,
+ 'label' => t('Validate Configuration'),
+ 'decorators' => array('ViewHelper')
+ )
+ );
+ $page->getDisplayGroup('buttons')->addElement($page->getElement('backend_validation'));
+ }
}
/**
diff --git a/public/js/icinga/behavior/actiontable.js b/public/js/icinga/behavior/actiontable.js
index d3df54614..3f1cf1f9e 100644
--- a/public/js/icinga/behavior/actiontable.js
+++ b/public/js/icinga/behavior/actiontable.js
@@ -43,7 +43,7 @@
* Handle the selection of an action table
*
* @param table {HTMLElement} The table
- * @param {Icinga}
+ * @param icinga {Icinga}
*
* @constructor
*/
@@ -158,7 +158,6 @@
return;
}
var self = this;
- var url = this.getMultiselectionUrl();
this.rowActions()
.filter(
function (i, el) {
@@ -283,14 +282,7 @@
var ActionTable = function (icinga) {
Icinga.EventListener.call(this, icinga);
-
- /**
- * The hash that is currently being loaded
- *
- * @var String
- */
- this.loadingHash = null;
-
+
/**
* If currently loading
*
@@ -364,7 +356,7 @@
}
self.icinga.history.pushUrl(state);
- // re draw all table selections
+ // redraw all table selections
self.tables().each(function () {
new Selection(this, self.icinga).refresh();
});
@@ -375,22 +367,46 @@
};
/**
- * Ensure that
+ * Render the selection and prepare selection rows
*/
ActionTable.prototype.onRendered = function(evt) {
var container = evt.target;
var self = evt.data.self;
- // draw all selections
+ // initialize all rows with the correct link
+ $('table.action tr', container).each(function(idx, el) {
+ // IE will not ignore user-select unless we cancel selectstart
+ $(el).on('selectstart', false);
+
+ var $a = $('a[href].rowaction', el).first();
+ if ($a.length) {
+ // TODO: Find out whether we leak memory on IE with this:
+ $(el).attr('href', $a.attr('href'));
+ return;
+ }
+ $a = $('a[href]', el).first();
+ if ($a.length) {
+ $(el).attr('href', $a.attr('href'));
+ }
+ });
+
+ // draw all active selections that have disappeared on reload
self.tables().each(function(i, el) {
new Selection(el, self.icinga).refresh();
});
- // update displayed selection count
+ // update displayed selection counter
var table = new Selection(self.tables(container).first());
$(container).find('.selection-info-count').text(table.selections().size());
};
+ ActionTable.prototype.clearAll = function () {
+ var self = this;
+ this.tables().each(function () {
+ new Selection(this, self.icinga).clear();
+ });
+ };
+
Icinga.Behaviors.ActionTable = ActionTable;
}) (Icinga, jQuery);
diff --git a/public/js/icinga/events.js b/public/js/icinga/events.js
index 000ecf103..3ea40b3d7 100644
--- a/public/js/icinga/events.js
+++ b/public/js/icinga/events.js
@@ -40,20 +40,6 @@
icinga.loader.loadUrl(url, $(el)).autorefresh = true;
});
- // Set first links href in a action table tr as row href:
- $('table.action tr', el).each(function(idx, el) {
- var $a = $('a[href].rowaction', el).first();
- if ($a.length) {
- // TODO: Find out whether we leak memory on IE with this:
- $(el).attr('href', $a.attr('href'));
- return;
- }
- $a = $('a[href]', el).first();
- if ($a.length) {
- $(el).attr('href', $a.attr('href'));
- }
- });
-
$('td.state span.timesince').attr('title', null);
var moduleName = el.data('icingaModule');
@@ -441,7 +427,6 @@
} else {
icinga.ui.layout1col();
}
- $('table tr[href].active').removeClass('active');
icinga.history.pushCurrentState();
}
}
diff --git a/public/js/icinga/ui.js b/public/js/icinga/ui.js
index d2f9ab138..4ab802ca7 100644
--- a/public/js/icinga/ui.js
+++ b/public/js/icinga/ui.js
@@ -241,6 +241,9 @@
$('#layout').removeClass('twocols');
this.closeContainer($('#col2'));
this.disableCloseButtons();
+
+ // one-column layouts never have any selection active
+ this.icinga.behaviors.actiontable.clearAll();
},
closeContainer: function($c) {