Change the StoreFactory to work with the DbAdapterFactory and fix code styling

Change the StoreFactory configuration to reference to a resource instead of
defining the whole database. Additionally fix docstrings, fix imports and fix
function calls to comply to coding style standards.

refs #4503
This commit is contained in:
Matthias Jentsch 2013-08-15 14:16:34 +02:00
parent 3692a73de5
commit 7f30b587be
11 changed files with 78 additions and 130 deletions

View File

@ -27,8 +27,4 @@ type=ini
; Use database to store preference into mysql or postgres ; Use database to store preference into mysql or postgres
;[preferences] ;[preferences]
;type=db ;type=db
;dbtype=pgsql ;resource=icingaweb-mysql
;dbhost=127.0.0.1
;dbpassword=icingaweb
;dbuser=icingaweb
;dbname=icingaweb

View File

@ -29,27 +29,12 @@ example:
[preferences] [preferences]
type=db type=db
dbtype=pgsql resource=icingaweb-pgsql
dbhost=127.0.0.1
dbpassword=icingaweb
dbuser=icingaweb
dbname=icingaweb
### Settings ### Settings
* **dbtype**: Database adapter, currently supporting ***mysql*** or ***pgsql*** * **resource**: A reference to a database declared in *resources.ini*. Please read the chapter about
resources for a detailed description about how to set up resources.
* **dbhost**: Host of the database server, use localhost or 127.0.0.1
for unix socket transport
* **dbpassword**: Password for the configured database user
* **dbuser**: User who can connect to database
* **dbname**: Name of the database
* **port**(optional): For network connections the specific port if not default
(3306 for mysql and 5432 for postgres)
### Preparation ### Preparation

View File

@ -35,7 +35,7 @@ use Icinga\Application\Modules\Manager as ModuleManager;
use Icinga\Application\Platform; use Icinga\Application\Platform;
use \Icinga\Application\Config; use \Icinga\Application\Config;
use Icinga\Exception\ProgrammingError; use Icinga\Exception\ProgrammingError;
use Icinga\Application\DbAdapterFactory; use \Icinga\Application\DbAdapterFactory;
use Icinga\Exception\ConfigurationError; use Icinga\Exception\ConfigurationError;
use Icinga\Util\DateTimeFactory; use Icinga\Util\DateTimeFactory;
@ -343,9 +343,6 @@ abstract class ApplicationBootstrap
} }
/** /**
<<<<<<< HEAD
* Setup time zone
=======
* Setup factories that provide access to the resources * Setup factories that provide access to the resources
* *
* @return self * @return self
@ -359,7 +356,6 @@ abstract class ApplicationBootstrap
/** /**
* Setup default timezone * Setup default timezone
>>>>>>> Add the DbAdapterFactory to instanciate database adapters using resource names
* *
* @return self * @return self
* @throws ConfigurationError if the timezone in config.ini isn't valid * @throws ConfigurationError if the timezone in config.ini isn't valid

View File

@ -1,42 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Application;
/**
* A factory that is configurable
*/
interface ConfigAwareFactory {
/**
* Set the factory configuration
*
* @param mixed $config The configuration
*/
public static function setConfig($config);
}

View File

@ -31,6 +31,7 @@ namespace Icinga\Application;
use Zend_Config; use Zend_Config;
use Zend_Db; use Zend_Db;
use Icinga\Application\Logger; use Icinga\Application\Logger;
use Icinga\Util\ConfigAwareFactory;
use Icinga\Exception\ConfigurationError; use Icinga\Exception\ConfigurationError;
use Icinga\Exception\ProgrammingError; use Icinga\Exception\ProgrammingError;
use Tests\Icinga\Application\ZendDbMock; use Tests\Icinga\Application\ZendDbMock;
@ -38,8 +39,8 @@ use Tests\Icinga\Application\ZendDbMock;
/** /**
* Create resources using short identifiers referring to configuration entries * Create resources using short identifiers referring to configuration entries
*/ */
class DbAdapterFactory implements ConfigAwareFactory { class DbAdapterFactory implements ConfigAwareFactory
{
/** /**
* Resource definitions * Resource definitions
* *
@ -142,7 +143,7 @@ class DbAdapterFactory implements ConfigAwareFactory {
Logger::error($msg); Logger::error($msg);
throw new ConfigurationError($msg); throw new ConfigurationError($msg);
} }
if (array_key_exists($identifier,self::$resourceCache)) { if (array_key_exists($identifier, self::$resourceCache)) {
return self::$resourceCache[$identifier]; return self::$resourceCache[$identifier];
} else { } else {
$res = self::createDbAdapter(self::$resources->{$identifier}); $res = self::createDbAdapter(self::$resources->{$identifier});
@ -165,7 +166,8 @@ class DbAdapterFactory implements ConfigAwareFactory {
{ {
if ($config->type !== 'db') { if ($config->type !== 'db') {
throw new ConfigurationError( throw new ConfigurationError(
'Resource type must be "db" but is "' . $config->type . '"'); 'Resource type must be "db" but is "' . $config->type . '"'
);
} }
$options = array( $options = array(
'dbname' => $config->dbname, 'dbname' => $config->dbname,
@ -175,10 +177,10 @@ class DbAdapterFactory implements ConfigAwareFactory {
); );
switch ($config->db) { switch ($config->db) {
case 'mysql': case 'mysql':
return self::callFactory('Pdo_Mysql',$options); return self::callFactory('Pdo_Mysql' ,$options);
case 'pgsql': case 'pgsql':
return self::callFactory('Pdo_Pgsql',$options); return self::callFactory('Pdo_Pgsql', $options);
default: default:
throw new ConfigurationError('Unsupported db type ' . $config->db . '.'); throw new ConfigurationError('Unsupported db type ' . $config->db . '.');
@ -197,6 +199,6 @@ class DbAdapterFactory implements ConfigAwareFactory {
private static function callFactory($adapter, $options) private static function callFactory($adapter, $options)
{ {
$factory = self::$factoryClass; $factory = self::$factoryClass;
return $factory::factory($adapter,$options); return $factory::factory($adapter, $options);
} }
} }

View File

@ -29,11 +29,11 @@
namespace Icinga\Authentication\Backend; namespace Icinga\Authentication\Backend;
use Icinga\User; use \Icinga\User;
use Icinga\Authentication\UserBackend; use \Icinga\Authentication\UserBackend;
use Icinga\Authentication\Credentials; use \Icinga\Authentication\Credentials;
use Icinga\Authentication; use \Icinga\Authentication;
use Icinga\Application\Logger; use \Icinga\Application\Logger;
/** /**
* User authentication backend (@see Icinga\Authentication\UserBackend) for * User authentication backend (@see Icinga\Authentication\UserBackend) for
@ -43,8 +43,8 @@ use Icinga\Application\Logger;
* See the UserBackend class (@see Icinga\Authentication\UserBackend) for * See the UserBackend class (@see Icinga\Authentication\UserBackend) for
* usage information * usage information
*/ */
class DbUserBackend implements UserBackend { class DbUserBackend implements UserBackend
{
/** /**
* The database connection that will be used for fetching users * The database connection that will be used for fetching users
* *
@ -93,6 +93,7 @@ class DbUserBackend implements UserBackend {
* Check if the user identified by the given credentials is available * Check if the user identified by the given credentials is available
* *
* @param Credentials $credentials The login credentials * @param Credentials $credentials The login credentials
*
* @return boolean True when the username is known and currently active. * @return boolean True when the username is known and currently active.
*/ */
public function hasUsername(Credentials $credential) public function hasUsername(Credentials $credential)
@ -109,6 +110,7 @@ class DbUserBackend implements UserBackend {
* Authenticate a user with the given credentials * Authenticate a user with the given credentials
* *
* @param Credentials $credentials The login credentials * @param Credentials $credentials The login credentials
*
* @return User|null The authenticated user or Null. * @return User|null The authenticated user or Null.
*/ */
public function authenticate(Credentials $credential) public function authenticate(Credentials $credential)
@ -120,9 +122,10 @@ class DbUserBackend implements UserBackend {
$this->db->getConnection(); $this->db->getConnection();
$res = $this->db $res = $this->db
->select()->from($this->userTable) ->select()->from($this->userTable)
->where($this->USER_NAME_COLUMN.' = ?',$credential->getUsername()) ->where($this->USER_NAME_COLUMN.' = ?', $credential->getUsername())
->where($this->ACTIVE_COLUMN. ' = ?',true) ->where($this->ACTIVE_COLUMN. ' = ?', true)
->where($this->PASSWORD_COLUMN. ' = ?',hash_hmac('sha256', ->where(
$this->PASSWORD_COLUMN. ' = ?', hash_hmac('sha256',
$this->getUserSalt($credential->getUsername()), $this->getUserSalt($credential->getUsername()),
$credential->getPassword()) $credential->getPassword())
) )
@ -147,7 +150,7 @@ class DbUserBackend implements UserBackend {
array( array(
$this->LAST_LOGIN_COLUMN => new \Zend_Db_Expr('NOW()') $this->LAST_LOGIN_COLUMN => new \Zend_Db_Expr('NOW()')
), ),
$this->USER_NAME_COLUMN.' = '.$this->db->quoteInto('?',$username)); $this->USER_NAME_COLUMN.' = '.$this->db->quoteInto('?', $username));
} }
/** /**
@ -161,8 +164,8 @@ class DbUserBackend implements UserBackend {
{ {
$this->db->getConnection(); $this->db->getConnection();
$res = $this->db->select() $res = $this->db->select()
->from($this->userTable,$this->SALT_COLUMN) ->from($this->userTable, $this->SALT_COLUMN)
->where($this->USER_NAME_COLUMN.' = ?',$username) ->where($this->USER_NAME_COLUMN.' = ?', $username)
->query()->fetch(); ->query()->fetch();
return $res[$this->SALT_COLUMN]; return $res[$this->SALT_COLUMN];
} }
@ -201,6 +204,7 @@ class DbUserBackend implements UserBackend {
* Create a new instance of User from a query result * Create a new instance of User from a query result
* *
* @param array $result The query result-array containing the column * @param array $result The query result-array containing the column
*
* @return User The created instance of User. * @return User The created instance of User.
*/ */
private function createUserFromResult(Array $result) private function createUserFromResult(Array $result)
@ -209,7 +213,8 @@ class DbUserBackend implements UserBackend {
$result[$this->USER_NAME_COLUMN], $result[$this->USER_NAME_COLUMN],
$result[$this->FIRST_NAME_COLUMN], $result[$this->FIRST_NAME_COLUMN],
$result[$this->LAST_NAME_COLUMN], $result[$this->LAST_NAME_COLUMN],
$result[$this->EMAIL_COLUMN]); $result[$this->EMAIL_COLUMN]
);
$usr->setDomain($result[$this->DOMAIN_COLUMN]); $usr->setDomain($result[$this->DOMAIN_COLUMN]);
return $usr; return $usr;
} }

View File

@ -28,11 +28,11 @@
namespace Icinga\Authentication; namespace Icinga\Authentication;
use Icinga\Application\Logger; use \Icinga\Application\Logger;
use \Icinga\Application\Config as IcingaConfig; use \Icinga\Application\Config as IcingaConfig;
use Icinga\Application\DbAdapterFactory; use \Icinga\Application\DbAdapterFactory;
use Icinga\Exception\ConfigurationError as ConfigError; use \Icinga\Exception\ConfigurationError as ConfigError;
use Icinga\User; use \Icinga\User;
/** /**
* The authentication manager allows to identify users and * The authentication manager allows to identify users and
@ -159,7 +159,7 @@ class Manager
{ {
foreach ($backends as $backend) { foreach ($backends as $backend) {
if (strtolower($target) === strtolower($backend->target)) { if (strtolower($target) === strtolower($backend->target)) {
$db = $this->tryToInitBackend($target,$backend); $db = $this->tryToInitBackend($target, $backend);
if (isset($db)) { if (isset($db)) {
break; break;
} }
@ -198,7 +198,7 @@ class Manager
return new $class($resource); return new $class($resource);
} catch (\Exception $e) { } catch (\Exception $e) {
$msg = 'Not able to create backend: ' . $msg = 'Not able to create backend: ' .
print_r($backendConfig->backend,true) print_r($backendConfig->backend, true)
. '. Exception: ' . $e->getMessage(); . '. Exception: ' . $e->getMessage();
Logger::warn($msg); Logger::warn($msg);
return null; return null;

View File

@ -30,6 +30,7 @@ namespace Icinga\User\Preferences;
use Icinga\User; use Icinga\User;
use Icinga\Exception\ProgrammingError; use Icinga\Exception\ProgrammingError;
use \Icinga\Application\DbAdapterFactory;
use \Zend_Config; use \Zend_Config;
use \Zend_Db; use \Zend_Db;
@ -53,6 +54,7 @@ final class StoreFactory
* *
* @param Zend_Config $config * @param Zend_Config $config
* @param User $user * @param User $user
*
* @return FlushObserverInterface * @return FlushObserverInterface
* @throws ProgrammingError * @throws ProgrammingError
*/ */
@ -68,33 +70,12 @@ final class StoreFactory
} }
$items = $config->toArray(); $items = $config->toArray();
if ($items['type'] == 'db') {
$items['dbAdapter'] = DbAdapterFactory::getDbAdapter($items['resource']);
}
unset($items['type']); unset($items['type']);
// TODO(mh): Encapsulate into a db adapter factory (#4503)
if (isset($items['dbname'])
&& isset($items['dbuser'])
&& isset($items['dbpassword'])
&& isset($items['dbhost'])
&& isset($items['dbtype'])
) {
$zendDbType = 'PDO_'. strtoupper($items['dbtype']);
$zendDbOptions = array(
'host' => $items['dbhost'],
'username' => $items['dbuser'],
'password' => $items['dbpassword'],
'dbname' => $items['dbname']
);
if (isset($items['port'])) {
$zendDbOptions['port'] = $items['port'];
}
$dbAdapter = Zend_Db::factory($zendDbType, $zendDbOptions);
$items['dbAdapter'] = $dbAdapter;
}
foreach ($items as $key => $value) { foreach ($items as $key => $value) {
$setter = 'set'. ucfirst($key); $setter = 'set'. ucfirst($key);
if (is_callable(array($store, $setter))) { if (is_callable(array($store, $setter))) {

View File

@ -1,5 +1,29 @@
<?php <?php
// {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Util; namespace Icinga\Util;
@ -17,3 +41,4 @@ interface ConfigAwareFactory
*/ */
public static function setConfig($config); public static function setConfig($config);
} }

View File

@ -37,12 +37,11 @@ require_once('../../library/Icinga/Application/Logger.php');
require_once('library/Icinga/Application/ZendDbMock.php'); require_once('library/Icinga/Application/ZendDbMock.php');
require_once('../../library/Icinga/Exception/ConfigurationError.php'); require_once('../../library/Icinga/Exception/ConfigurationError.php');
require_once('../../library/Icinga/Exception/ProgrammingError.php'); require_once('../../library/Icinga/Exception/ProgrammingError.php');
require_once('../../library/Icinga/Application/ConfigAwareFactory.php'); require_once('../../library/Icinga/Util/ConfigAwareFactory.php');
require_once('../../library/Icinga/Application/DbAdapterFactory.php'); require_once('../../library/Icinga/Application/DbAdapterFactory.php');
use Tests\Icinga\Application\ZendDbMock; use \Tests\Icinga\Application\ZendDbMock;
use Icinga\Application\DbAdapterFactory; use \Icinga\Application\DbAdapterFactory;
use Icinga\Exception\ConfigurationError;
/* /*
* Unit test for the class DbAdapterFactory * Unit test for the class DbAdapterFactory

View File

@ -31,7 +31,8 @@ namespace Tests\Icinga\Application;
/** /**
* Partially emulate the functionality of Zend_Db * Partially emulate the functionality of Zend_Db
*/ */
class ZendDbMock { class ZendDbMock
{
/** /**
* The config that was used in the last call of the factory function * The config that was used in the last call of the factory function