diff --git a/application/forms/Config/Authentication/DbBackendForm.php b/application/forms/Config/Authentication/DbBackendForm.php index f84354a52..561782cfd 100644 --- a/application/forms/Config/Authentication/DbBackendForm.php +++ b/application/forms/Config/Authentication/DbBackendForm.php @@ -145,6 +145,7 @@ class DbBackendForm extends BaseBackendForm ) ) ); + $dbBackend->connect(); if ($dbBackend->getUserCount() < 1) { $this->addErrorMessage("No users found under the specified database backend"); return false; diff --git a/library/Icinga/Authentication/Backend/DbUserBackend.php b/library/Icinga/Authentication/Backend/DbUserBackend.php index bace53090..7f1eba270 100644 --- a/library/Icinga/Authentication/Backend/DbUserBackend.php +++ b/library/Icinga/Authentication/Backend/DbUserBackend.php @@ -35,7 +35,6 @@ use \Zend_Config; use \Zend_Db; use \Zend_Db_Adapter_Abstract; use \Icinga\Data\ResourceFactory; -use \Icinga\Data\Db\Connection as DbConnection; use \Icinga\User; use \Icinga\Authentication\UserBackend; use \Icinga\Authentication\Credential; @@ -118,7 +117,7 @@ class DbUserBackend implements UserBackend * instance of Zend_Db_Adapter_Abstract * 'name' => The name of this authentication backend * - * @throws Exception When the connection to the resource is not possible. + * @throws ConfigurationError When the given resource does not exist. */ public function __construct(Zend_Config $config) { @@ -132,9 +131,6 @@ class DbUserBackend implements UserBackend $resource = ResourceFactory::createResource(ResourceFactory::getResourceConfig($config->resource)); $this->db = $resource->getConnection(); } - - // test the connection - $this->db->getConnection(); } /** @@ -355,4 +351,14 @@ class DbUserBackend implements UserBackend $query = $this->db->select()->from($this->userTable, 'COUNT(*) as count')->query(); return $query->fetch()->count; } + + /** + * Try to connect to the underlying database. + * + * @throws ConfigurationError When the backend is not reachable with the given configuration. + */ + public function connect() + { + $this->db->getConnection(); + } } diff --git a/library/Icinga/Authentication/Backend/LdapUserBackend.php b/library/Icinga/Authentication/Backend/LdapUserBackend.php index c84320750..ff71db49a 100644 --- a/library/Icinga/Authentication/Backend/LdapUserBackend.php +++ b/library/Icinga/Authentication/Backend/LdapUserBackend.php @@ -69,12 +69,12 @@ class LdapUserBackend implements UserBackend /** * Create a new LdapUserBackend * - * @param Zend_Config $config The configuration for this authentication backend. - * 'resource' => The name of the resource to use, or an actual + * @param Zend_Config $config The configuration for this authentication backend. + * 'resource' => The name of the resource to use, or an actual * instance of \Icinga\Protocol\Ldap\Connection. - * 'name' => The name of this authentication backend. + * 'name' => The name of this authentication backend. * - * @throws \Exception When the connection to the resource is not possible. + * @throws ConfigurationError When the given resource does not exist. */ public function __construct(Zend_Config $config) { @@ -83,7 +83,6 @@ class LdapUserBackend implements UserBackend } $this->config = $config; $this->name = $config->name; - if ($config->resource instanceof LdapConnection) { $this->connection = $config->resource; } else { @@ -91,8 +90,6 @@ class LdapUserBackend implements UserBackend ResourceFactory::getResourceConfig($config->resource) ); } - // will throw an exception, when the connection is not possible. - $this->connection->connect(); } /** @@ -190,4 +187,15 @@ class LdapUserBackend implements UserBackend ) ); } + + /** + * + * Establish the connection to this authentication backend + * + * @throws \Exception When the connection to the resource is not possible. + */ + public function connect() + { + $this->connection->connect(); + } } diff --git a/library/Icinga/Authentication/Manager.php b/library/Icinga/Authentication/Manager.php index 83c9393e3..c57adf0ad 100644 --- a/library/Icinga/Authentication/Manager.php +++ b/library/Icinga/Authentication/Manager.php @@ -34,13 +34,10 @@ use Icinga\Exception\ConfigurationError; use \Zend_Config; use \Icinga\User; use \Icinga\Data\ResourceFactory; -use \Icinga\Data\Db\Connection as DbConnection; use \Icinga\Application\Logger; use \Icinga\Application\Config as IcingaConfig; -use \Icinga\Protocol\Ldap\Connection as LdapConnection; use \Icinga\Authentication\Backend\DbUserBackend; use \Icinga\Authentication\Backend\LdapUserBackend; -use \Icinga\Exception\ProgrammingError; use \Icinga\Exception\ConfigurationError as ConfigError; @@ -97,6 +94,20 @@ class Manager **/ private $session = null; + /** + * The configuration + * + * @var Zend_Config + */ + private $config = null; + + /** + * If the backends are already created. + * + * @var Boolean + */ + private $initialized = false; + /** * Creates a new authentication manager using the provided config (or the * configuration provided in the authentication.ini if no config is given) @@ -115,16 +126,12 @@ class Manager if ($config === null && !(isset($options['noDefaultConfig']) && $options['noDefaultConfig'] == true)) { $config = IcingaConfig::app('authentication'); } - - if ($config !== null) { - $this->setupBackends($config); - } - if (!isset($options['sessionClass'])) { $this->session = new PhpSession(); } else { $this->session = $options['sessionClass']; } + $this->config = $config; } /** @@ -159,11 +166,11 @@ class Manager $backendConfig->name = $name; } $backend = $this->createBackend($backendConfig); - if ($backend instanceof UserBackend) { + $backend->connect(); $this->userBackends[$backend->getName()] = $backend; - } elseif ($backend instanceof GroupBackend) { + $backend->connect(); $this->groupBackends[$backend->getName()] = $backend; } } @@ -229,6 +236,7 @@ class Manager */ public function getUserBackend($name) { + $this->initBackends(); return (isset($this->userBackends[$name])) ? $this->userBackends[$name] : null; } @@ -252,6 +260,7 @@ class Manager */ public function getGroupBackend($name) { + $this->initBackends(); return (isset($this->groupBackends[$name])) ? $this->groupBackends[$name] : null; } @@ -266,8 +275,9 @@ class Manager */ private function getBackendForCredential(Credential $credentials) { - $authErrors = 0; + $this->initBackends(); + $authErrors = 0; foreach ($this->userBackends as $userBackend) { $flag = false; @@ -312,6 +322,17 @@ class Manager return null; } + /** + * Ensures that all backends are initialized + */ + private function initBackends() + { + if (!$this->initialized) { + $this->setupBackends($this->config); + $this->initialized = true; + } + } + /** * Try to authenticate the current user with the Credential (@see Credential). * @@ -324,6 +345,7 @@ class Manager */ public function authenticate(Credential $credentials, $persist = true) { + $this->initBackends(); if (count($this->userBackends) === 0) { Logger::error('AuthManager: No authentication backend provided, your users will never be able to login.'); throw new ConfigError( diff --git a/library/Icinga/Authentication/UserBackend.php b/library/Icinga/Authentication/UserBackend.php index 114f3eddb..b7c36d713 100644 --- a/library/Icinga/Authentication/UserBackend.php +++ b/library/Icinga/Authentication/UserBackend.php @@ -69,4 +69,11 @@ interface UserBackend * @return int */ public function getUserCount(); + + /** + * Establish the connection to this authentication backend + * + * @throws ConfigurationError When the backend is not reachable with the given configuration. + */ + public function connect(); } diff --git a/test/php/library/Icinga/Authentication/BackendMock.php b/test/php/library/Icinga/Authentication/BackendMock.php index 53f2bebd6..a289b4815 100644 --- a/test/php/library/Icinga/Authentication/BackendMock.php +++ b/test/php/library/Icinga/Authentication/BackendMock.php @@ -121,4 +121,9 @@ class BackendMock implements UserBackend { $this->allowedCredentials = $credentials; } + + public function connect() + { + + } } diff --git a/test/php/library/Icinga/Authentication/DbUserBackendTest.php b/test/php/library/Icinga/Authentication/DbUserBackendTest.php index 899a621e2..591cc129a 100644 --- a/test/php/library/Icinga/Authentication/DbUserBackendTest.php +++ b/test/php/library/Icinga/Authentication/DbUserBackendTest.php @@ -131,6 +131,7 @@ class DbUserBackendTest extends BaseTestCase { $this->setupDbProvider($db); $backend = new DbUserBackend($this->createDbBackendConfig($db)); + $backend->connect(); $this->runBackendAuthentication($backend); $this->runBackendUsername($backend); } @@ -144,6 +145,7 @@ class DbUserBackendTest extends BaseTestCase { $this->setupDbProvider($db); $backend = new DbUserBackend($this->createDbBackendConfig($db)); + $backend->connect(); $this->runBackendAuthentication($backend); $this->runBackendUsername($backend); } @@ -281,7 +283,7 @@ class DbUserBackendTest extends BaseTestCase $testName = 'test-name-123123'; $backend = new DbUserBackend($this->createDbBackendConfig($db, $testName)); - + $backend->connect(); $this->assertSame($testName, $backend->getName()); } @@ -293,6 +295,7 @@ class DbUserBackendTest extends BaseTestCase $this->setupDbProvider($db); $testName = 'test-name-123123'; $backend = new DbUserBackend($this->createDbBackendConfig($db, $testName)); + $backend->connect(); $this->assertGreaterThan(0, $backend->getUserCount()); } @@ -305,6 +308,7 @@ class DbUserBackendTest extends BaseTestCase $this->setupDbProvider($db); $testName = 'test-name-123123'; $backend = new DbUserBackend($this->createDbBackendConfig($db, $testName)); + $backend->connect(); $this->assertGreaterThan(0, $backend->getUserCount()); } diff --git a/test/php/library/Icinga/Authentication/ErrorProneBackendMock.php b/test/php/library/Icinga/Authentication/ErrorProneBackendMock.php index e9b021e14..7657ccd15 100644 --- a/test/php/library/Icinga/Authentication/ErrorProneBackendMock.php +++ b/test/php/library/Icinga/Authentication/ErrorProneBackendMock.php @@ -125,4 +125,8 @@ class ErrorProneBackendMock implements UserBackend throw new Exception('getUserCount error: No users in this error prone backend'); } + public function connect() + { + + } }