addPage(new WelcomePage()); $this->addPage(new ModulePage()); $this->addPage(new RequirementsPage()); $this->addPage(new AuthenticationPage()); $this->addPage(new DbResourcePage(array('name' => 'setup_auth_db_resource'))); $this->addPage(new DatabaseCreationPage(array('name' => 'setup_auth_db_creation'))); $this->addPage(new LdapDiscoveryPage()); //$this->addPage(new LdapDiscoveryConfirmPage()); $this->addPage(new LdapResourcePage()); $this->addPage(new AuthBackendPage()); $this->addPage(new UserGroupBackendPage()); $this->addPage(new AdminAccountPage()); $this->addPage(new GeneralConfigPage()); $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'))); if (($modulePageData = $this->getPageData('setup_modules')) !== null) { $modulePage = $this->getPage('setup_modules')->populate($modulePageData); foreach ($modulePage->getModuleWizards() as $moduleWizard) { $this->addPage($moduleWizard); } } } /** * 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) { if ($page->getName() === 'setup_requirements') { $page->setWizard($this); } elseif ($page->getName() === 'setup_authentication_backend') { /** @var AuthBackendPage $page */ $authData = $this->getPageData('setup_authentication_type'); if ($authData['type'] === 'db') { $page->setResourceConfig($this->getPageData('setup_auth_db_resource')); } elseif ($authData['type'] === 'ldap') { $page->setResourceConfig($this->getPageData('setup_ldap_resource')); $suggestions = $this->getPageData('setup_ldap_discovery'); if (isset($suggestions['backend'])) { $page->setSuggestions($suggestions['backend']); } if ($this->getDirection() === static::FORWARD) { $backendConfig = $this->getPageData('setup_authentication_backend'); if ($backendConfig !== null && $request->getPost('name') !== $backendConfig['name']) { $pageData = & $this->getPageData(); unset($pageData['setup_usergroup_backend']); } } } if ($this->getDirection() === static::FORWARD) { $backendConfig = $this->getPageData('setup_authentication_backend'); if ($backendConfig !== null && $request->getPost('backend') !== $backendConfig['backend']) { $pageData = & $this->getPageData(); unset($pageData['setup_usergroup_backend']); } } /*} elseif ($page->getName() === 'setup_ldap_discovery_confirm') { $page->setResourceConfig($this->getPageData('setup_ldap_discovery'));*/ } elseif ($page->getName() === 'setup_auth_db_resource') { $page->addDescription(mt( 'setup', 'Now please configure the database resource where to store users and user groups.' )); $page->addDescription(mt( 'setup', '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.' )); } elseif ($page->getName() === 'setup_usergroup_backend') { $page->setResourceConfig($this->getPageData('setup_ldap_resource')); $page->setBackendConfig($this->getPageData('setup_authentication_backend')); } elseif ($page->getName() === 'setup_admin_account') { $page->setBackendConfig($this->getPageData('setup_authentication_backend')); $page->setGroupConfig($this->getPageData('setup_usergroup_backend')); $authData = $this->getPageData('setup_authentication_type'); if ($authData['type'] === 'db') { $page->setResourceConfig($this->getPageData('setup_auth_db_resource')); } elseif ($authData['type'] === 'ldap') { $page->setResourceConfig($this->getPageData('setup_ldap_resource')); } } elseif ($page->getName() === 'setup_auth_db_creation' || $page->getName() === 'setup_config_db_creation') { $page->setDatabaseSetupPrivileges( array_unique(array_merge($this->databaseCreationPrivileges, $this->databaseSetupPrivileges)) ); $page->setDatabaseUsagePrivileges($this->databaseUsagePrivileges); $page->setResourceConfig( $this->getPageData('setup_auth_db_resource') ?: $this->getPageData('setup_config_db_resource') ); } elseif ($page->getName() === 'setup_summary') { $page->setSubjectTitle('Icinga Web 2'); $page->setSummary($this->getSetup()->getSummary()); } elseif ($page->getName() === 'setup_config_db_resource') { $page->addDescription(mt( 'setup', 'Now please configure the database resource where to store user preferences.' )); $page->addDescription(mt( 'setup', '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.' )); $ldapData = $this->getPageData('setup_ldap_resource'); if ($ldapData !== null && $request->getPost('name') === $ldapData['name']) { $page->error( mt('setup', 'The given resource name must be unique and is already in use by the LDAP resource') ); } } elseif ($page->getName() === 'setup_ldap_resource') { $suggestion = $this->getPageData('setup_ldap_discovery'); if (isset($suggestion['resource'])) { $page->populate($suggestion['resource']); } if ($this->getDirection() === static::FORWARD) { $resourceConfig = $this->getPageData('setup_ldap_resource'); if ($resourceConfig !== null && $request->getPost('name') !== $resourceConfig['name']) { $pageData = & $this->getPageData(); unset($pageData['setup_usergroup_backend']); } } } elseif ($page->getName() === 'setup_authentication_type') { $authData = $this->getPageData($page->getName()); $pageData = & $this->getPageData(); if ($authData !== null && $request->getPost('type') !== $authData['type']) { // Drop any existing page data in case the authentication type has changed, // otherwise it will conflict with other forms that depend on this one unset($pageData['setup_admin_account']); 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']); } } elseif (isset($authData['type']) && $authData['type'] == 'external') { // If you choose the authentication type external and validate the database and then come // back to change the authentication type but do not change it, you will get an database configuration // related error message on the next page. To avoid this error, the 'setup_config_db_resource' // page must be unset. unset($pageData['setup_config_db_resource']); } } } /** * 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) { $skip = false; $newPage = parent::getNewPage($requestedPage, $originPage); if ($newPage->getName() === 'setup_auth_db_resource') { $authData = $this->getPageData('setup_authentication_type'); $skip = $authData['type'] !== 'db'; } elseif ($newPage->getname() === 'setup_ldap_discovery') { $authData = $this->getPageData('setup_authentication_type'); $skip = $authData['type'] !== 'ldap'; /*} elseif ($newPage->getName() === 'setup_ldap_discovery_confirm') { $skip = false === $this->hasPageData('setup_ldap_discovery');*/ } elseif ($newPage->getName() === 'setup_ldap_resource') { $authData = $this->getPageData('setup_authentication_type'); $skip = $authData['type'] !== 'ldap'; } elseif ($newPage->getName() === 'setup_usergroup_backend') { $backendConfig = $this->getPageData('setup_authentication_backend'); $skip = $backendConfig['backend'] !== 'ldap'; } elseif ($newPage->getName() === 'setup_config_db_resource') { $authData = $this->getPageData('setup_authentication_type'); $skip = $authData['type'] === 'db'; } elseif (in_array($newPage->getName(), array('setup_auth_db_creation', 'setup_config_db_creation'))) { if (($newPage->getName() === 'setup_auth_db_creation' || $this->hasPageData('setup_config_db_resource')) && (($config = $this->getPageData('setup_auth_db_resource')) !== null || ($config = $this->getPageData('setup_config_db_resource')) !== null) && !$config['skip_validation'] && $this->getDirection() == static::FORWARD ) { // Execute this code only if the direction is forward. // Otherwise, an error will be output when you go back. $db = new DbTool($config); try { $db->connectToDb(); // Are we able to login on the database? if (array_search(reset($this->databaseTables), $db->listTables(), true) === false) { // In case the database schema does not yet exist the // user needs the privileges to setup the database $skip = $db->checkPrivileges($this->databaseSetupPrivileges, $this->databaseTables); } else { // In case the database schema exists the user needs the required privileges // to operate the database, if those are missing we ask for another user $skip = $db->checkPrivileges($this->databaseUsagePrivileges, $this->databaseTables); } } catch (PDOException $_) { try { $db->connectToHost(); // Are we able to login on the server? // It is not possible to reliably determine whether a database exists or not if a user can't // log in to the database, so we just require the user to be able to create the database $skip = $db->checkPrivileges( array_unique( array_merge($this->databaseCreationPrivileges, $this->databaseSetupPrivileges) ), $this->databaseTables ); } catch (PDOException $_) { // We are NOT able to login on the server.. } } } else { $skip = true; } } return $skip ? $this->skipPage($newPage) : $newPage; } /** * 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) { parent::addButtons($page); $pages = $this->getPages(); $index = array_search($page, $pages, true); if ($index === 0) { $page->getElement(static::BTN_NEXT)->setLabel( mt('setup', 'Start', 'setup.welcome.btn.next') ); } 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', 'setup_icingadb_resource', 'setup_icingadb_redis', 'setup_icingadb_api_transport' ))) { $page->addElement( 'submit', 'backend_validation', array( 'ignore' => true, 'label' => t('Validate Configuration'), 'data-progress-label' => t('Validation In Progress'), 'decorators' => array('ViewHelper'), 'formnovalidate' => 'formnovalidate' ) ); $page->getDisplayGroup('buttons')->addElement($page->getElement('backend_validation')); } if ($page->getName() === 'setup_command_transport') { if ($page->getSubForm('transport_form')->getSubForm('transport_form') instanceof ApiTransportForm) { $page->addElement( 'submit', 'transport_validation', array( 'ignore' => true, 'label' => t('Validate Configuration'), 'data-progress-label' => t('Validation In Progress'), 'decorators' => array('ViewHelper'), 'formnovalidate' => 'formnovalidate' ) ); $page->getDisplayGroup('buttons')->addElement($page->getElement('transport_validation')); } } } /** * Clear the session being used by this wizard * * @param bool $removeToken If true, the setup token will be removed */ public function clearSession($removeToken = true) { parent::clearSession(); if ($removeToken) { $tokenPath = Config::resolvePath('setup.token'); if (file_exists($tokenPath)) { @unlink($tokenPath); } } } /** * Return the setup for this wizard * * @return Setup */ public function getSetup() { $pageData = $this->getPageData(); $setup = new Setup(); if (isset($pageData['setup_auth_db_resource']) && !$pageData['setup_auth_db_resource']['skip_validation'] && (! isset($pageData['setup_auth_db_creation']) || !$pageData['setup_auth_db_creation']['skip_validation'] ) ) { $setup->addStep( new DatabaseStep(array( 'tables' => $this->databaseTables, 'privileges' => $this->databaseUsagePrivileges, 'resourceConfig' => $pageData['setup_auth_db_resource'], 'adminName' => isset($pageData['setup_auth_db_creation']['username']) ? $pageData['setup_auth_db_creation']['username'] : null, 'adminPassword' => isset($pageData['setup_auth_db_creation']['password']) ? $pageData['setup_auth_db_creation']['password'] : null, 'schemaPath' => Config::module('setup') ->get('schema', 'path', Icinga::app()->getBaseDir('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, 'schemaPath' => Config::module('setup') ->get('schema', 'path', Icinga::app()->getBaseDir('schema')) )) ); } $setup->addStep( new GeneralConfigStep(array( 'generalConfig' => $pageData['setup_general_config'], 'resourceName' => isset($pageData['setup_auth_db_resource']['name']) ? $pageData['setup_auth_db_resource']['name'] : (isset($pageData['setup_config_db_resource']['name']) ? $pageData['setup_config_db_resource']['name'] : null ) )) ); $adminAccountType = $pageData['setup_admin_account']['user_type']; if ($adminAccountType === 'user_group') { $adminAccountData = array('groupname' => $pageData['setup_admin_account'][$adminAccountType]); } else { $adminAccountData = array('username' => $pageData['setup_admin_account'][$adminAccountType]); if ($adminAccountType === 'new_user' && !$pageData['setup_auth_db_resource']['skip_validation'] && (! isset($pageData['setup_auth_db_creation']) || !$pageData['setup_auth_db_creation']['skip_validation'] ) ) { $adminAccountData['resourceConfig'] = $pageData['setup_auth_db_resource']; $adminAccountData['password'] = $pageData['setup_admin_account']['new_user_password']; } } $authType = $pageData['setup_authentication_type']['type']; $setup->addStep( new AuthenticationStep(array( 'adminAccountData' => $adminAccountData, 'backendConfig' => $pageData['setup_authentication_backend'], 'resourceName' => $authType === 'db' ? $pageData['setup_auth_db_resource']['name'] : ( $authType === 'ldap' ? $pageData['setup_ldap_resource']['name'] : null ) )) ); if ($authType !== 'external') { $setup->addStep( new UserGroupStep(array( 'backendConfig' => $pageData['setup_authentication_backend'], 'groupConfig' => isset($pageData['setup_usergroup_backend']) ? $pageData['setup_usergroup_backend'] : null, 'resourceName' => $authType === 'db' ? $pageData['setup_auth_db_resource']['name'] : $pageData['setup_ldap_resource']['name'], 'resourceConfig' => $authType === 'db' ? $pageData['setup_auth_db_resource'] : null, 'username' => $authType === 'db' ? $pageData['setup_admin_account'][$adminAccountType] : null )) ); } if (isset($pageData['setup_auth_db_resource']) || isset($pageData['setup_config_db_resource']) || isset($pageData['setup_ldap_resource']) ) { $setup->addStep( new ResourceStep(array( 'dbResourceConfig' => isset($pageData['setup_auth_db_resource']) ? array_diff_key($pageData['setup_auth_db_resource'], array('skip_validation' => 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']) ? array_diff_key($pageData['setup_ldap_resource'], array('skip_validation' => null)) : null )) ); } foreach ($this->getWizards() as $wizard) { if ($wizard->isComplete()) { $setup->addSteps($wizard->getSetup()->getSteps()); } } $setup->addStep(new EnableModuleStep(array_keys($this->getPage('setup_modules')->getCheckedModules()))); return $setup; } /** * Return the requirements of this wizard * * @return RequirementSet */ public function getRequirements($skipModules = false) { $set = new RequirementSet(); $set->add(new PhpVersionRequirement(array( 'condition' => array('>=', '7.2'), 'description' => sprintf(mt( 'setup', 'Running Icinga Web 2 requires PHP version %s.' ), '7.2') ))); $set->add(new OSRequirement(array( 'optional' => true, 'condition' => 'linux', 'description' => mt( 'setup', 'Icinga Web 2 is developed for and tested on Linux. While we cannot' . ' guarantee they will, other platforms may also perform as well.' ) ))); $set->add(new WebLibraryRequirement(array( 'condition' => ['icinga-php-library', '>=', '0.9.0'], 'alias' => 'Icinga PHP library', 'description' => mt( 'setup', 'The Icinga PHP library (IPL) is required for Icinga Web 2 and modules' ) ))); $set->add(new WebLibraryRequirement(array( 'condition' => ['icinga-php-thirdparty', '>=', '0.11.0'], 'alias' => 'Icinga PHP Thirdparty', 'description' => mt( 'setup', 'The Icinga PHP Thirdparty library is required for Icinga Web 2 and modules' ) ))); $set->add(new PhpModuleRequirement(array( 'condition' => 'OpenSSL', 'description' => mt( 'setup', 'The PHP module for OpenSSL is required to generate cryptographically safe password salts.' ) ))); $set->add(new PhpModuleRequirement(array( 'condition' => 'XML', 'description' => mt( 'setup', 'The XML module for PHP is required for Markdown and custom HTML annotations.' ) ))); $set->add(new PhpModuleRequirement(array( 'condition' => 'JSON', 'description' => mt( 'setup', 'The JSON module for PHP is required for various export functionalities as well as APIs.' ) ))); $set->add(new PhpModuleRequirement(array( 'condition' => 'gettext', 'description' => mt( 'setup', 'For message localization, the gettext module for PHP is required.' ) ))); $set->add(new PhpModuleRequirement(array( 'condition' => 'INTL', 'description' => mt( 'setup', 'For language, timezone and date/time format negotiation, the INTL module for PHP is required.' ) ))); $set->add(new PhpModuleRequirement(array( 'condition' => 'DOM', 'description' => mt( 'setup', 'For charts and exports of views and reports to PDF, the DOM module for PHP is required.' ) ))); $set->add(new PhpModuleRequirement(array( 'optional' => true, 'condition' => 'LDAP', 'description' => mt( 'setup', 'If you\'d like to authenticate users using LDAP the corresponding PHP module is required.' ) ))); $set->add(new PhpModuleRequirement(array( 'optional' => true, 'condition' => 'mbstring', 'description' => mt( 'setup', 'In case you want views being exported to PDF, you\'ll need the mbstring extension for PHP.' ) ))); $set->add(new PhpModuleRequirement(array( 'optional' => true, 'condition' => 'GD', 'description' => mt( 'setup', 'In case you want views being exported to PDF, you\'ll need the GD extension for PHP.' ) ))); $set->add(new PhpModuleRequirement(array( 'optional' => true, 'condition' => 'Imagick', 'description' => mt( 'setup', 'In case you want graphs being exported to PDF as well, you\'ll need the ImageMagick extension for PHP.' ) ))); $dbSet = new RequirementSet(false, RequirementSet::MODE_OR); $dbSet->add(new PhpModuleRequirement(array( 'optional' => true, 'condition' => 'pdo_mysql', 'alias' => 'PDO-MySQL', 'description' => mt( 'setup', 'To store users or preferences in a MySQL database the PDO-MySQL module for PHP is required.' ) ))); $dbSet->add(new PhpModuleRequirement(array( 'optional' => true, 'condition' => 'pdo_pgsql', 'alias' => 'PDO-PostgreSQL', 'description' => mt( 'setup', 'To store users or preferences in a PostgreSQL database the PDO-PostgreSQL module for PHP is required.' ) ))); $set->merge($dbSet); $dbRequire = (new SetRequirement(array( 'optional' => false, 'condition' => $dbSet, 'title' =>'Database', 'alias' => 'PDO-MySQL OR PDO-PostgreSQL', 'description' => mt( 'setup', 'A database is mandatory, therefore at least one module ' . 'PDO-MySQL or PDO-PostgreSQL for PHP is required.' ) ))); $set->add($dbRequire); $set->add(new ConfigDirectoryRequirement(array( 'condition' => Icinga::app()->getStorageDir(), 'title' => mt('setup', 'Read- and writable storage directory'), 'description' => mt( 'setup', 'The Icinga Web 2 storage directory defaults to "/var/lib/icingaweb2", if' . ' not explicitly set in the environment variable "ICINGAWEB_STORAGEDIR".' ) ))); $set->add(new ConfigDirectoryRequirement(array( 'condition' => Icinga::app()->getConfigDir(), 'description' => mt( 'setup', 'The Icinga Web 2 configuration directory defaults to "/etc/icingaweb2", if' . ' not explicitly set in the environment variable "ICINGAWEB_CONFIGDIR".' ) ))); if (! $skipModules) { foreach ($this->getWizards() as $wizard) { $set->merge($wizard->getRequirements()); } } return $set; } }