Change 'user' table to 'account', error handling and docs
Fix installation instructions for postgresql, the user table is now 'account', as user is a keyword in some rdbms, now catching exceptions and returning auth failed while logging errors refs #3769
This commit is contained in:
parent
ce95511890
commit
306a51271b
|
@ -1,7 +1,7 @@
|
||||||
[users]
|
[users]
|
||||||
backend=Db
|
backend=Db
|
||||||
dbtype=mysql
|
dbtype=pgsql
|
||||||
table=user
|
table=account
|
||||||
host=localhost
|
host=localhost
|
||||||
password=icinga
|
password=icinga
|
||||||
user=icingaweb
|
user=icingaweb
|
||||||
|
|
|
@ -43,7 +43,7 @@ your backend, take a look at the various options described in `./configure --hel
|
||||||
It is required to set up all used Databases correctly, which basically means to create all needed user accounts and to
|
It is required to set up all used Databases correctly, which basically means to create all needed user accounts and to
|
||||||
create all database tables. You will find the installation guides for the different databases in the sections below:
|
create all database tables. You will find the installation guides for the different databases in the sections below:
|
||||||
|
|
||||||
*IMPORTANT*: Select a secure password instead of "icinga" and alter the config/*.ini accordingly.
|
*IMPORTANT*: Select a secure password instead of "icinga" and alter the config/authentication.ini accordingly.
|
||||||
|
|
||||||
|
|
||||||
#### MySQL
|
#### MySQL
|
||||||
|
@ -80,8 +80,18 @@ create all database tables. You will find the installation guides for the differ
|
||||||
2. Create all tables (You need to be in the icinga2-web folder)
|
2. Create all tables (You need to be in the icinga2-web folder)
|
||||||
|
|
||||||
|
|
||||||
bash$ psql -d icingaweb -a -f etc/schema/users.mysql.sql
|
bash$ psql -U icingaweb -a -f etc/schema/users.pgsql.sql
|
||||||
|
|
||||||
|
3. Enable trust authentication on localhost
|
||||||
|
|
||||||
|
Add the following lines to your pg_hba.conf (etc/postgresql/X.x/main/pg_hba.conf under debian, /var/lib/pgsql/data/pg_hba.conf for Redhat/Fedora)
|
||||||
|
to enable trust authentication for the icingaweb user when connecting from the localhost.
|
||||||
|
|
||||||
|
local icingaweb icingaweb trust
|
||||||
|
host icingaweb icingaweb 127.0.0.1/32 trust
|
||||||
|
host icingaweb icingaweb ::1/128 trust
|
||||||
|
|
||||||
|
And restart your databse ('service postgresql restart' or '/etc/init.d/postgresql-X.x reload')
|
||||||
|
|
||||||
Quick and Dirty
|
Quick and Dirty
|
||||||
----------------
|
----------------
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
create table user (
|
create table account (
|
||||||
user_name varchar(255) NOT NULL,
|
user_name varchar(255) NOT NULL,
|
||||||
first_name varchar(255),
|
first_name varchar(255),
|
||||||
last_name varchar(255),
|
last_name varchar(255),
|
||||||
|
@ -15,7 +15,7 @@ create table user (
|
||||||
* user: icingaadmin
|
* user: icingaadmin
|
||||||
* password: icinga
|
* password: icinga
|
||||||
*/
|
*/
|
||||||
INSERT INTO user (
|
INSERT INTO account (
|
||||||
user_name,
|
user_name,
|
||||||
salt,
|
salt,
|
||||||
password,
|
password,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
create table "user" (
|
create table "account" (
|
||||||
user_name varchar(255) NOT NULL,
|
user_name varchar(255) NOT NULL,
|
||||||
first_name varchar(255),
|
first_name varchar(255),
|
||||||
last_name varchar(255),
|
last_name varchar(255),
|
||||||
|
@ -15,7 +15,7 @@ create table "user" (
|
||||||
* user: icingaadmin
|
* user: icingaadmin
|
||||||
* password: icinga
|
* password: icinga
|
||||||
*/
|
*/
|
||||||
INSERT INTO "user" (
|
INSERT INTO "account" (
|
||||||
user_name,
|
user_name,
|
||||||
salt,
|
salt,
|
||||||
password,
|
password,
|
||||||
|
|
|
@ -33,7 +33,7 @@ use Icinga\Authentication\User as 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticates users using a sql db as backend.
|
* Authenticates users using a sql db as backend.
|
||||||
|
@ -41,26 +41,41 @@ use Icinga\Authentication;
|
||||||
*/
|
*/
|
||||||
class DbUserBackend implements UserBackend {
|
class DbUserBackend implements UserBackend {
|
||||||
|
|
||||||
private $db;
|
/**
|
||||||
|
* The database connection that will be used for fetching users
|
||||||
|
*
|
||||||
|
* @var \Zend_Db
|
||||||
|
*/
|
||||||
|
private $db = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the user table as provided by the configuration
|
||||||
|
*
|
||||||
|
* @var String
|
||||||
|
*/
|
||||||
private $userTable;
|
private $userTable;
|
||||||
|
|
||||||
private $USER_NAME_COLUMN = "user_name",
|
/**
|
||||||
$FIRST_NAME_COLUMN = "first_name",
|
* Mapping of columns
|
||||||
$LAST_NAME_COLUMN = "last_name",
|
*
|
||||||
$LAST_LOGIN_COLUMN = "last_login",
|
* @var string
|
||||||
$SALT_COLUMN = "salt",
|
*/
|
||||||
$PASSWORD_COLUMN = "password",
|
private $USER_NAME_COLUMN = 'user_name',
|
||||||
$ACTIVE_COLUMN = "active",
|
$FIRST_NAME_COLUMN = 'first_name',
|
||||||
$DOMAIN_COLUMN = "domain",
|
$LAST_NAME_COLUMN = 'last_name',
|
||||||
$EMAIL_COLUMN = "email";
|
$LAST_LOGIN_COLUMN = 'last_login',
|
||||||
|
$SALT_COLUMN = 'salt',
|
||||||
|
$PASSWORD_COLUMN = 'password',
|
||||||
|
$ACTIVE_COLUMN = 'active',
|
||||||
|
$DOMAIN_COLUMN = 'domain',
|
||||||
|
$EMAIL_COLUMN = 'email';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* maps the configuration dbtypes to the corresponding Zend-PDOs
|
* maps the configuration dbtypes to the corresponding Zend-PDOs
|
||||||
*/
|
*/
|
||||||
private $dbTypeMap = Array(
|
private $dbTypeMap = Array(
|
||||||
"mysql" => "PDO_MYSQL",
|
'mysql' => 'PDO_MYSQL',
|
||||||
"pgsql" => "PDO_PGSQL"
|
'pgsql' => 'PDO_PGSQL'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,7 +87,7 @@ class DbUserBackend implements UserBackend {
|
||||||
{
|
{
|
||||||
$this->dbtype = $config->dbtype;
|
$this->dbtype = $config->dbtype;
|
||||||
$this->userTable = $config->table;
|
$this->userTable = $config->table;
|
||||||
|
try {
|
||||||
$this->db = \Zend_Db::factory(
|
$this->db = \Zend_Db::factory(
|
||||||
$this->dbTypeMap[$config->dbtype],
|
$this->dbTypeMap[$config->dbtype],
|
||||||
array(
|
array(
|
||||||
|
@ -86,7 +101,12 @@ class DbUserBackend implements UserBackend {
|
||||||
* Test the connection settings
|
* Test the connection settings
|
||||||
*/
|
*/
|
||||||
$this->db->getConnection();
|
$this->db->getConnection();
|
||||||
$this->db->select()->from($this->userTable,new \Zend_Db_Expr("TRUE"));
|
$this->db->select()->from($this->userTable,new \Zend_Db_Expr('TRUE'));
|
||||||
|
} catch (\Zend_Db_Adapter_Exception $exc) {
|
||||||
|
Logger::error('Could not authenticate via database : %s ', $exc->getMessage());
|
||||||
|
$this->db = null;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,6 +117,10 @@ class DbUserBackend implements UserBackend {
|
||||||
*/
|
*/
|
||||||
public function hasUsername(Credentials $credential)
|
public function hasUsername(Credentials $credential)
|
||||||
{
|
{
|
||||||
|
if ($this->db === null) {
|
||||||
|
Logger::warn('Ignoring hasUsername in database as no connection is available');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$user = $this->getUserByName($credential->getUsername());
|
$user = $this->getUserByName($credential->getUsername());
|
||||||
return !empty($user);
|
return !empty($user);
|
||||||
}
|
}
|
||||||
|
@ -109,12 +133,16 @@ class DbUserBackend implements UserBackend {
|
||||||
*/
|
*/
|
||||||
public function authenticate(Credentials $credential)
|
public function authenticate(Credentials $credential)
|
||||||
{
|
{
|
||||||
|
if ($this->db === null) {
|
||||||
|
Logger::warn('Ignoring database authentication as no connection is available');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
$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())
|
||||||
)
|
)
|
||||||
|
@ -137,7 +165,7 @@ class DbUserBackend implements UserBackend {
|
||||||
$this->db->update(
|
$this->db->update(
|
||||||
$this->userTable,
|
$this->userTable,
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
@ -166,6 +194,11 @@ class DbUserBackend implements UserBackend {
|
||||||
*/
|
*/
|
||||||
private function getUserByName($username)
|
private function getUserByName($username)
|
||||||
{
|
{
|
||||||
|
if ($this->db === null) {
|
||||||
|
Logger::warn('Ignoring getUserByName as no database connection is available');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
$this->db->getConnection();
|
$this->db->getConnection();
|
||||||
$res = $this->db->
|
$res = $this->db->
|
||||||
select()->from($this->userTable)
|
select()->from($this->userTable)
|
||||||
|
@ -176,6 +209,10 @@ class DbUserBackend implements UserBackend {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return $this->createUserFromResult($res);
|
return $this->createUserFromResult($res);
|
||||||
|
} catch (\Zend_Db_Statement_Exception $exc) {
|
||||||
|
Logger::error("Could not fetch users from db : %s ", $exc->getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,14 +8,14 @@ namespace Tests\Icinga\Authentication;
|
||||||
//use Icinga\Protocol\Ldap\Exception;
|
//use Icinga\Protocol\Ldap\Exception;
|
||||||
//use Zend_Config_Ini;
|
//use Zend_Config_Ini;
|
||||||
|
|
||||||
require_once("Zend/Config/Ini.php");
|
require_once('Zend/Config/Ini.php');
|
||||||
require_once("Zend/Db.php");
|
require_once('Zend/Db.php');
|
||||||
require_once("../../library/Icinga/Authentication/UserBackend.php");
|
require_once('../../library/Icinga/Authentication/UserBackend.php');
|
||||||
require_once("../../library/Icinga/Protocol/Ldap/Exception.php");
|
require_once('../../library/Icinga/Protocol/Ldap/Exception.php');
|
||||||
require_once("../../library/Icinga/Application/Config.php");
|
require_once('../../library/Icinga/Application/Config.php');
|
||||||
require_once("../../library/Icinga/Authentication/Credentials.php");
|
require_once('../../library/Icinga/Authentication/Credentials.php');
|
||||||
require_once("../../library/Icinga/Authentication/Backend/DbUserBackend.php");
|
require_once('../../library/Icinga/Authentication/Backend/DbUserBackend.php');
|
||||||
require_once("../../library/Icinga/Authentication/User.php");
|
require_once('../../library/Icinga/Authentication/User.php');
|
||||||
|
|
||||||
use Icinga\Authentication\Backend\DbUserBackend;
|
use Icinga\Authentication\Backend\DbUserBackend;
|
||||||
use Icinga\Util\Crypto;
|
use Icinga\Util\Crypto;
|
||||||
|
@ -33,21 +33,21 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
|
|
||||||
private $dbUserBackend;
|
private $dbUserBackend;
|
||||||
private $db;
|
private $db;
|
||||||
private $testTable = "icinga_users_test";
|
private $testTable = 'account';
|
||||||
private $testDatabase = "icinga_unittest";
|
private $testDatabase = 'icinga_unittest';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must be identical with the column names defined in DbUserBackend
|
* Must be identical with the column names defined in DbUserBackend
|
||||||
*/
|
*/
|
||||||
private $USER_NAME_COLUMN = "user_name",
|
private $USER_NAME_COLUMN = 'user_name',
|
||||||
$FIRST_NAME_COLUMN = "first_name",
|
$FIRST_NAME_COLUMN = 'first_name',
|
||||||
$LAST_NAME_COLUMN = "last_name",
|
$LAST_NAME_COLUMN = 'last_name',
|
||||||
$LAST_LOGIN_COLUMN = "last_login",
|
$LAST_LOGIN_COLUMN = 'last_login',
|
||||||
$SALT_COLUMN = "salt",
|
$SALT_COLUMN = 'salt',
|
||||||
$PASSWORD_COLUMN = "password",
|
$PASSWORD_COLUMN = 'password',
|
||||||
$ACTIVE_COLUMN = "active",
|
$ACTIVE_COLUMN = 'active',
|
||||||
$DOMAIN_COLUMN = "domain",
|
$DOMAIN_COLUMN = 'domain',
|
||||||
$EMAIL_COLUMN = "email";
|
$EMAIL_COLUMN = 'email';
|
||||||
|
|
||||||
private $users;
|
private $users;
|
||||||
private $mysql;
|
private $mysql;
|
||||||
|
@ -67,9 +67,9 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
private function getBackendConfig()
|
private function getBackendConfig()
|
||||||
{
|
{
|
||||||
$config = new \stdClass();
|
$config = new \stdClass();
|
||||||
$config->host = "127.0.0.1";
|
$config->host = '127.0.0.1';
|
||||||
$config->user = "icinga_unittest";
|
$config->user = 'icinga_unittest';
|
||||||
$config->password= "icinga_unittest";
|
$config->password= 'icinga_unittest';
|
||||||
$config->table = $this->testTable;
|
$config->table = $this->testTable;
|
||||||
$config->db = $this->testDatabase;
|
$config->db = $this->testDatabase;
|
||||||
return $config;
|
return $config;
|
||||||
|
@ -78,7 +78,7 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
/**
|
/**
|
||||||
* Create a backend with the given database type
|
* Create a backend with the given database type
|
||||||
*
|
*
|
||||||
* @param $dbType The database type as a string, like "mysql" or "pgsql".
|
* @param $dbType The database type as a string, like 'mysql' or 'pgsql'.
|
||||||
* @return DbUserBackend|null
|
* @return DbUserBackend|null
|
||||||
*/
|
*/
|
||||||
private function createBackend($dbType)
|
private function createBackend($dbType)
|
||||||
|
@ -90,7 +90,7 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
$this->setUpDb($db);
|
$this->setUpDb($db);
|
||||||
return new DbUserBackend($config);
|
return new DbUserBackend($config);
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
echo "CREATE_BACKEND_ERROR:".$e->getMessage();
|
echo 'CREATE_BACKEND_ERROR:'.$e->getMessage();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,8 +120,8 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
$this->ACTIVE_COLUMN => 0
|
$this->ACTIVE_COLUMN => 0
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->mysql = $this->createBackend("mysql");
|
$this->mysql = $this->createBackend('mysql');
|
||||||
$this->pgsql = $this->createBackend("pgsql");
|
$this->pgsql = $this->createBackend('pgsql');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,7 +134,7 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
$this->runBackendUsername($this->pgsql);
|
$this->runBackendUsername($this->pgsql);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
echo "\nSKIPPING PGSQL TEST...\n";
|
echo '\nSKIPPING PGSQL TEST...\n';
|
||||||
$this->markTestSkipped();
|
$this->markTestSkipped();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
$this->runBackendUsername($this->mysql);
|
$this->runBackendUsername($this->mysql);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
echo "\nSKIPPING MYSQL TEST...\n";
|
echo '\nSKIPPING MYSQL TEST...\n';
|
||||||
$this->markTestSkipped();
|
$this->markTestSkipped();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
/**
|
/**
|
||||||
* Create a database with the given config and type
|
* Create a database with the given config and type
|
||||||
*
|
*
|
||||||
* @param $dbtype The database type as a string, like "mysql" or "pgsql".
|
* @param $dbtype The database type as a string, like 'mysql' or 'pgsql'.
|
||||||
* @param $config The configuration-object.
|
* @param $config The configuration-object.
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
@ -168,7 +168,7 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
'host' => $config->host,
|
'host' => $config->host,
|
||||||
'username' => $config->user,
|
'username' => $config->user,
|
||||||
'password' => $config->password,
|
'password' => $config->password,
|
||||||
"dbname" => "icinga_unittest"
|
'dbname' => 'icinga_unittest'
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,11 +178,11 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
public function tearDown()
|
public function tearDown()
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
$db = $this->createDb("mysql",$this->getBackendConfig());
|
$db = $this->createDb('mysql',$this->getBackendConfig());
|
||||||
$this->tearDownDb($db);
|
$this->tearDownDb($db);
|
||||||
} catch(\Exception $e) { }
|
} catch(\Exception $e) { }
|
||||||
try {
|
try {
|
||||||
$db = $this->createDb("pgsql",$this->getBackendConfig());
|
$db = $this->createDb('pgsql',$this->getBackendConfig());
|
||||||
$this->tearDownDb($db);
|
$this->tearDownDb($db);
|
||||||
} catch(\Exception $e) { }
|
} catch(\Exception $e) { }
|
||||||
}
|
}
|
||||||
|
@ -204,6 +204,11 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
*/
|
*/
|
||||||
private function setUpDb($db)
|
private function setUpDb($db)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
|
$this->tearDownDb($db);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// if no database exists, an exception will be thrown
|
||||||
|
}
|
||||||
$db->exec('CREATE TABLE '.$this->testTable.' (
|
$db->exec('CREATE TABLE '.$this->testTable.' (
|
||||||
'.$this->USER_NAME_COLUMN.' varchar(255) NOT NULL,
|
'.$this->USER_NAME_COLUMN.' varchar(255) NOT NULL,
|
||||||
'.$this->FIRST_NAME_COLUMN.' varchar(255),
|
'.$this->FIRST_NAME_COLUMN.' varchar(255),
|
||||||
|
@ -220,7 +225,7 @@ class DbUserBackendTest extends \PHPUnit_Framework_TestCase {
|
||||||
$usr = $this->users[$i];
|
$usr = $this->users[$i];
|
||||||
$data = Array(
|
$data = Array(
|
||||||
$this->USER_NAME_COLUMN => $usr[$this->USER_NAME_COLUMN],
|
$this->USER_NAME_COLUMN => $usr[$this->USER_NAME_COLUMN],
|
||||||
$this->PASSWORD_COLUMN => hash_hmac("sha256",
|
$this->PASSWORD_COLUMN => hash_hmac('sha256',
|
||||||
$usr[$this->SALT_COLUMN],
|
$usr[$this->SALT_COLUMN],
|
||||||
$usr[$this->PASSWORD_COLUMN]
|
$usr[$this->PASSWORD_COLUMN]
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in New Issue