parent
c78b016d74
commit
08d259eccf
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Form\Setup;
|
||||
|
||||
use PDOException;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Form\Element\Note;
|
||||
use Icinga\Web\Setup\DbTool;
|
||||
|
||||
/**
|
||||
* Wizard page to define a database user that is able to create databases and tables
|
||||
*/
|
||||
class DatabaseCreationPage extends Form
|
||||
{
|
||||
/**
|
||||
* The resource configuration to use
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* The required database privileges
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $databasePrivileges;
|
||||
|
||||
/**
|
||||
* Initialize this page
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('setup_database_creation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the resource configuration to use
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setResourceConfig(array $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the required database privileges
|
||||
*
|
||||
* @param array $privileges The required privileges
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setDatabasePrivileges(array $privileges)
|
||||
{
|
||||
$this->databasePrivileges = $privileges;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$this->addElement(
|
||||
new Note(
|
||||
'description',
|
||||
array(
|
||||
'value' => t(
|
||||
'It seems that either the database you defined earlier does not yet exist and cannot be created'
|
||||
. ' using the provided access credentials or the database does not have the required schema to '
|
||||
. 'be operated by Icinga Web 2. Please provide appropriate access credentials to solve this.'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'text',
|
||||
'username',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Username'),
|
||||
'description' => t('A user which is able to create databases and/or touch the database schema')
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'password',
|
||||
'password',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Password'),
|
||||
'description' => t('The password for the database user defined above')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the given form data and check whether the defined user has sufficient access rights
|
||||
*
|
||||
* @param array $data The data to validate
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($data)
|
||||
{
|
||||
if (false === parent::isValid($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->config['username'] = $this->getValue('username');
|
||||
$this->config['password'] = $this->getValue('password');
|
||||
$db = new DbTool($this->config);
|
||||
|
||||
try {
|
||||
$db->connectToDb();
|
||||
if (false === $db->checkPrivileges($this->databasePrivileges)) {
|
||||
$this->addError(
|
||||
t('The provided credentials do not have the required access rights to create the database schema.')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
try {
|
||||
$db->connectToHost();
|
||||
if (false === $db->checkPrivileges($this->databasePrivileges)) {
|
||||
$this->addError(
|
||||
t('The provided credentials cannot be used to create the database and/or the user.')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$this->addError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace Icinga\Application;
|
||||
|
||||
use PDOException;
|
||||
use Icinga\Form\Setup\WelcomePage;
|
||||
use Icinga\Form\Setup\DbResourcePage;
|
||||
use Icinga\Form\Setup\PreferencesPage;
|
||||
|
@ -13,9 +14,11 @@ use Icinga\Form\Setup\LdapResourcePage;
|
|||
use Icinga\Form\Setup\RequirementsPage;
|
||||
use Icinga\Form\Setup\GeneralConfigPage;
|
||||
use Icinga\Form\Setup\AuthenticationPage;
|
||||
use Icinga\Form\Setup\DatabaseCreationPage;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Wizard;
|
||||
use Icinga\Web\Request;
|
||||
use Icinga\Web\Setup\DbTool;
|
||||
use Icinga\Web\Setup\SetupWizard;
|
||||
use Icinga\Web\Setup\Requirements;
|
||||
use Icinga\Application\Platform;
|
||||
|
@ -25,6 +28,31 @@ use Icinga\Application\Platform;
|
|||
*/
|
||||
class WebSetup extends Wizard implements SetupWizard
|
||||
{
|
||||
/**
|
||||
* The database tables required by Icinga Web 2
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $databaseTables = array('account', 'preference');
|
||||
|
||||
/**
|
||||
* The privileges required by Icinga Web 2 to setup the database
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $databaseSetupPrivileges = array(
|
||||
'USAGE',
|
||||
'CREATE',
|
||||
'ALTER',
|
||||
'INSERT',
|
||||
'UPDATE',
|
||||
'DELETE',
|
||||
'TRUNCATE',
|
||||
'REFERENCES',
|
||||
'CREATE USER',
|
||||
'GRANT OPTION'
|
||||
);
|
||||
|
||||
/**
|
||||
* @see Wizard::init()
|
||||
*/
|
||||
|
@ -37,8 +65,9 @@ class WebSetup extends Wizard implements SetupWizard
|
|||
$this->addPage(new DbResourcePage());
|
||||
$this->addPage(new LdapResourcePage());
|
||||
$this->addPage(new AuthBackendPage());
|
||||
$this->addPage(new GeneralConfigPage());
|
||||
$this->addPage(new AdminAccountPage());
|
||||
$this->addPage(new GeneralConfigPage());
|
||||
$this->addPage(new DatabaseCreationPage());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,6 +97,9 @@ class WebSetup extends Wizard implements SetupWizard
|
|||
} elseif ($authData['type'] === 'ldap') {
|
||||
$page->setResourceConfig($this->getPageData('setup_ldap_resource'));
|
||||
}
|
||||
} elseif ($page->getName() === 'setup_database_creation') {
|
||||
$page->setDatabasePrivileges($this->databaseSetupPrivileges);
|
||||
$page->setResourceConfig($this->getPageData('setup_db_resource'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,6 +117,25 @@ class WebSetup extends Wizard implements SetupWizard
|
|||
} elseif ($newPage->getName() === 'setup_ldap_resource') {
|
||||
$authData = $this->getPageData('setup_authentication_type');
|
||||
$skip = $authData['type'] !== 'ldap';
|
||||
} elseif ($newPage->getName() === 'setup_database_creation') {
|
||||
if ($this->hasPageData('setup_db_resource')) {
|
||||
$db = new DbTool($this->getPageData('setup_db_resource'));
|
||||
|
||||
try {
|
||||
$db->connectToDb();
|
||||
$diff = array_diff($this->databaseTables, $db->listTables());
|
||||
if (false === empty($diff)) {
|
||||
$skip = $db->checkPrivileges($this->databaseSetupPrivileges);
|
||||
} else {
|
||||
$skip = true;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$db->connectToHost();
|
||||
$skip = $db->checkPrivileges($this->databaseSetupPrivileges);
|
||||
}
|
||||
} else {
|
||||
$skip = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($skip) {
|
||||
|
|
|
@ -6,6 +6,9 @@ namespace Icinga\Web\Setup;
|
|||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use LogicException;
|
||||
use Zend_Db_Adapter_Pdo_Mysql;
|
||||
use Zend_Db_Adapter_Pdo_Pgsql;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
|
||||
/**
|
||||
|
@ -14,11 +17,18 @@ use Icinga\Exception\ConfigurationError;
|
|||
class DbTool
|
||||
{
|
||||
/**
|
||||
* The database connection
|
||||
* The PDO database connection
|
||||
*
|
||||
* @var PDO
|
||||
*/
|
||||
protected $conn;
|
||||
protected $pdoConn;
|
||||
|
||||
/**
|
||||
* The Zend database adapter
|
||||
*
|
||||
* @var Zend_Db_Adapter_Pdo_Abstract
|
||||
*/
|
||||
protected $zendConn;
|
||||
|
||||
/**
|
||||
* The resource configuration
|
||||
|
@ -39,21 +49,27 @@ class DbTool
|
|||
|
||||
/**
|
||||
* Connect to the server
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function connectToHost()
|
||||
{
|
||||
$this->assertHostAccess();
|
||||
$this->connect();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function connectToDb()
|
||||
{
|
||||
$this->assertHostAccess();
|
||||
$this->assertDatabaseAccess();
|
||||
$this->connect($this->config['dbname']);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,6 +104,18 @@ class DbTool
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that a connection with a database has been established
|
||||
*
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function assertConnectedToDb()
|
||||
{
|
||||
if ($this->zendConn === null) {
|
||||
throw new LogicException('Not connected to database');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish a connection with the database or just the server by omitting the database name
|
||||
*
|
||||
|
@ -95,11 +123,55 @@ class DbTool
|
|||
*/
|
||||
public function connect($dbname = null)
|
||||
{
|
||||
if ($this->conn !== null) {
|
||||
$this->_pdoConnect($dbname);
|
||||
if ($dbname !== null) {
|
||||
$this->_zendConnect($dbname);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Zend database adapter
|
||||
*
|
||||
* @param string $dbname The name of the database to connect with
|
||||
*
|
||||
* @throws ConfigurationError In case the resource type is not a supported PDO driver name
|
||||
*/
|
||||
protected function _zendConnect($dbname)
|
||||
{
|
||||
if ($this->zendConn !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->conn = new PDO(
|
||||
$config = array(
|
||||
'dbname' => $dbname,
|
||||
'username' => $this->config['username'],
|
||||
'password' => $this->config['password']
|
||||
);
|
||||
|
||||
if ($this->config['db'] === 'mysql') {
|
||||
$this->zendConn = new Zend_Db_Adapter_Pdo_Mysql($config);
|
||||
} elseif ($this->config['db'] === 'pgsql') {
|
||||
$this->zendConn = new Zend_Db_Adapter_Pdo_Pgsql($config);
|
||||
} else {
|
||||
throw new ConfigurationError(
|
||||
'Failed to connect to database. Unsupported PDO driver "%s"',
|
||||
$this->config['db']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize PDO connection
|
||||
*
|
||||
* @param string $dbname The name of the database to connect with
|
||||
*/
|
||||
protected function _pdoConnect($dbname)
|
||||
{
|
||||
if ($this->pdoConn !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->pdoConn = new PDO(
|
||||
$this->buildDsn($this->config['db'], $dbname),
|
||||
$this->config['username'],
|
||||
$this->config['password'],
|
||||
|
@ -155,4 +227,27 @@ class DbTool
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given privileges were granted
|
||||
*
|
||||
* @param array $privileges An array of strings with the required privilege names
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkPrivileges(array $privileges)
|
||||
{
|
||||
return true; // TODO(7163): Implement privilege checks
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all existing database tables
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listTables()
|
||||
{
|
||||
$this->assertConnectedToDb();
|
||||
return $this->zendConn->listTables();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue