Merge branch 'bugfix/ldapuserbackend-lazy-loading-5506'

This commit is contained in:
Matthias Jentsch 2014-01-22 13:07:26 +01:00
commit b3bdee983d
8 changed files with 81 additions and 24 deletions

View File

@ -145,6 +145,7 @@ class DbBackendForm extends BaseBackendForm
) )
) )
); );
$dbBackend->connect();
if ($dbBackend->getUserCount() < 1) { if ($dbBackend->getUserCount() < 1) {
$this->addErrorMessage("No users found under the specified database backend"); $this->addErrorMessage("No users found under the specified database backend");
return false; return false;

View File

@ -35,7 +35,6 @@ use \Zend_Config;
use \Zend_Db; use \Zend_Db;
use \Zend_Db_Adapter_Abstract; use \Zend_Db_Adapter_Abstract;
use \Icinga\Data\ResourceFactory; use \Icinga\Data\ResourceFactory;
use \Icinga\Data\Db\Connection as DbConnection;
use \Icinga\User; use \Icinga\User;
use \Icinga\Authentication\UserBackend; use \Icinga\Authentication\UserBackend;
use \Icinga\Authentication\Credential; use \Icinga\Authentication\Credential;
@ -118,7 +117,7 @@ class DbUserBackend implements UserBackend
* instance of Zend_Db_Adapter_Abstract * instance of Zend_Db_Adapter_Abstract
* '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) public function __construct(Zend_Config $config)
{ {
@ -132,9 +131,6 @@ class DbUserBackend implements UserBackend
$resource = ResourceFactory::createResource(ResourceFactory::getResourceConfig($config->resource)); $resource = ResourceFactory::createResource(ResourceFactory::getResourceConfig($config->resource));
$this->db = $resource->getConnection(); $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(); $query = $this->db->select()->from($this->userTable, 'COUNT(*) as count')->query();
return $query->fetch()->count; 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();
}
} }

View File

@ -74,7 +74,7 @@ class LdapUserBackend implements UserBackend
* instance of \Icinga\Protocol\Ldap\Connection. * 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) public function __construct(Zend_Config $config)
{ {
@ -83,7 +83,6 @@ class LdapUserBackend implements UserBackend
} }
$this->config = $config; $this->config = $config;
$this->name = $config->name; $this->name = $config->name;
if ($config->resource instanceof LdapConnection) { if ($config->resource instanceof LdapConnection) {
$this->connection = $config->resource; $this->connection = $config->resource;
} else { } else {
@ -91,8 +90,6 @@ class LdapUserBackend implements UserBackend
ResourceFactory::getResourceConfig($config->resource) 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();
}
} }

View File

@ -34,13 +34,10 @@ use Icinga\Exception\ConfigurationError;
use \Zend_Config; use \Zend_Config;
use \Icinga\User; use \Icinga\User;
use \Icinga\Data\ResourceFactory; use \Icinga\Data\ResourceFactory;
use \Icinga\Data\Db\Connection as DbConnection;
use \Icinga\Application\Logger; use \Icinga\Application\Logger;
use \Icinga\Application\Config as IcingaConfig; use \Icinga\Application\Config as IcingaConfig;
use \Icinga\Protocol\Ldap\Connection as LdapConnection;
use \Icinga\Authentication\Backend\DbUserBackend; use \Icinga\Authentication\Backend\DbUserBackend;
use \Icinga\Authentication\Backend\LdapUserBackend; use \Icinga\Authentication\Backend\LdapUserBackend;
use \Icinga\Exception\ProgrammingError;
use \Icinga\Exception\ConfigurationError as ConfigError; use \Icinga\Exception\ConfigurationError as ConfigError;
@ -97,6 +94,20 @@ class Manager
**/ **/
private $session = null; 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 * Creates a new authentication manager using the provided config (or the
* configuration provided in the authentication.ini if no config is given) * 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)) { if ($config === null && !(isset($options['noDefaultConfig']) && $options['noDefaultConfig'] == true)) {
$config = IcingaConfig::app('authentication'); $config = IcingaConfig::app('authentication');
} }
if ($config !== null) {
$this->setupBackends($config);
}
if (!isset($options['sessionClass'])) { if (!isset($options['sessionClass'])) {
$this->session = new PhpSession(); $this->session = new PhpSession();
} else { } else {
$this->session = $options['sessionClass']; $this->session = $options['sessionClass'];
} }
$this->config = $config;
} }
/** /**
@ -159,11 +166,11 @@ class Manager
$backendConfig->name = $name; $backendConfig->name = $name;
} }
$backend = $this->createBackend($backendConfig); $backend = $this->createBackend($backendConfig);
if ($backend instanceof UserBackend) { if ($backend instanceof UserBackend) {
$backend->connect();
$this->userBackends[$backend->getName()] = $backend; $this->userBackends[$backend->getName()] = $backend;
} elseif ($backend instanceof GroupBackend) { } elseif ($backend instanceof GroupBackend) {
$backend->connect();
$this->groupBackends[$backend->getName()] = $backend; $this->groupBackends[$backend->getName()] = $backend;
} }
} }
@ -229,6 +236,7 @@ class Manager
*/ */
public function getUserBackend($name) public function getUserBackend($name)
{ {
$this->initBackends();
return (isset($this->userBackends[$name])) ? return (isset($this->userBackends[$name])) ?
$this->userBackends[$name] : null; $this->userBackends[$name] : null;
} }
@ -252,6 +260,7 @@ class Manager
*/ */
public function getGroupBackend($name) public function getGroupBackend($name)
{ {
$this->initBackends();
return (isset($this->groupBackends[$name])) ? return (isset($this->groupBackends[$name])) ?
$this->groupBackends[$name] : null; $this->groupBackends[$name] : null;
} }
@ -266,8 +275,9 @@ class Manager
*/ */
private function getBackendForCredential(Credential $credentials) private function getBackendForCredential(Credential $credentials)
{ {
$authErrors = 0; $this->initBackends();
$authErrors = 0;
foreach ($this->userBackends as $userBackend) { foreach ($this->userBackends as $userBackend) {
$flag = false; $flag = false;
@ -312,6 +322,17 @@ class Manager
return null; 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). * Try to authenticate the current user with the Credential (@see Credential).
* *
@ -324,6 +345,7 @@ class Manager
*/ */
public function authenticate(Credential $credentials, $persist = true) public function authenticate(Credential $credentials, $persist = true)
{ {
$this->initBackends();
if (count($this->userBackends) === 0) { if (count($this->userBackends) === 0) {
Logger::error('AuthManager: No authentication backend provided, your users will never be able to login.'); Logger::error('AuthManager: No authentication backend provided, your users will never be able to login.');
throw new ConfigError( throw new ConfigError(

View File

@ -69,4 +69,11 @@ interface UserBackend
* @return int * @return int
*/ */
public function getUserCount(); 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();
} }

View File

@ -121,4 +121,9 @@ class BackendMock implements UserBackend
{ {
$this->allowedCredentials = $credentials; $this->allowedCredentials = $credentials;
} }
public function connect()
{
}
} }

View File

@ -131,6 +131,7 @@ class DbUserBackendTest extends BaseTestCase
{ {
$this->setupDbProvider($db); $this->setupDbProvider($db);
$backend = new DbUserBackend($this->createDbBackendConfig($db)); $backend = new DbUserBackend($this->createDbBackendConfig($db));
$backend->connect();
$this->runBackendAuthentication($backend); $this->runBackendAuthentication($backend);
$this->runBackendUsername($backend); $this->runBackendUsername($backend);
} }
@ -144,6 +145,7 @@ class DbUserBackendTest extends BaseTestCase
{ {
$this->setupDbProvider($db); $this->setupDbProvider($db);
$backend = new DbUserBackend($this->createDbBackendConfig($db)); $backend = new DbUserBackend($this->createDbBackendConfig($db));
$backend->connect();
$this->runBackendAuthentication($backend); $this->runBackendAuthentication($backend);
$this->runBackendUsername($backend); $this->runBackendUsername($backend);
} }
@ -281,7 +283,7 @@ class DbUserBackendTest extends BaseTestCase
$testName = 'test-name-123123'; $testName = 'test-name-123123';
$backend = new DbUserBackend($this->createDbBackendConfig($db, $testName)); $backend = new DbUserBackend($this->createDbBackendConfig($db, $testName));
$backend->connect();
$this->assertSame($testName, $backend->getName()); $this->assertSame($testName, $backend->getName());
} }
@ -293,6 +295,7 @@ class DbUserBackendTest extends BaseTestCase
$this->setupDbProvider($db); $this->setupDbProvider($db);
$testName = 'test-name-123123'; $testName = 'test-name-123123';
$backend = new DbUserBackend($this->createDbBackendConfig($db, $testName)); $backend = new DbUserBackend($this->createDbBackendConfig($db, $testName));
$backend->connect();
$this->assertGreaterThan(0, $backend->getUserCount()); $this->assertGreaterThan(0, $backend->getUserCount());
} }
@ -305,6 +308,7 @@ class DbUserBackendTest extends BaseTestCase
$this->setupDbProvider($db); $this->setupDbProvider($db);
$testName = 'test-name-123123'; $testName = 'test-name-123123';
$backend = new DbUserBackend($this->createDbBackendConfig($db, $testName)); $backend = new DbUserBackend($this->createDbBackendConfig($db, $testName));
$backend->connect();
$this->assertGreaterThan(0, $backend->getUserCount()); $this->assertGreaterThan(0, $backend->getUserCount());
} }

View File

@ -125,4 +125,8 @@ class ErrorProneBackendMock implements UserBackend
throw new Exception('getUserCount error: No users in this error prone backend'); throw new Exception('getUserCount error: No users in this error prone backend');
} }
public function connect()
{
}
} }