Merge branch 'bugfix/improve-setup-wizard-experience-8709'

fixes #8709
This commit is contained in:
Johannes Meyer 2015-07-02 11:28:07 +02:00
commit 179a22266e
16 changed files with 330 additions and 238 deletions

View File

@ -6,6 +6,7 @@ use Icinga\Web\Url;
use Icinga\Web\Widget\Tab; use Icinga\Web\Widget\Tab;
use Icinga\Application\Config; use Icinga\Application\Config;
use Icinga\Forms\PreferenceForm; use Icinga\Forms\PreferenceForm;
use Icinga\Data\ConfigObject;
use Icinga\User\Preferences\PreferencesStore; use Icinga\User\Preferences\PreferencesStore;
/** /**
@ -38,13 +39,16 @@ class PreferenceController extends BasePreferenceController
*/ */
public function indexAction() public function indexAction()
{ {
$storeConfig = Config::app()->getSection('preferences'); $config = Config::app()->getSection('global');
$user = $this->getRequest()->getUser(); $user = $this->getRequest()->getUser();
$form = new PreferenceForm(); $form = new PreferenceForm();
$form->setPreferences($user->getPreferences()); $form->setPreferences($user->getPreferences());
if ($storeConfig->get('store', 'ini') !== 'none') { if ($config->get('config_backend', 'ini') !== 'none') {
$form->setStore(PreferencesStore::create($storeConfig, $user)); $form->setStore(PreferencesStore::create(new ConfigObject(array(
'store' => $config->get('config_backend', 'ini'),
'resource' => $config->config_resource
)), $user));
} }
$form->handleRequest(); $form->handleRequest();

View File

@ -7,7 +7,6 @@ use Icinga\Application\Icinga;
use Icinga\Data\ResourceFactory; use Icinga\Data\ResourceFactory;
use Icinga\Web\Form; use Icinga\Web\Form;
/** /**
* Form class to modify the general application configuration * Form class to modify the general application configuration
*/ */
@ -43,7 +42,7 @@ class ApplicationConfigForm extends Form
$this->addElement( $this->addElement(
'select', 'select',
'preferences_store', 'global_config_backend',
array( array(
'required' => true, 'required' => true,
'autosubmit' => true, 'autosubmit' => true,
@ -55,7 +54,7 @@ class ApplicationConfigForm extends Form
) )
) )
); );
if (isset($formData['preferences_store']) && $formData['preferences_store'] === 'db') { if (isset($formData['global_config_backend']) && $formData['global_config_backend'] === 'db') {
$backends = array(); $backends = array();
foreach (ResourceFactory::getResourceConfigs()->toArray() as $name => $resource) { foreach (ResourceFactory::getResourceConfigs()->toArray() as $name => $resource) {
if ($resource['type'] === 'db') { if ($resource['type'] === 'db') {
@ -65,7 +64,7 @@ class ApplicationConfigForm extends Form
$this->addElement( $this->addElement(
'select', 'select',
'preferences_resource', 'global_config_resource',
array( array(
'required' => true, 'required' => true,
'multiOptions' => $backends, 'multiOptions' => $backends,

View File

@ -6,6 +6,7 @@ namespace Icinga\Authentication;
use Exception; use Exception;
use Icinga\Authentication\UserGroup\UserGroupBackend; use Icinga\Authentication\UserGroup\UserGroupBackend;
use Icinga\Application\Config; use Icinga\Application\Config;
use Icinga\Data\ConfigObject;
use Icinga\Exception\IcingaException; use Icinga\Exception\IcingaException;
use Icinga\Exception\NotReadableError; use Icinga\Exception\NotReadableError;
use Icinga\Application\Logger; use Icinga\Application\Logger;
@ -63,8 +64,11 @@ class Manager
); );
$config = new Config(); $config = new Config();
} }
if ($config->get('preferences', 'store', 'ini') !== 'none') { if ($config->get('global', 'config_backend', 'ini') !== 'none') {
$preferencesConfig = $config->getSection('preferences'); $preferencesConfig = new ConfigObject(array(
'store' => $config->get('global', 'config_backend', 'ini'),
'resource' => $config->get('global', 'config_resource')
));
try { try {
$preferencesStore = PreferencesStore::create( $preferencesStore = PreferencesStore::create(
$preferencesConfig, $preferencesConfig,

View File

@ -39,26 +39,19 @@ class Form extends Zend_Form
const DEFAULT_SUFFIX = '_default'; const DEFAULT_SUFFIX = '_default';
/** /**
* The type of the notification for the error * Identifier for notifications of type error
*/ */
const NOTIFICATION_ERROR = 0; const NOTIFICATION_ERROR = 0;
/** /**
* The type of the notification for the warning * Identifier for notifications of type warning
*/ */
const NOTIFICATION_WARNING = 2; const NOTIFICATION_WARNING = 1;
/** /**
* The type of the notification for the info * Identifier for notifications of type info
*/ */
const NOTIFICATION_INFO = 4; const NOTIFICATION_INFO = 2;
/**
* The notifications of the form
*
* @var array
*/
protected $notifications = array();
/** /**
* Whether this form has been created * Whether this form has been created
@ -160,6 +153,13 @@ class Form extends Zend_Form
*/ */
protected $descriptions; protected $descriptions;
/**
* The notifications of this form
*
* @var array
*/
protected $notifications;
/** /**
* Whether the Autosubmit decorator should be applied to this form * Whether the Autosubmit decorator should be applied to this form
* *
@ -522,6 +522,50 @@ class Form extends Zend_Form
return $this->descriptions; return $this->descriptions;
} }
/**
* Set the notifications for this form
*
* @param array $notifications
*
* @return $this
*/
public function setNotifications(array $notifications)
{
$this->notifications = $notifications;
return $this;
}
/**
* Add a notification for this form
*
* If $notification is an array the second value should be
* an array as well containing additional HTML properties.
*
* @param string|array $notification
* @param int $type
*
* @return $this
*/
public function addNotification($notification, $type)
{
$this->notifications[$type][] = $notification;
return $this;
}
/**
* Return the notifications of this form
*
* @return array
*/
public function getNotifications()
{
if ($this->notifications === null) {
return array();
}
return $this->notifications;
}
/** /**
* Set whether the Autosubmit decorator should be applied to this form * Set whether the Autosubmit decorator should be applied to this form
* *
@ -1264,55 +1308,48 @@ class Form extends Zend_Form
} }
/** /**
* Return all form notifications * Add a error notification and prevent the form from being successfully validated
* *
* @return array * @param string|array $message The notfication's message
*/
public function getNotifications()
{
return $this->notifications;
}
/**
* Add a typed message to the notifications
* *
* @param string $message The message which would be displayed to the user * @return $this
*
* @param int $type The type of the message notification
*/
public function addNotification($message, $type = self::NOTIFICATION_ERROR)
{
$this->notifications[$message] = $type;
$this->markAsError();
}
/**
* Add a error message to notifications
*
* @param string $message
*/ */
public function error($message) public function error($message)
{ {
$this->addNotification($message, $type = self::NOTIFICATION_ERROR); $this->addNotification($message, self::NOTIFICATION_ERROR);
$this->markAsError();
return $this;
} }
/** /**
* Add a warning message to notifications * Add a warning notification and prevent the form from being successfully validated
* *
* @param string $message * @param string|array $message The notfication's message
*
* @return $this
*/ */
public function warning($message) public function warning($message)
{ {
$this->addNotification($message, $type = self::NOTIFICATION_WARNING); $this->addNotification($message, self::NOTIFICATION_WARNING);
$this->markAsError();
return $this;
} }
/** /**
* Add a info message to notifications * Add a info notification
* *
* @param string $message * @param string|array $message The notfication's message
* @param bool $markAsError Whether to prevent the form from being successfully validated or not
*
* @return $this
*/ */
public function info($message) public function info($message, $markAsError = true)
{ {
$this->addNotification($message, $type = self::NOTIFICATION_INFO); $this->addNotification($message, self::NOTIFICATION_INFO);
if ($markAsError) {
$this->markAsError();
}
return $this;
} }
} }

View File

@ -4,15 +4,16 @@
namespace Icinga\Web\Form\Decorator; namespace Icinga\Web\Form\Decorator;
use Zend_Form_Decorator_Abstract; use Zend_Form_Decorator_Abstract;
use Icinga\Web\Form as Form; use Icinga\Exception\ProgrammingError;
use Icinga\Web\Form;
/** /**
* Decorator to add a list of notifications at the top of a form * Decorator to add a list of notifications at the top or bottom of a form
*/ */
class FormNotifications extends Zend_Form_Decorator_Abstract class FormNotifications extends Zend_Form_Decorator_Abstract
{ {
/** /**
* Render form descriptions * Render form notifications
* *
* @param string $content The html rendered so far * @param string $content The html rendered so far
* *
@ -31,16 +32,27 @@ class FormNotifications extends Zend_Form_Decorator_Abstract
} }
$notifications = $this->recurseForm($form); $notifications = $this->recurseForm($form);
if (empty($notifications)) { if (empty($notifications)) {
return $content; return $content;
} }
$html = '<ul class="form-notifications">'; $html = '<ul class="form-notifications">';
foreach (array(Form::NOTIFICATION_ERROR, Form::NOTIFICATION_WARNING, Form::NOTIFICATION_INFO) as $type) {
if (isset($notifications[$type])) {
$html .= '<li><ul class="' . $this->getNotificationTypeName($type) . '">';
foreach ($notifications[$type] as $message) {
if (is_array($message)) {
list($message, $properties) = $message;
$html .= '<li' . $view->propertiesToString($properties) . '>'
. $view->escape($message)
. '</li>';
} else {
$html .= '<li>' . $view->escape($message) . '</li>';
}
}
asort($notifications); $html .= '</ul></li>';
foreach ($notifications as $message => $type) { }
$html .= '<li class="'.self::getNotificationTypeName($type).'">' . $view->escape($message) . '</li>';
} }
switch ($this->getPlacement()) { switch ($this->getPlacement()) {
@ -54,42 +66,44 @@ class FormNotifications extends Zend_Form_Decorator_Abstract
/** /**
* Recurse the given form and return the notifications for it and all of its subforms * Recurse the given form and return the notifications for it and all of its subforms
* *
* @param Form $form The form to recurse * @param Form $form The form to recurse
* *
* @return array * @return array
*/ */
protected function recurseForm(Form $form) protected function recurseForm(Form $form)
{ {
$notifications = $form->getNotifications(); $notifications = $form->getNotifications();
foreach ($form->getSubForms() as $subForm) { foreach ($form->getSubForms() as $subForm) {
$notifications = $notifications + $this->recurseForm($subForm); foreach ($this->recurseForm($subForm) as $type => $messages) {
foreach ($messages as $message) {
$notifications[$type][] = $message;
}
}
} }
return $notifications; return $notifications;
} }
/** /**
* Get the readable type name of the notification * Return the name for the given notification type
* *
* @param $type Type of the message * @param int $type
* *
* @return string * @return string
*
* @throws ProgrammingError In case the given type is invalid
*/ */
public static function getNotificationTypeName($type) protected function getNotificationTypeName($type)
{ {
switch ($type) { switch ($type) {
case Form::NOTIFICATION_ERROR: case Form::NOTIFICATION_ERROR:
return 'error'; return 'error';
break;
case Form::NOTIFICATION_WARNING: case Form::NOTIFICATION_WARNING:
return 'warning'; return 'warning';
break;
case Form::NOTIFICATION_INFO: case Form::NOTIFICATION_INFO:
return 'info'; return 'info';
break;
default: default:
return 'unknown'; throw new ProgrammingError('Invalid notification type "%s" provided', $type);
} }
} }
} }

View File

@ -25,7 +25,7 @@ use Icinga\Module\Setup\Requirement\PhpModuleRequirement;
class MonitoringWizard extends Wizard implements SetupWizard class MonitoringWizard extends Wizard implements SetupWizard
{ {
/** /**
* @see Wizard::init() * Register all pages for this wizard
*/ */
public function init() public function init()
{ {
@ -39,7 +39,10 @@ class MonitoringWizard extends Wizard implements SetupWizard
} }
/** /**
* @see Wizard::setupPage() * Setup the given page that is either going to be displayed or validated
*
* @param Form $page The page to setup
* @param Request $request The current request
*/ */
public function setupPage(Form $page, Request $request) public function setupPage(Form $page, Request $request)
{ {
@ -52,18 +55,30 @@ class MonitoringWizard extends Wizard implements SetupWizard
$this->getDirection() === static::FORWARD $this->getDirection() === static::FORWARD
&& ($page->getName() === 'setup_monitoring_ido' || $page->getName() === 'setup_monitoring_livestatus') && ($page->getName() === 'setup_monitoring_ido' || $page->getName() === 'setup_monitoring_livestatus')
) { ) {
if ((($dbResourceData = $this->getPageData('setup_db_resource')) !== null if (
&& $dbResourceData['name'] === $request->getPost('name')) (($authDbResourceData = $this->getPageData('setup_auth_db_resource')) !== null
|| (($ldapResourceData = $this->getPageData('setup_ldap_resource')) !== null && $authDbResourceData['name'] === $request->getPost('name'))
&& $ldapResourceData['name'] === $request->getPost('name')) || (($configDbResourceData = $this->getPageData('setup_config_db_resource')) !== null
&& $configDbResourceData['name'] === $request->getPost('name'))
|| (($ldapResourceData = $this->getPageData('setup_ldap_resource')) !== null
&& $ldapResourceData['name'] === $request->getPost('name'))
) { ) {
$page->addError(mt('monitoring', 'The given resource name is already in use.')); $page->error(mt('monitoring', 'The given resource name is already in use.'));
} }
} }
} }
/** /**
* @see Wizard::getNewPage() * Return the new page to set as current page
*
* {@inheritdoc} Runs additional checks related to some registered pages.
*
* @param string $requestedPage The name of the requested page
* @param Form $originPage The origin page
*
* @return Form The new page
*
* @throws InvalidArgumentException In case the requested page does not exist or is not permitted yet
*/ */
protected function getNewPage($requestedPage, Form $originPage) protected function getNewPage($requestedPage, Form $originPage)
{ {
@ -81,7 +96,9 @@ class MonitoringWizard extends Wizard implements SetupWizard
} }
/** /**
* @see Wizard::addButtons() * Add buttons to the given page based on its position in the page-chain
*
* @param Form $page The page to add the buttons to
*/ */
protected function addButtons(Form $page) protected function addButtons(Form $page)
{ {
@ -100,7 +117,9 @@ class MonitoringWizard extends Wizard implements SetupWizard
} }
/** /**
* @see SetupWizard::getSetup() * Return the setup for this wizard
*
* @return Setup
*/ */
public function getSetup() public function getSetup()
{ {
@ -132,7 +151,9 @@ class MonitoringWizard extends Wizard implements SetupWizard
} }
/** /**
* @see SetupWizard::getRequirements() * Return the requirements of this wizard
*
* @return RequirementSet
*/ */
public function getRequirements() public function getRequirements()
{ {

View File

@ -202,7 +202,7 @@ class AdminAccountPage extends Form
return false; return false;
} }
if ($data['user_type'] === 'new_user' && !$this->hasUser($data['new_user'])) { if ($data['user_type'] === 'new_user' && $this->hasUser($data['new_user'])) {
$this->getElement('new_user')->addError($this->translate('Username already exists.')); $this->getElement('new_user')->addError($this->translate('Username already exists.'));
return false; return false;
} }
@ -255,7 +255,11 @@ class AdminAccountPage extends Form
*/ */
protected function hasUser($username) protected function hasUser($username)
{ {
return $this->createBackend()->select()->where('user_name', $username)->count() > 1; try {
return $this->createBackend()->select()->where('user_name', $username)->count() > 1;
} catch (Exception $_) {
return null;
}
} }
/** /**

View File

@ -121,7 +121,7 @@ class AuthBackendPage extends Form
return false; return false;
} }
if (false === isset($data['skip_validation']) || $data['skip_validation'] == 0) { if ($this->config['type'] === 'ldap' && ( !isset($data['skip_validation']) || $data['skip_validation'] == 0)) {
$self = clone $this; $self = clone $this;
$self->addElement( $self->addElement(
'text', 'text',
@ -130,7 +130,7 @@ class AuthBackendPage extends Form
'value' => $this->getResourceConfig() 'value' => $this->getResourceConfig()
) )
); );
if ($this->config['type'] === 'ldap' && false === LdapBackendForm::isValidUserBackend($self)) { if (! LdapBackendForm::isValidUserBackend($self)) {
$this->addSkipValidationCheckbox(); $this->addSkipValidationCheckbox();
return false; return false;
} }

View File

@ -38,7 +38,6 @@ class DatabaseCreationPage extends Form
*/ */
public function init() public function init()
{ {
$this->setName('setup_database_creation');
$this->setTitle($this->translate('Database Setup', 'setup.page.title')); $this->setTitle($this->translate('Database Setup', 'setup.page.title'));
$this->addDescription($this->translate( $this->addDescription($this->translate(
'It seems that either the database you defined earlier does not yet exist and cannot be created' 'It seems that either the database you defined earlier does not yet exist and cannot be created'
@ -156,7 +155,7 @@ class DatabaseCreationPage extends Form
$db->connectToHost(); // Are we able to login on the server? $db->connectToHost(); // Are we able to login on the server?
} catch (PDOException $e) { } catch (PDOException $e) {
// We are NOT able to login on the server.. // We are NOT able to login on the server..
$this->addError($e->getMessage()); $this->error($e->getMessage());
$this->addSkipValidationCheckbox(); $this->addSkipValidationCheckbox();
return false; return false;
} }
@ -165,7 +164,7 @@ class DatabaseCreationPage extends Form
// In case we are connected the credentials filled into this // In case we are connected the credentials filled into this
// form need to be granted to create databases, users... // form need to be granted to create databases, users...
if (false === $db->checkPrivileges($this->databaseSetupPrivileges)) { if (false === $db->checkPrivileges($this->databaseSetupPrivileges)) {
$this->addError( $this->error(
$this->translate('The provided credentials cannot be used to create the database and/or the user.') $this->translate('The provided credentials cannot be used to create the database and/or the user.')
); );
$this->addSkipValidationCheckbox(); $this->addSkipValidationCheckbox();
@ -174,7 +173,7 @@ class DatabaseCreationPage extends Form
// ...and to grant all required usage privileges to others // ...and to grant all required usage privileges to others
if (false === $db->isGrantable($this->databaseUsagePrivileges)) { if (false === $db->isGrantable($this->databaseUsagePrivileges)) {
$this->addError(sprintf( $this->error(sprintf(
$this->translate( $this->translate(
'The provided credentials cannot be used to grant all required privileges to the login "%s".' 'The provided credentials cannot be used to grant all required privileges to the login "%s".'
), ),

View File

@ -18,7 +18,6 @@ class DbResourcePage extends Form
*/ */
public function init() public function init()
{ {
$this->setName('setup_db_resource');
$this->setTitle($this->translate('Database Resource', 'setup.page.title')); $this->setTitle($this->translate('Database Resource', 'setup.page.title'));
$this->addDescription($this->translate( $this->addDescription($this->translate(
'Now please configure your database resource. Note that the database itself does not need to' 'Now please configure your database resource. Note that the database itself does not need to'
@ -56,14 +55,6 @@ class DbResourcePage extends Form
$resourceForm = new DbResourceForm(); $resourceForm = new DbResourceForm();
$this->addElements($resourceForm->createElements($formData)->getElements()); $this->addElements($resourceForm->createElements($formData)->getElements());
$this->getElement('name')->setValue('icingaweb_db'); $this->getElement('name')->setValue('icingaweb_db');
$this->addElement(
'hidden',
'prefix',
array(
'required' => true,
'value' => 'icingaweb_'
)
);
} }
/** /**
@ -84,7 +75,7 @@ class DbResourcePage extends Form
$db = new DbTool($this->getValues()); $db = new DbTool($this->getValues());
$db->checkConnectivity(); $db->checkConnectivity();
} catch (PDOException $e) { } catch (PDOException $e) {
$this->addError($e->getMessage()); $this->error($e->getMessage());
$this->addSkipValidationCheckbox(); $this->addSkipValidationCheckbox();
return false; return false;
} }

View File

@ -3,8 +3,9 @@
namespace Icinga\Module\Setup\Forms; namespace Icinga\Module\Setup\Forms;
use Icinga\Web\Form; use Icinga\Forms\Config\General\ApplicationConfigForm;
use Icinga\Forms\Config\General\LoggingConfigForm; use Icinga\Forms\Config\General\LoggingConfigForm;
use Icinga\Web\Form;
/** /**
* Wizard page to define the application and logging configuration * Wizard page to define the application and logging configuration
@ -28,7 +29,13 @@ class GeneralConfigPage extends Form
*/ */
public function createElements(array $formData) public function createElements(array $formData)
{ {
$loggingForm = new LoggingConfigForm(); $appConfigForm = new ApplicationConfigForm();
$this->addElements($loggingForm->createElements($formData)->getElements()); $appConfigForm->createElements($formData);
$appConfigForm->removeElement('global_module_path');
$appConfigForm->removeElement('global_config_resource');
$this->addElements($appConfigForm->getElements());
$loggingConfigForm = new LoggingConfigForm();
$this->addElements($loggingConfigForm->createElements($formData)->getElements());
} }
} }

View File

@ -77,7 +77,7 @@ class LdapDiscoveryPage extends Form
} catch (Exception $e) { } catch (Exception $e) {
} }
$this->addError( $this->error(
sprintf($this->translate('Could not find any LDAP servers on the domain "%s".'), $data['domain']) sprintf($this->translate('Could not find any LDAP servers on the domain "%s".'), $data['domain'])
); );
} else { } else {

View File

@ -1,47 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Module\Setup\Forms;
use Icinga\Web\Form;
use Icinga\Application\Platform;
/**
* Wizard page to choose a preference backend
*/
class PreferencesPage extends Form
{
/**
* Initialize this page
*/
public function init()
{
$this->setRequiredCue(null);
$this->setName('setup_preferences_type');
$this->setTitle($this->translate('Preferences', 'setup.page.title'));
$this->addDescription($this->translate('Please choose how Icinga Web 2 should store user preferences.'));
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$storageTypes = array();
$storageTypes['ini'] = $this->translate('File System (INI Files)');
if (Platform::hasMysqlSupport() || Platform::hasPostgresqlSupport()) {
$storageTypes['db'] = $this->translate('Database');
}
$storageTypes['none'] = $this->translate('Don\'t Store Preferences');
$this->addElement(
'select',
'store',
array(
'required' => true,
'label' => $this->translate('User Preference Storage Type'),
'multiOptions' => $storageTypes
)
);
}
}

View File

@ -23,13 +23,12 @@ class GeneralConfigStep extends Step
{ {
$config = array(); $config = array();
foreach ($this->data['generalConfig'] as $sectionAndPropertyName => $value) { foreach ($this->data['generalConfig'] as $sectionAndPropertyName => $value) {
list($section, $property) = explode('_', $sectionAndPropertyName); list($section, $property) = explode('_', $sectionAndPropertyName, 2);
$config[$section][$property] = $value; $config[$section][$property] = $value;
} }
$config['preferences']['store'] = $this->data['preferencesStore']; if ($config['global']['config_backend'] === 'db') {
if (isset($this->data['preferencesResource'])) { $config['global']['config_resource'] = $this->data['resourceName'];
$config['preferences']['resource'] = $this->data['preferencesResource'];
} }
try { try {
@ -54,14 +53,10 @@ class GeneralConfigStep extends Step
$generalHtml = '' $generalHtml = ''
. '<ul>' . '<ul>'
. '<li>' . sprintf( . '<li>' . sprintf(
$this->data['preferencesStore'] === 'ini' ? sprintf( $this->data['generalConfig']['global_config_backend'] === 'ini' ? sprintf(
t('Preferences will be stored per user account in INI files at: %s'), t('Preferences will be stored per user account in INI files at: %s'),
Config::resolvePath('preferences') Config::resolvePath('preferences')
) : ( ) : t('Preferences will be stored using a database.')
$this->data['preferencesStore'] === 'db' ? t('Preferences will be stored using a database.') : (
t('Preferences will not be persisted across browser sessions.')
)
)
) . '</li>' ) . '</li>'
. '</ul>'; . '</ul>';

View File

@ -13,7 +13,6 @@ use Icinga\Module\Setup\Forms\ModulePage;
use Icinga\Module\Setup\Forms\WelcomePage; use Icinga\Module\Setup\Forms\WelcomePage;
use Icinga\Module\Setup\Forms\SummaryPage; use Icinga\Module\Setup\Forms\SummaryPage;
use Icinga\Module\Setup\Forms\DbResourcePage; use Icinga\Module\Setup\Forms\DbResourcePage;
use Icinga\Module\Setup\Forms\PreferencesPage;
use Icinga\Module\Setup\Forms\AuthBackendPage; use Icinga\Module\Setup\Forms\AuthBackendPage;
use Icinga\Module\Setup\Forms\AdminAccountPage; use Icinga\Module\Setup\Forms\AdminAccountPage;
use Icinga\Module\Setup\Forms\LdapDiscoveryPage; use Icinga\Module\Setup\Forms\LdapDiscoveryPage;
@ -91,7 +90,7 @@ class WebWizard extends Wizard implements SetupWizard
); );
/** /**
* @see Wizard::init() * Register all pages and module wizards for this wizard
*/ */
protected function init() protected function init()
{ {
@ -99,15 +98,16 @@ class WebWizard extends Wizard implements SetupWizard
$this->addPage(new ModulePage()); $this->addPage(new ModulePage());
$this->addPage(new RequirementsPage()); $this->addPage(new RequirementsPage());
$this->addPage(new AuthenticationPage()); $this->addPage(new AuthenticationPage());
$this->addPage(new PreferencesPage()); $this->addPage(new DbResourcePage(array('name' => 'setup_auth_db_resource')));
$this->addPage(new DbResourcePage()); $this->addPage(new DatabaseCreationPage(array('name' => 'setup_auth_db_creation')));
$this->addPage(new LdapDiscoveryPage()); $this->addPage(new LdapDiscoveryPage());
//$this->addPage(new LdapDiscoveryConfirmPage()); //$this->addPage(new LdapDiscoveryConfirmPage());
$this->addPage(new LdapResourcePage()); $this->addPage(new LdapResourcePage());
$this->addPage(new AuthBackendPage()); $this->addPage(new AuthBackendPage());
$this->addPage(new AdminAccountPage()); $this->addPage(new AdminAccountPage());
$this->addPage(new GeneralConfigPage()); $this->addPage(new GeneralConfigPage());
$this->addPage(new DatabaseCreationPage()); $this->addPage(new DbResourcePage(array('name' => 'setup_config_db_resource')));
$this->addPage(new DatabaseCreationPage(array('name' => 'setup_config_db_creation')));
$this->addPage(new SummaryPage(array('name' => 'setup_summary'))); $this->addPage(new SummaryPage(array('name' => 'setup_summary')));
if (($modulePageData = $this->getPageData('setup_modules')) !== null) { if (($modulePageData = $this->getPageData('setup_modules')) !== null) {
@ -119,25 +119,19 @@ class WebWizard extends Wizard implements SetupWizard
} }
/** /**
* @see Wizard::setupPage() * Setup the given page that is either going to be displayed or validated
*
* @param Form $page The page to setup
* @param Request $request The current request
*/ */
public function setupPage(Form $page, Request $request) public function setupPage(Form $page, Request $request)
{ {
if ($page->getName() === 'setup_requirements') { if ($page->getName() === 'setup_requirements') {
$page->setWizard($this); $page->setWizard($this);
} elseif ($page->getName() === 'setup_preferences_type') {
$authData = $this->getPageData('setup_authentication_type');
if ($authData['type'] === 'db') {
$page->create()->getElement('store')->setValue('db');
$page->addDescription(mt(
'setup',
'Note that choosing "Database" causes Icinga Web 2 to use the same database as for authentication.'
));
}
} elseif ($page->getName() === 'setup_authentication_backend') { } elseif ($page->getName() === 'setup_authentication_backend') {
$authData = $this->getPageData('setup_authentication_type'); $authData = $this->getPageData('setup_authentication_type');
if ($authData['type'] === 'db') { if ($authData['type'] === 'db') {
$page->setResourceConfig($this->getPageData('setup_db_resource')); $page->setResourceConfig($this->getPageData('setup_auth_db_resource'));
} elseif ($authData['type'] === 'ldap') { } elseif ($authData['type'] === 'ldap') {
$page->setResourceConfig($this->getPageData('setup_ldap_resource')); $page->setResourceConfig($this->getPageData('setup_ldap_resource'));
@ -152,38 +146,46 @@ class WebWizard extends Wizard implements SetupWizard
$page->setBackendConfig($this->getPageData('setup_authentication_backend')); $page->setBackendConfig($this->getPageData('setup_authentication_backend'));
$authData = $this->getPageData('setup_authentication_type'); $authData = $this->getPageData('setup_authentication_type');
if ($authData['type'] === 'db') { if ($authData['type'] === 'db') {
$page->setResourceConfig($this->getPageData('setup_db_resource')); $page->setResourceConfig($this->getPageData('setup_auth_db_resource'));
} elseif ($authData['type'] === 'ldap') { } elseif ($authData['type'] === 'ldap') {
$page->setResourceConfig($this->getPageData('setup_ldap_resource')); $page->setResourceConfig($this->getPageData('setup_ldap_resource'));
} }
} elseif ($page->getName() === 'setup_database_creation') { } elseif ($page->getName() === 'setup_auth_db_creation' || $page->getName() === 'setup_config_db_creation') {
$page->setDatabaseSetupPrivileges( $page->setDatabaseSetupPrivileges(
array_unique(array_merge($this->databaseCreationPrivileges, $this->databaseSetupPrivileges)) array_unique(array_merge($this->databaseCreationPrivileges, $this->databaseSetupPrivileges))
); );
$page->setDatabaseUsagePrivileges($this->databaseUsagePrivileges); $page->setDatabaseUsagePrivileges($this->databaseUsagePrivileges);
$page->setResourceConfig($this->getPageData('setup_db_resource')); $page->setResourceConfig(
$this->getPageData('setup_auth_db_resource') ?: $this->getPageData('setup_config_db_resource')
);
} elseif ($page->getName() === 'setup_summary') { } elseif ($page->getName() === 'setup_summary') {
$page->setSubjectTitle('Icinga Web 2'); $page->setSubjectTitle('Icinga Web 2');
$page->setSummary($this->getSetup()->getSummary()); $page->setSummary($this->getSetup()->getSummary());
} elseif ($page->getName() === 'setup_db_resource') { } elseif ($page->getName() === 'setup_config_db_resource') {
$ldapData = $this->getPageData('setup_ldap_resource'); $ldapData = $this->getPageData('setup_ldap_resource');
if ($ldapData !== null && $request->getPost('name') === $ldapData['name']) { if ($ldapData !== null && $request->getPost('name') === $ldapData['name']) {
$page->addError( $page->error(
mt('setup', 'The given resource name must be unique and is already in use by the LDAP resource') mt('setup', 'The given resource name must be unique and is already in use by the LDAP resource')
); );
} }
} elseif ($page->getName() === 'setup_ldap_resource') { } elseif ($page->getName() === 'setup_ldap_resource') {
$dbData = $this->getPageData('setup_db_resource');
if ($dbData !== null && $request->getPost('name') === $dbData['name']) {
$page->addError(
mt('setup', 'The given resource name must be unique and is already in use by the database resource')
);
}
$suggestion = $this->getPageData('setup_ldap_discovery'); $suggestion = $this->getPageData('setup_ldap_discovery');
if (isset($suggestion['resource'])) { if (isset($suggestion['resource'])) {
$page->populate($suggestion['resource']); $page->populate($suggestion['resource']);
} }
} elseif ($page->getName() === 'setup_general_config') {
$authData = $this->getPageData('setup_authentication_type');
if ($authData['type'] === 'db') {
$page->create()->getElement('global_config_backend')->setValue('db');
$page->info(
mt(
'setup',
'Note that choosing "Database" as preference storage causes'
. ' Icinga Web 2 to use the same database as for authentication.'
),
false
);
}
} elseif ($page->getName() === 'setup_authentication_type' && $this->getDirection() === static::FORWARD) { } elseif ($page->getName() === 'setup_authentication_type' && $this->getDirection() === static::FORWARD) {
$authData = $this->getPageData($page->getName()); $authData = $this->getPageData($page->getName());
if ($authData !== null && $request->getPost('type') !== $authData['type']) { if ($authData !== null && $request->getPost('type') !== $authData['type']) {
@ -192,21 +194,37 @@ class WebWizard extends Wizard implements SetupWizard
$pageData = & $this->getPageData(); $pageData = & $this->getPageData();
unset($pageData['setup_admin_account']); unset($pageData['setup_admin_account']);
unset($pageData['setup_authentication_backend']); unset($pageData['setup_authentication_backend']);
if ($authData['type'] === 'db') {
unset($pageData['setup_auth_db_resource']);
unset($pageData['setup_auth_db_creation']);
} elseif ($request->getPost('type') === 'db') {
unset($pageData['setup_config_db_resource']);
unset($pageData['setup_config_db_creation']);
}
} }
} }
} }
/** /**
* @see Wizard::getNewPage() * Return the new page to set as current page
*
* {@inheritdoc} Runs additional checks related to some registered pages.
*
* @param string $requestedPage The name of the requested page
* @param Form $originPage The origin page
*
* @return Form The new page
*
* @throws InvalidArgumentException In case the requested page does not exist or is not permitted yet
*/ */
protected function getNewPage($requestedPage, Form $originPage) protected function getNewPage($requestedPage, Form $originPage)
{ {
$skip = false; $skip = false;
$newPage = parent::getNewPage($requestedPage, $originPage); $newPage = parent::getNewPage($requestedPage, $originPage);
if ($newPage->getName() === 'setup_db_resource') { if ($newPage->getName() === 'setup_auth_db_resource') {
$prefData = $this->getPageData('setup_preferences_type');
$authData = $this->getPageData('setup_authentication_type'); $authData = $this->getPageData('setup_authentication_type');
$skip = $prefData['store'] !== 'db' && $authData['type'] !== 'db'; $skip = $authData['type'] !== 'db';
} elseif ($newPage->getname() === 'setup_ldap_discovery') { } elseif ($newPage->getname() === 'setup_ldap_discovery') {
$authData = $this->getPageData('setup_authentication_type'); $authData = $this->getPageData('setup_authentication_type');
$skip = $authData['type'] !== 'ldap'; $skip = $authData['type'] !== 'ldap';
@ -215,8 +233,17 @@ class WebWizard extends Wizard implements SetupWizard
} elseif ($newPage->getName() === 'setup_ldap_resource') { } elseif ($newPage->getName() === 'setup_ldap_resource') {
$authData = $this->getPageData('setup_authentication_type'); $authData = $this->getPageData('setup_authentication_type');
$skip = $authData['type'] !== 'ldap'; $skip = $authData['type'] !== 'ldap';
} elseif ($newPage->getName() === 'setup_database_creation') { } elseif ($newPage->getName() === 'setup_config_db_resource') {
if (($config = $this->getPageData('setup_db_resource')) !== null && ! $config['skip_validation']) { $authData = $this->getPageData('setup_authentication_type');
$configData = $this->getPageData('setup_general_config');
$skip = $authData['type'] === 'db' || $configData['global_config_backend'] !== 'db';
} elseif (in_array($newPage->getName(), array('setup_auth_db_creation', 'setup_config_db_creation'))) {
if (
($newPage->getName() === 'setup_auth_db_creation' || $this->hasPageData('setup_config_db_resource'))
&& (($config = $this->getPageData('setup_auth_db_resource')) !== null
|| ($config = $this->getPageData('setup_config_db_resource')) !== null)
&& !$config['skip_validation']
) {
$db = new DbTool($config); $db = new DbTool($config);
try { try {
@ -254,7 +281,9 @@ class WebWizard extends Wizard implements SetupWizard
} }
/** /**
* @see Wizard::addButtons() * Add buttons to the given page based on its position in the page-chain
*
* @param Form $page The page to add the buttons to
*/ */
protected function addButtons(Form $page) protected function addButtons(Form $page)
{ {
@ -270,7 +299,7 @@ class WebWizard extends Wizard implements SetupWizard
} }
/** /**
* @see Wizard::clearSession() * Clear the session being used by this wizard and drop the setup token
*/ */
public function clearSession() public function clearSession()
{ {
@ -283,29 +312,54 @@ class WebWizard extends Wizard implements SetupWizard
} }
/** /**
* @see SetupWizard::getSetup() * Return the setup for this wizard
*
* @return Setup
*/ */
public function getSetup() public function getSetup()
{ {
$pageData = $this->getPageData(); $pageData = $this->getPageData();
$setup = new Setup(); $setup = new Setup();
if (isset($pageData['setup_db_resource']) if (
&& ! $pageData['setup_db_resource']['skip_validation'] isset($pageData['setup_auth_db_resource'])
&& (false === isset($pageData['setup_database_creation']) && !$pageData['setup_auth_db_resource']['skip_validation']
|| ! $pageData['setup_database_creation']['skip_validation'] && (! isset($pageData['setup_auth_db_creation'])
|| !$pageData['setup_auth_db_creation']['skip_validation']
) )
) { ) {
$setup->addStep( $setup->addStep(
new DatabaseStep(array( new DatabaseStep(array(
'tables' => $this->databaseTables, 'tables' => $this->databaseTables,
'privileges' => $this->databaseUsagePrivileges, 'privileges' => $this->databaseUsagePrivileges,
'resourceConfig' => $pageData['setup_db_resource'], 'resourceConfig' => $pageData['setup_auth_db_resource'],
'adminName' => isset($pageData['setup_database_creation']['username']) 'adminName' => isset($pageData['setup_auth_db_creation']['username'])
? $pageData['setup_database_creation']['username'] ? $pageData['setup_auth_db_creation']['username']
: null, : null,
'adminPassword' => isset($pageData['setup_database_creation']['password']) 'adminPassword' => isset($pageData['setup_auth_db_creation']['password'])
? $pageData['setup_database_creation']['password'] ? $pageData['setup_auth_db_creation']['password']
: null,
'schemaPath' => Config::module('setup')
->get('schema', 'path', Icinga::app()->getBaseDir('etc' . DIRECTORY_SEPARATOR . 'schema'))
))
);
} elseif (
isset($pageData['setup_config_db_resource'])
&& !$pageData['setup_config_db_resource']['skip_validation']
&& (! isset($pageData['setup_config_db_creation'])
|| !$pageData['setup_config_db_creation']['skip_validation']
)
) {
$setup->addStep(
new DatabaseStep(array(
'tables' => $this->databaseTables,
'privileges' => $this->databaseUsagePrivileges,
'resourceConfig' => $pageData['setup_config_db_resource'],
'adminName' => isset($pageData['setup_config_db_creation']['username'])
? $pageData['setup_config_db_creation']['username']
: null,
'adminPassword' => isset($pageData['setup_config_db_creation']['password'])
? $pageData['setup_config_db_creation']['password']
: null, : null,
'schemaPath' => Config::module('setup') 'schemaPath' => Config::module('setup')
->get('schema', 'path', Icinga::app()->getBaseDir('etc' . DIRECTORY_SEPARATOR . 'schema')) ->get('schema', 'path', Icinga::app()->getBaseDir('etc' . DIRECTORY_SEPARATOR . 'schema'))
@ -315,22 +369,24 @@ class WebWizard extends Wizard implements SetupWizard
$setup->addStep( $setup->addStep(
new GeneralConfigStep(array( new GeneralConfigStep(array(
'generalConfig' => $pageData['setup_general_config'], 'generalConfig' => $pageData['setup_general_config'],
'preferencesStore' => $pageData['setup_preferences_type']['store'], 'resourceName' => isset($pageData['setup_auth_db_resource']['name'])
'preferencesResource' => isset($pageData['setup_db_resource']['name']) ? $pageData['setup_auth_db_resource']['name']
? $pageData['setup_db_resource']['name'] : (isset($pageData['setup_config_db_resource']['name'])
: null ? $pageData['setup_config_db_resource']['name']
: null
)
)) ))
); );
$adminAccountType = $pageData['setup_admin_account']['user_type']; $adminAccountType = $pageData['setup_admin_account']['user_type'];
$adminAccountData = array('username' => $pageData['setup_admin_account'][$adminAccountType]); $adminAccountData = array('username' => $pageData['setup_admin_account'][$adminAccountType]);
if ($adminAccountType === 'new_user' && ! $pageData['setup_db_resource']['skip_validation'] if ($adminAccountType === 'new_user' && !$pageData['setup_auth_db_resource']['skip_validation']
&& (false === isset($pageData['setup_database_creation']) && (! isset($pageData['setup_auth_db_creation'])
|| ! $pageData['setup_database_creation']['skip_validation'] || !$pageData['setup_auth_db_creation']['skip_validation']
) )
) { ) {
$adminAccountData['resourceConfig'] = $pageData['setup_db_resource']; $adminAccountData['resourceConfig'] = $pageData['setup_auth_db_resource'];
$adminAccountData['password'] = $pageData['setup_admin_account']['new_user_password']; $adminAccountData['password'] = $pageData['setup_admin_account']['new_user_password'];
} }
$authType = $pageData['setup_authentication_type']['type']; $authType = $pageData['setup_authentication_type']['type'];
@ -338,18 +394,25 @@ class WebWizard extends Wizard implements SetupWizard
new AuthenticationStep(array( new AuthenticationStep(array(
'adminAccountData' => $adminAccountData, 'adminAccountData' => $adminAccountData,
'backendConfig' => $pageData['setup_authentication_backend'], 'backendConfig' => $pageData['setup_authentication_backend'],
'resourceName' => $authType === 'db' ? $pageData['setup_db_resource']['name'] : ( 'resourceName' => $authType === 'db' ? $pageData['setup_auth_db_resource']['name'] : (
$authType === 'ldap' ? $pageData['setup_ldap_resource']['name'] : null $authType === 'ldap' ? $pageData['setup_ldap_resource']['name'] : null
) )
)) ))
); );
if (isset($pageData['setup_db_resource']) || isset($pageData['setup_ldap_resource'])) { if (
isset($pageData['setup_auth_db_resource'])
|| isset($pageData['setup_config_db_resource'])
|| isset($pageData['setup_ldap_resource'])
) {
$setup->addStep( $setup->addStep(
new ResourceStep(array( new ResourceStep(array(
'dbResourceConfig' => isset($pageData['setup_db_resource']) 'dbResourceConfig' => isset($pageData['setup_auth_db_resource'])
? array_diff_key($pageData['setup_db_resource'], array('skip_validation' => null)) ? array_diff_key($pageData['setup_auth_db_resource'], array('skip_validation' => null))
: null, : (isset($pageData['setup_config_db_resource'])
? array_diff_key($pageData['setup_config_db_resource'], array('skip_validation' => null))
: null
),
'ldapResourceConfig' => isset($pageData['setup_ldap_resource']) 'ldapResourceConfig' => isset($pageData['setup_ldap_resource'])
? array_diff_key($pageData['setup_ldap_resource'], array('skip_validation' => null)) ? array_diff_key($pageData['setup_ldap_resource'], array('skip_validation' => null))
: null : null
@ -369,7 +432,9 @@ class WebWizard extends Wizard implements SetupWizard
} }
/** /**
* @see SetupWizard::getRequirements() * Return the requirements of this wizard
*
* @return RequirementSet
*/ */
public function getRequirements($skipModules = false) public function getRequirements($skipModules = false)
{ {

View File

@ -139,7 +139,6 @@ form div.element ul.errors {
li { li {
color: @colorCritical; color: @colorCritical;
font-weight: bold; font-weight: bold;
line-height: 1.5em;
} }
} }
@ -160,33 +159,33 @@ form ul.form-errors {
li { li {
color: white; color: white;
font-weight: bold; font-weight: bold;
line-height: 1.5em;
} }
} }
form ul.form-notifications { form ul.form-notifications {
.non-list-like-list; .non-list-like-list;
margin-bottom: 1em; margin-bottom: 1em;
padding: 0em; padding: 0;
li.info { ul {
background: @colorFormNotificationInfo; .non-list-like-list;
}
li.warning { &.info {
background: @colorFormNotificationWarning; background-color: @colorFormNotificationInfo;
} }
li.error { &.warning {
background: @colorFormNotificationError; background-color: @colorFormNotificationWarning;
}
&.error {
background-color: @colorFormNotificationError;
}
} }
li { li {
color: white; color: white;
font-weight: bold; font-weight: bold;
line-height: 1.5em;
padding: 0.5em;
margin-bottom: 0.5em;
} }
} }