AuthManager: Fix tests

refs #4641
This commit is contained in:
Marius Hein 2013-08-28 15:56:33 +02:00
parent dfb7238b81
commit 83d20a6175
9 changed files with 711 additions and 136 deletions

View File

@ -32,6 +32,7 @@ use \Exception;
use \stdClass; use \stdClass;
use \Zend_Config; use \Zend_Config;
use \Zend_Db; use \Zend_Db;
use \Zend_Db_Adapter_Abstract;
use \Icinga\Application\DbAdapterFactory; use \Icinga\Application\DbAdapterFactory;
use \Icinga\Exception\ProgrammingError; use \Icinga\Exception\ProgrammingError;
use \Icinga\User; use \Icinga\User;
@ -109,7 +110,12 @@ class DbUserBackend implements UserBackend
public function __construct(Zend_Config $config) public function __construct(Zend_Config $config)
{ {
$this->name = $config->name; $this->name = $config->name;
$this->db = DbAdapterFactory::getDbAdapter($config->resource);
if ($config->resource instanceof Zend_Db_Adapter_Abstract) {
$this->db = $config->resource;
} else {
$this->db = DbAdapterFactory::getDbAdapter($config->resource);
}
// Throw any errors for Authentication/Manager // Throw any errors for Authentication/Manager
$this->db->getConnection(); $this->db->getConnection();

View File

@ -190,18 +190,24 @@ class Manager
$target = ucwords(strtolower($backendConfig->target)); $target = ucwords(strtolower($backendConfig->target));
$name = $backendConfig->name; $name = $backendConfig->name;
if (!$type) { if (!$type && !$backendConfig->class) {
Logger::warn('AuthManager: Backend "%s" has no type configured. (e.g. backend=ldap)', $name); Logger::warn('AuthManager: Backend "%s" has no backend type configuration. (e.g. backend=ldap)', $name);
return null; return null;
} }
if (!$target) { if (!$target && !$backendConfig->class) {
Logger::warn('AuthManager: Backend "%s" has no target configured. (e.g. target=user|group)', $name); Logger::warn('AuthManager: Backend "%s" has no target configuration. (e.g. target=user|group)', $name);
return null; return null;
} }
try { try {
$class = '\\Icinga\\Authentication\\Backend\\' . $type . $target . 'Backend'; // Allow vendor and test classes in configuration
if ($backendConfig->class) {
$class = $backendConfig->class;
} else {
$class = '\\Icinga\\Authentication\\Backend\\' . $type . $target . 'Backend';
}
if (!class_exists($class)) { if (!class_exists($class)) {
Logger::error('AuthManager: Class not found (%s) for backend %s', $class, $name); Logger::error('AuthManager: Class not found (%s) for backend %s', $class, $name);
return null; return null;
@ -221,17 +227,43 @@ class Manager
*/ */
public function addUserBackend(UserBackend $userBackend) public function addUserBackend(UserBackend $userBackend)
{ {
$this->userBackends[] = $userBackend; $this->userBackends[$userBackend->getName()] = $userBackend;
}
/**
* Get a user backend by name
*
* @param string $name
*
* @return UserBackend|null
*/
public function getUserBackend($name)
{
return (isset($this->userBackends[$name])) ?
$this->userBackends[$name] : null;
} }
/** /**
* Add a group backend to stack * Add a group backend to stack
* *
* @param $groupBackend * @param GroupBackend $groupBackend
*/ */
public function addGroupBackend($groupBackend) public function addGroupBackend(GroupBackend $groupBackend)
{ {
$this->groupBackends[] = $groupBackend; $this->groupBackends[$groupBackend->getName()] = $groupBackend;
}
/**
* Get a group backend by name
*
* @param string $name
*
* @return GroupBackend|null
*/
public function getGroupBackend($name)
{
return (isset($this->groupBackends[$name])) ?
$this->groupBackends[$name] : null;
} }
/** /**

View File

@ -4,13 +4,23 @@
namespace Tests\Icinga\Authentication; namespace Tests\Icinga\Authentication;
require_once __DIR__. '/../../../../../library/Icinga/Authentication/Credentials.php'; // @codingStandardsIgnoreStart
require_once __DIR__. '/../../../../../library/Icinga/Authentication/UserBackend.php'; require_once realpath(__DIR__ . '/../../../../../library/Icinga/Test/BaseTestCase.php');
require_once __DIR__. '/../../../../../library/Icinga/User.php'; // @codingStandardsIgnoreEnd
use Icinga\Authentication\Credentials as Credentials; use Icinga\Test\BaseTestCase;
use Icinga\Authentication\UserBackend as UserBackend;
use Icinga\User; // @codingStandardsIgnoreStart
require_once 'Zend/Config.php';
require_once BaseTestCase::$libDir . '/Authentication/Credentials.php';
require_once BaseTestCase::$libDir . '/Authentication/UserBackend.php';
require_once BaseTestCase::$libDir . '/User.php';
// @codingStandardsIgnoreEnd
use \Zend_Config;
use \Icinga\Authentication\Credentials as Credentials;
use \Icinga\Authentication\UserBackend as UserBackend;
use \Icinga\User;
/** /**
* Simple backend mock that takes an config object * Simple backend mock that takes an config object
@ -20,14 +30,23 @@ use Icinga\User;
class BackendMock implements UserBackend class BackendMock implements UserBackend
{ {
public $allowedCredentials = array(); public $allowedCredentials = array();
public function __construct($config = null) public $name;
public function __construct(Zend_Config $config = null)
{ {
if ($config === null) { if ($config === null) {
return; return;
} }
if (isset ($config->credentials)) { if (isset ($config->credentials)) {
$this->allowedCredentials = $config->credentials; $this->allowedCredentials = $config->credentials;
} }
if ($config->name) {
$this->name = $config->name;
} else {
$this->name = 'TestBackendMock-' . uniqid();
}
} }
public function hasUsername(Credentials $userCredentials) public function hasUsername(Credentials $userCredentials)
@ -39,14 +58,25 @@ class BackendMock implements UserBackend
} }
return false; return false;
} }
/**
* Name of the backend
*
* @return string
*/
public function getName()
{
return $this->name;
}
public static function getDummyUser() public static function getDummyUser()
{ {
return new User( return new User(
"Username", 'Username',
"Firstname", 'Firstname',
"Lastname", 'Lastname',
"user@test.local" 'user@test.local'
); );
} }
@ -59,6 +89,12 @@ class BackendMock implements UserBackend
if (!in_array($credentials, $this->allowedCredentials)) { if (!in_array($credentials, $this->allowedCredentials)) {
return false; return false;
} }
return self::getDummyUser(); return self::getDummyUser();
} }
public function setCredentials(array $credentials)
{
$this->allowedCredentials = $credentials;
}
} }

View File

@ -1,5 +1,4 @@
<?php <?php
// {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}}
/** /**
* This file is part of Icinga 2 Web. * This file is part of Icinga 2 Web.
@ -107,6 +106,22 @@ class DbUserBackendTest extends BaseTestCase
) )
); );
private function createDbBackendConfig($resource, $name = null)
{
if ($name === null) {
$name = 'TestDbUserBackend-' . uniqid();
}
$config = new Zend_Config(
array(
'name' => $name,
'resource' => $resource
)
);
return $config;
}
/** /**
* Test the authentication functions of the DbUserBackend using PostgreSQL as backend. * Test the authentication functions of the DbUserBackend using PostgreSQL as backend.
* *
@ -115,7 +130,7 @@ class DbUserBackendTest extends BaseTestCase
public function testCorrectUserLoginForPgsql($db) public function testCorrectUserLoginForPgsql($db)
{ {
$this->setupDbProvider($db); $this->setupDbProvider($db);
$backend = new DbUserBackend($db); $backend = new DbUserBackend($this->createDbBackendConfig($db));
$this->runBackendAuthentication($backend); $this->runBackendAuthentication($backend);
$this->runBackendUsername($backend); $this->runBackendUsername($backend);
} }
@ -128,7 +143,7 @@ class DbUserBackendTest extends BaseTestCase
public function testCorrectUserLoginForMySQL($db) public function testCorrectUserLoginForMySQL($db)
{ {
$this->setupDbProvider($db); $this->setupDbProvider($db);
$backend = new DbUserBackend($db); $backend = new DbUserBackend($this->createDbBackendConfig($db));
$this->runBackendAuthentication($backend); $this->runBackendAuthentication($backend);
$this->runBackendUsername($backend); $this->runBackendUsername($backend);
} }
@ -256,4 +271,17 @@ class DbUserBackendTest extends BaseTestCase
'Assert that an inactive user cannot authenticate.' 'Assert that an inactive user cannot authenticate.'
); );
} }
/**
* @dataProvider mysqlDb
*/
public function testBackendNameAssignment($db)
{
$this->setupDbProvider($db);
$testName = 'test-name-123123';
$backend = new DbUserBackend($this->createDbBackendConfig($db, $testName));
$this->assertSame($testName, $backend->getName());
}
} }

View File

@ -0,0 +1,91 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Authentication;
// @codingStandardsIgnoreStart
require_once realpath(__DIR__ . '/../../../../../library/Icinga/Test/BaseTestCase.php');
// @codingStandardsIgnoreEnd
use Icinga\Test\BaseTestCase;
// @codingStandardsIgnoreStart
require_once 'Zend/Config.php';
require_once BaseTestCase::$libDir . '/Authentication/Credentials.php';
require_once BaseTestCase::$libDir . '/Authentication/UserBackend.php';
require_once BaseTestCase::$libDir . '/User.php';
// @codingStandardsIgnoreEnd
use \Exception;
use \Zend_Config;
use \Icinga\Authentication\Credentials as Credentials;
use \Icinga\Authentication\UserBackend as UserBackend;
use \Icinga\User;
/**
* Simple backend mock that takes an config object
* with the property "credentials", which is an array
* of Credentials this backend authenticates
**/
class ErrorProneBackendMock implements UserBackend
{
public static $throwOnCreate = false;
public $name;
/**
* Creates a new object
*
* @param Zend_Config $config
* @throws Exception
*/
public function __construct(Zend_Config $config)
{
if (self::$throwOnCreate === true) {
throw new Exception('__construct error: Could not create');
}
if ($config->name) {
$this->name = $config->name;
} else {
$this->name = 'TestBackendErrorProneMock-' . uniqid();
}
}
/**
* Test if the username exists
*
* @param Credentials $credentials
*
* @return bool
* @throws Exception
*/
public function hasUsername(Credentials $credentials)
{
throw new Exception('hasUsername error: ' . $credentials->getUsername());
}
/**
* Authenticate
*
* @param Credentials $credentials
*
* @return User
* @throws Exception
*/
public function authenticate(Credentials $credentials)
{
throw new Exception('authenticate error: ' . $credentials->getUsername());
}
/**
* Name of the backend
*
* @return string
*/
public function getName()
{
return $this->name;
}
}

View File

@ -1,53 +1,106 @@
<?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 Tests\Icinga\Authentication; namespace Tests\Icinga\Authentication;
// @codingStandardsIgnoreStart
require_once realpath(__DIR__ . '/../../../../../library/Icinga/Test/BaseTestCase.php');
// @codingStandardsIgnoreEnd
use Icinga\Authentication\Credentials;
use \Icinga\Test\BaseTestCase;
// @codingStandardsIgnoreStart
require_once 'Zend/Config.php';
require_once BaseTestCase::$libDir . '/Protocol/Ldap/Connection.php';
require_once BaseTestCase::$libDir . '/Protocol/Ldap/Query.php';
require_once BaseTestCase::$libDir . '/Authentication/Credentials.php';
require_once BaseTestCase::$libDir . '/Authentication/UserBackend.php';
require_once BaseTestCase::$libDir . '/Authentication/Backend/LdapUserBackend.php';
// @codingStandardsIgnoreEnd
use \Exception;
use \Zend_Config;
use Icinga\Authentication\Backend\LdapUserBackend;
/** /**
* *
* Test class for Ldapuserbackend * Test class for Ldapuserbackend
* Created Mon, 10 Jun 2013 07:54:34 +0000 * Created Mon, 10 Jun 2013 07:54:34 +0000
* *
**/ **/
class LdapuserbackendTest extends \PHPUnit_Framework_TestCase class LdapUserBackendTest extends BaseTestCase
{ {
// Change this according to your ldap test server // Change this according to your ldap test server
const ADMIN_DN = "cn=admin,dc=icinga,dc=org"; const ADMIN_DN = 'cn=admin,dc=icinga,dc=org';
const ADMIN_PASS = "admin"; const ADMIN_PASS = 'admin';
private $users = array( private $users = array(
"cn=John Doe, dc=icinga, dc=org" => array( 'cn=Richard Miles,ou=icinga-unittest,dc=icinga,dc=org' => array(
"cn" => "John Doe", 'cn' => 'Richard Miles',
"sn" => "Doe", 'sn' => 'Miles',
"objectclass" => "inetOrgPerson", 'objectclass' => 'inetOrgPerson',
"givenName" => "John", 'givenName' => 'Richard',
"mail" => "john@doe.local" 'mail' => 'richard@doe.local',
'uid' => 'rmiles',
'userPassword' => 'passrmiles'
), ),
"cn=Jane Woe, dc=icinga, dc=org" => array( 'cn=Jane Woe,ou=icinga-unittest,dc=icinga,dc=org' => array(
"cn" => "Jane Woe", 'cn' => 'Jane Woe',
"sn" => "Woe", 'sn' => 'Woe',
"objectclass" => "inetOrgPerson", 'objectclass' => 'inetOrgPerson',
"givenName" => "Jane", 'givenName' => 'Jane',
"mail" => "jane@woe.local" 'mail' => 'jane@woe.local',
'uid' => 'jwoe',
'userPassword' => 'passjwoe'
)
);
private $baseOu = array(
'ou=icinga-unittest,dc=icinga,dc=org' => array(
'objectclass' => 'organizationalUnit',
'ou' => 'icinga-unittest'
) )
); );
private function getLDAPConnection() private function getLDAPConnection()
{ {
$this->markTestSkipped("LDAP User Backend is currently not testable, as it would require to Boostrap most of the application (see Protocol\Ldap\Connection)"); $ldapConn = ldap_connect('localhost', 389);
return;
$ldapConn = ldap_connect("localhost", 389);
if (!$ldapConn) { if (!$ldapConn) {
$this->markTestSkipped("Could not connect to test-ldap server, skipping test"); $this->markTestSkipped('Could not connect to test-ldap server, skipping test');
return null;
} }
$bind = ldap_bind($ldapConn, self::ADMIN_DN, self::ADMIN_PASS); $bind = @ldap_bind($ldapConn, self::ADMIN_DN, self::ADMIN_PASS);
if (!$bind) { if (!$bind) {
$this->markTestSkipped("Could not bind to test-ldap server, skipping test"); $this->markTestSkipped('Could not bind to test-ldap server, skipping test');
return null;
} }
return $ldapConn; return $ldapConn;
} }
@ -56,62 +109,114 @@ class LdapuserbackendTest extends \PHPUnit_Framework_TestCase
foreach ($this->users as $ou => $info) { foreach ($this->users as $ou => $info) {
@ldap_delete($connection, $ou); @ldap_delete($connection, $ou);
} }
foreach ($this->baseOu as $ou => $info) {
@ldap_delete($connection, $ou);
}
} }
private function insertTestdata($connection) private function insertTestdata($connection)
{ {
foreach ($this->users as $ou => $info) { foreach ($this->baseOu as $ou => $info) {
if (ldap_add($connection, $ou, $info) === false) { if (ldap_add($connection, $ou, $info) === false) {
$this->markTestSkipped("Couldn't set up test-ldap users, skipping test"); $this->markTestSkipped('Couldn\'t set up test-ldap users, skipping test');
} }
} }
foreach ($this->users as $ou => $info) {
if (ldap_add($connection, $ou, $info) === false) {
$this->markTestSkipped('Couldn\'t set up test-ldap users, skipping test');
}
}
} }
protected function setUp() protected function setUp()
{ {
$conn = $this->getLDAPConnection(); $conn = $this->getLDAPConnection();
if ($conn == null) {
return;
}
$this->clearTestData($conn); $this->clearTestData($conn);
$this->insertTestData($conn); $this->insertTestData($conn);
$result = ldap_list($conn, "dc=icinga, dc=org", "(cn=John Doe)");
$result = ldap_list($conn, 'ou=icinga-unittest, dc=icinga, dc=org', '(cn=Richard Miles)');
if (ldap_count_entries($conn, $result) < 1) { if (ldap_count_entries($conn, $result) < 1) {
$this->markTestSkipped("Couldn't set up test users, skipping test"); $this->markTestSkipped('Couldn\'t set up test users, skipping test');
} }
$result = ldap_list($conn, "dc=icinga, dc=org", "(cn=Jane Woe)");
$result = ldap_list($conn, 'ou=icinga-unittest, dc=icinga, dc=org', '(cn=Jane Woe)');
if (ldap_count_entries($conn, $result) < 1) { if (ldap_count_entries($conn, $result) < 1) {
$this->markTestSkipped("Couldn't set up test users, skipping test"); $this->markTestSkipped('Couldn\'t set up test users, skipping test');
} }
ldap_close($conn); ldap_close($conn);
} }
public function tearDown() public function tearDown()
{ {
$conn = $this->getLDAPConnection(); $conn = $this->getLDAPConnection();
if ($conn == null) {
return;
}
$this->clearTestData($conn); // $this->clearTestData($conn);
ldap_close($conn); ldap_close($conn);
} }
/** private function createBackendConfig()
* Test for LdapUserBackend::HasUsername()
*
**/
public function testHasUsername()
{ {
$config = new Zend_Config(
array(
'backend' => 'ldap',
'target' => 'user',
'hostname' => 'localhost',
'root_dn' => 'ou=icinga-unittest,dc=icinga,dc=org',
'bind_dn' => 'cn=admin,cn=config',
'bind_pw' => 'admin',
'user_class' => 'inetOrgPerson',
'user_name_attribute' => 'uid'
)
);
return $config;
} }
/** /**
* Test for LdapUserBackend::Authenticate() * Test for LdapUserBackend::HasUsername()
* **/
**/ public function testHasUsername()
{
$backend = new LdapUserBackend($this->createBackendConfig());
$this->assertTrue($backend->hasUsername(new Credentials('jwoe')));
$this->assertTrue($backend->hasUsername(new Credentials('rmiles')));
$this->assertFalse($backend->hasUsername(new Credentials('DoesNotExist')));
}
/**
* Test for LdapUserBackend::Authenticate()
*/
public function testAuthenticate() public function testAuthenticate()
{ {
$this->markTestIncomplete('testAuthenticate is not implemented yet'); $backend = new LdapUserBackend($this->createBackendConfig());
$this->assertInstanceOf(
'\Icinga\User',
$backend->authenticate(new Credentials('jwoe', 'passjwoe'))
);
$this->assertFalse($backend->authenticate(new Credentials('jwoe', 'passjwoe22')));
$this->assertInstanceOf(
'\Icinga\User',
$backend->authenticate(new Credentials('rmiles', 'passrmiles'))
);
$this->assertFalse($backend->authenticate(new Credentials('rmiles', 'passrmiles33')));
}
/**
* @expectedException Exception
* @expectedExceptionMessage Cannot fetch single DN for
*/
public function testAuthenticateUnknownUser()
{
$backend = new LdapUserBackend($this->createBackendConfig());
$this->assertFalse($backend->authenticate(new Credentials('unknown123', 'passunknown123')));
} }
} }

View File

@ -1,67 +1,140 @@
<?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 Tests\Icinga\Authentication; namespace Tests\Icinga\Authentication;
require_once("../../library/Icinga/Application/Logger.php"); // @codingStandardsIgnoreStart
require_once("../../library/Icinga/Authentication/Manager.php"); require_once realpath(__DIR__ . '/../../../../../library/Icinga/Test/BaseTestCase.php');
require_once("../../library/Icinga/Authentication/Credentials.php"); // @codingStandardsIgnoreEnd
require_once("Zend/Log.php");
require_once("BackendMock.php");
require_once("SessionMock.php");
use Icinga\Authentication\Manager as AuthManager; use Icinga\Application\Logger;
use Icinga\Authentication\Credentials as Credentials; use \Icinga\Test\BaseTestCase;
// @codingStandardsIgnoreStart
require_once 'Zend/Log.php';
require_once 'Zend/Config.php';
require_once BaseTestCase::$libDir . '/Application/Logger.php';
require_once BaseTestCase::$libDir . '/Authentication/Manager.php';
require_once BaseTestCase::$libDir . '/Authentication/Credentials.php';
require_once BaseTestCase::$libDir . '/Exception/ConfigurationError.php';
require_once 'BackendMock.php';
require_once 'ErrorProneBackendMock.php';
require_once 'SessionMock.php';
// @codingStandardsIgnoreEnd
use \Zend_Config;
use \Icinga\Authentication\Manager as AuthManager;
use \Icinga\Authentication\Credentials;
use \Icinga\Exception\ConfigurationError;
/** /**
* * @backupStaticAttributes enabled
* Test class for Manager */
* Created Mon, 10 Jun 2013 07:54:34 +0000 class ManagerTest extends BaseTestCase
*
**/
class ManagerTest extends \PHPUnit_Framework_TestCase
{ {
public function getTestCredentials() public function getTestCredentials()
{ {
return (object) array("credentials" => array( return array(
new Credentials("jdoe", "passjdoe"), new Credentials("jdoe", "passjdoe"),
new Credentials("root", "passroot"), new Credentials("root", "passroot"),
new Credentials("test", "passtest") new Credentials("test", "passtest")
)); );
} }
public function getManagerInstance(&$session = null, $write = false) public function getManagerInstance(
{ &$session = null,
$write = false,
$nobackend = false,
Zend_Config $managerConfig = null
) {
if ($session == null) { if ($session == null) {
$session = new SessionMock(); $session = new SessionMock();
} }
return AuthManager::getInstance(
(object) array(), if ($managerConfig === null) {
array( $managerConfig = new Zend_Config(array());
"userBackendClass" => new BackendMock( }
$this->getTestCredentials()
), $managerOptions = array(
"groupBackendClass" => new BackendMock(), 'sessionClass' => $session,
"sessionClass" => $session, 'writeSession' => $write,
"writeSession" => $write 'noDefaultConfig' => true
)
); );
$manager = AuthManager::getInstance($managerConfig, $managerOptions);
if ($nobackend === false) {
$backend = new BackendMock();
$backend->allowedCredentials = $this->getTestCredentials();
$manager->addUserBackend($backend);
}
return $manager;
} }
public function testManagerInstanciation() public function testManagerInstanciation()
{ {
AuthManager::clearInstance();
$this->setPreserveGlobalState(false);
$authMgr = $this->getManagerInstance(); $authMgr = $this->getManagerInstance();
$auth = $this->assertEquals($authMgr, AuthManager::getInstance()); $this->assertSame($authMgr, AuthManager::getInstance());
AuthManager::clearInstance(); }
public function testManagerProducingDependencies()
{
$authMgr = $this->getManagerInstance($session, true);
$this->assertSame($authMgr, AuthManager::getInstance());
$backend = new BackendMock();
$backend->setCredentials($this->getTestCredentials());
$authMgr->addUserBackend($backend);
$this->assertTrue(
$authMgr->authenticate(
new Credentials('jdoe', 'passjdoe')
)
);
$this->assertInstanceOf('Icinga\User', $authMgr->getUser());
$this->assertSame('Username', $authMgr->getUser()->getUsername());
$this->assertInstanceOf(
'Tests\Icinga\Authentication\SessionMock',
$authMgr->getSession()
);
$authMgr->removeAuthorization();
$this->assertNull($authMgr->getUser());
} }
public function testAuthentication() public function testAuthentication()
{ {
AuthManager::clearInstance();
$auth = $this->getManagerInstance(); $auth = $this->getManagerInstance();
$this->assertFalse( $this->assertFalse(
$auth->authenticate( $auth->authenticate(
@ -81,12 +154,10 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
false false
) )
); );
AuthManager::clearInstance();
} }
public function testPersistAuthInSession() public function testPersistAuthInSession()
{ {
AuthManager::clearInstance();
$session = new SessionMock(); $session = new SessionMock();
$auth = $this->getManagerInstance($session, true); $auth = $this->getManagerInstance($session, true);
$this->assertFalse($auth->isAuthenticated(true)); $this->assertFalse($auth->isAuthenticated(true));
@ -95,12 +166,10 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
$user = $session->get("user"); $user = $session->get("user");
$this->assertEquals("Username", $user->getUsername()); $this->assertEquals("Username", $user->getUsername());
$this->assertTrue($auth->isAuthenticated(true)); $this->assertTrue($auth->isAuthenticated(true));
AuthManager::clearInstance();
} }
public function testAuthenticateFromSession() public function testAuthenticateFromSession()
{ {
AuthManager::clearInstance();
$session = new SessionMock(); $session = new SessionMock();
$session->set("user", BackendMock::getDummyUser()); $session->set("user", BackendMock::getDummyUser());
$auth = $this->getManagerInstance($session, false); $auth = $this->getManagerInstance($session, false);
@ -110,18 +179,195 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
} }
/** /**
* * @expectedException Exception
**/ * @expectedExceptionMessage Session write after close
*/
public function testWriteSessionTwice() public function testWriteSessionTwice()
{ {
$exception = false; $auth = $this->getManagerInstance($session, false);
try { $this->assertFalse($auth->isAuthenticated(true));
$auth = $this->getManagerInstance($session, false); $auth->authenticate(new Credentials("jdoe", "passjdoe"));
$this->assertFalse($auth->isAuthenticated(true)); }
$auth->authenticate(new Credentials("jdoe", "passjdoe"));
} catch (\Exception $e) { /**
$exception = true; * @expectedException Icinga\Exception\ConfigurationError
} * @expectedExceptionMessage No authentication backend set
$this->assertTrue($exception); */
public function testErrorProneBackendsFromConfigurationWhenInitiate()
{
$managerConfig = new Zend_Config(
array(
'provider1' => array(
'class' => 'Tests\Icinga\Authentication\ErrorProneBackendMock'
)
),
true
);
ErrorProneBackendMock::$throwOnCreate = true;
$authManager = $this->getManagerInstance($session, true, true, $managerConfig);
$this->assertNull(
$authManager->getUserBackend('provider1')
);
$authManager->authenticate(
new Credentials('jdoe', 'passjdoe')
);
}
/**
* @expectedException Icinga\Exception\ConfigurationError
* @expectedExceptionMessage No working backend found. Unable to authenticate any
*/
public function testErrorProneBackendsFromConfigurationWhenAuthenticate()
{
$managerConfig = new Zend_Config(
array(
'provider1' => array(
'class' => 'Tests\Icinga\Authentication\ErrorProneBackendMock'
),
'provider2' => array(
'class' => 'Tests\Icinga\Authentication\ErrorProneBackendMock'
)
),
true
);
ErrorProneBackendMock::$throwOnCreate = false;
$authManager = $this->getManagerInstance($session, false, true, $managerConfig);
$this->assertInstanceOf(
'Tests\Icinga\Authentication\ErrorProneBackendMock',
$authManager->getUserBackend('provider1')
);
$this->assertInstanceOf(
'Tests\Icinga\Authentication\ErrorProneBackendMock',
$authManager->getUserBackend('provider2')
);
$authManager->authenticate(
new Credentials('jdoe', 'passjdoe')
);
}
public function testAuthenticationChainWithGoodProviders()
{
$managerConfig = new Zend_Config(
array(
'provider1' => array(
'class' => 'Tests\Icinga\Authentication\BackendMock'
),
'provider2' => array(
'class' => 'Tests\Icinga\Authentication\BackendMock'
)
),
true
);
$authManager = $this->getManagerInstance($session, true, true, $managerConfig);
$authManager->getUserBackend('provider1')->setCredentials(
array(
new Credentials('p1-user1', 'p1-passwd1'),
new Credentials('p1-user2', 'p1-passwd2')
)
);
$authManager->getUserBackend('provider2')->setCredentials(
array(
new Credentials('p2-user1', 'p2-passwd1'),
new Credentials('p2-user2', 'p2-passwd2')
)
);
$this->assertTrue(
$authManager->authenticate(new Credentials('p2-user2', 'p2-passwd2'))
);
}
public function testAuthenticationChainWithBadProviders()
{
$managerConfig = new Zend_Config(
array(
'provider1' => array(
'class' => 'Tests\Icinga\Authentication\ErrorProneBackendMock'
),
'provider2' => array(
'class' => 'Tests\Icinga\Authentication\ErrorProneBackendMock'
),
'provider3' => array(
'class' => 'Tests\Icinga\Authentication\ErrorProneBackendMock'
),
'provider4' => array(
'class' => 'Tests\Icinga\Authentication\BackendMock'
)
),
true
);
$authManager = $this->getManagerInstance($session, false, true, $managerConfig);
$this->assertInstanceOf(
'Tests\Icinga\Authentication\ErrorProneBackendMock',
$authManager->getUserBackend('provider1')
);
$this->assertInstanceOf(
'Tests\Icinga\Authentication\BackendMock',
$authManager->getUserBackend('provider4')
);
$authManager->getUserBackend('provider4')->setCredentials(
array(
new Credentials('p4-user1', 'p4-passwd1'),
new Credentials('p4-user2', 'p4-passwd2')
)
);
$session->isOpen = true;
$this->assertTrue(
$authManager->authenticate(new Credentials('p4-user2', 'p4-passwd2'))
);
$session->isOpen = true;
$this->assertTrue(
$authManager->authenticate(new Credentials('p4-user1', 'p4-passwd1'))
);
$session->isOpen = true;
$this->assertFalse(
$authManager->authenticate(new Credentials('p4-user2', 'p4-passwd1-WRONG123123'))
);
}
public function testErrorConditionsInConfiguration()
{
$managerConfig = new Zend_Config(
array(
'provider1' => array(
'backend' => 'db'
),
'provider2' => array(
'target' => 'user'
),
'provider3' => array(
'class' => 'Uhh\Ahh\WeDoNotCare123'
)
),
true
);
$authManager = $this->getManagerInstance($session, true, true, $managerConfig);
$this->assertNull($authManager->getUserBackend('provider1'));
$this->assertNull($authManager->getUserBackend('provider2'));
$this->assertNull($authManager->getUserBackend('provider3'));
} }
} }

View File

@ -1,31 +1,63 @@
<?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 Tests\Icinga\Authentication; namespace Tests\Icinga\Authentication;
require_once('../../library/Icinga/Authentication/Session.php'); // @codingStandardsIgnoreStart
require_once('../../library/Icinga/Authentication/PhpSession.php'); require_once realpath(__DIR__ . '/../../../../../library/Icinga/Test/BaseTestCase.php');
require_once('../../library/Icinga/Application/Logger.php'); // @codingStandardsIgnoreEnd
require_once('../../library/Icinga/Exception/ConfigurationError.php');
require_once('Zend/Log.php');
use Icinga\Authentication\PhpSession as PhpSession; use Icinga\Test\BaseTestCase;
class PHPSessionTest extends \PHPUnit_Framework_TestCase // @codingStandardsIgnoreStart
require_once BaseTestCase::$libDir . '/Authentication/Session.php';
require_once BaseTestCase::$libDir . '/Authentication/PhpSession.php';
require_once BaseTestCase::$libDir . '/Application/Logger.php';
require_once BaseTestCase::$libDir . '/Exception/ConfigurationError.php';
require_once 'Zend/Log.php';
// @codingStandardsIgnoreEnd
use Icinga\Authentication\PhpSession;
class PhpSessionTest extends BaseTestCase
{ {
private function getSession() private function getSession()
{ {
if (!is_writable('/tmp')) { if (!is_writable('/tmp')) {
$this->markTestSkipped('Could not write to session directory'); $this->markTestSkipped('Could not write to session directory');
return;
} }
return new PhpSession(array( return new PhpSession(
'use_cookies' => false, array(
'save_path' => '/tmp' 'use_cookies' => false,
)); 'save_path' => '/tmp'
)
);
} }
/** /**
@ -62,7 +94,7 @@ class PHPSessionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(session_id(), '', 'Asserting test precondition: session not being setup yet '); $this->assertEquals(session_id(), '', 'Asserting test precondition: session not being setup yet ');
$session = $this->getSession(); $session = $this->getSession();
$session->open(); $session->open();
$this->assertNotEquals(session_id(), '', 'Asserting a Session ID being available after PhpSession::open()'); $this->assertNotEquals(session_id(), '', 'Asserting a Session ID being available after PhpSession::open()');
$session->close(); $session->close();
} }
@ -76,8 +108,8 @@ class PHPSessionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(session_id(), '', 'Asserting test precondition: session not being setup yet '); $this->assertEquals(session_id(), '', 'Asserting test precondition: session not being setup yet ');
$session = $this->getSession(); $session = $this->getSession();
$session->open(); $session->open();
$this->assertNotEquals(session_id(), '', 'Asserting a Session ID being available after PhpSession::open()'); $this->assertNotEquals(session_id(), '', 'Asserting a Session ID being available after PhpSession::open()');
$session->purge(); $session->purge();
$this->assertEquals(session_id(), '', 'Asserting no Session ID being available after PhpSession::purge()'); $this->assertEquals(session_id(), '', 'Asserting no Session ID being available after PhpSession::purge()');
} }
} }

View File

@ -31,7 +31,6 @@ class SessionMock extends Session
public function write($keepOpen = false) public function write($keepOpen = false)
{ {
$this->open(); $this->open();
if (!$keepOpen) { if (!$keepOpen) {
$this->close(); $this->close();