Updated config structure for auth backends, and added config backend
This commit is contained in:
parent
ee1b081447
commit
0e6a90fa8f
|
@ -18,8 +18,9 @@ $defaultConfig = [
|
||||||
'config' => null
|
'config' => null
|
||||||
],
|
],
|
||||||
'authentication' => [
|
'authentication' => [
|
||||||
'default' => [
|
'native' => [
|
||||||
'plugin' => 'native',
|
'plugin' => 'native',
|
||||||
|
'prefix' => 'default',
|
||||||
'config' => null
|
'config' => null
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
|
|
@ -43,18 +43,19 @@ class UserAuth
|
||||||
public function authenticate(string $username, string $password) : int
|
public function authenticate(string $username, string $password) : int
|
||||||
{
|
{
|
||||||
if (strpos($username, '/') === false) { // no explicit backend specification
|
if (strpos($username, '/') === false) { // no explicit backend specification
|
||||||
$backend = 'default';
|
$prefix = 'default';
|
||||||
$name = $username;
|
$name = $username;
|
||||||
} else {
|
} else {
|
||||||
$parts = preg_split('/\//', $username, 2);
|
$parts = preg_split('/\//', $username, 2);
|
||||||
$backend = $parts[0];
|
$prefix = $parts[0];
|
||||||
$name = $parts[1];
|
$name = $parts[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->debug('Trying to authenticate with info', ['backend' => $backend, 'name' => $name]);
|
$this->logger->debug('Trying to authenticate with info', ['prefix' => $prefix, 'name' => $name]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($this->authenticateBackend($backend, $name, $password)) {
|
$backend = '';
|
||||||
|
if ($this->authenticateBackend($prefix, $name, $password, $backend)) {
|
||||||
return $this->localUser($backend, $name, $password);
|
return $this->localUser($backend, $name, $password);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -71,23 +72,32 @@ class UserAuth
|
||||||
* @param $backend The name of the backend to use
|
* @param $backend The name of the backend to use
|
||||||
* @param $username The username to use
|
* @param $username The username to use
|
||||||
* @param $password The password to use
|
* @param $password The password to use
|
||||||
|
* @param $backendId Output to return the backend id used
|
||||||
*
|
*
|
||||||
* @return bool true if authentication successfull false otherwise
|
* @return bool true if authentication successfull false otherwise
|
||||||
*
|
*
|
||||||
* @throws \Exceptions\PluginNotFoundExecption if no matching backend can be found
|
* @throws \Exceptions\PluginNotFoundExecption if no matching backend can be found
|
||||||
*/
|
*/
|
||||||
private function authenticateBackend(string $backend, string $username, string $password) : bool
|
private function authenticateBackend(string $backend, string $username, string $password, string &$backendId) : bool
|
||||||
{
|
{
|
||||||
$config = $this->c['config']['authentication'];
|
$config = $this->c['config']['authentication'];
|
||||||
|
|
||||||
if (!array_key_exists($backend, $config)) { // Check if backend is configured for prefix
|
$configForPrefix = array_filter($config, function ($v, $k) use ($backend) {
|
||||||
|
return $backend === $v['prefix'];
|
||||||
|
}, ARRAY_FILTER_USE_BOTH);
|
||||||
|
|
||||||
|
if (count($configForPrefix) === 0) { // Check if backend is configured for prefix
|
||||||
$this->logger->warning('No authentication backend configured for prefix', ['prefix' => $backend]);
|
$this->logger->warning('No authentication backend configured for prefix', ['prefix' => $backend]);
|
||||||
throw new PluginNotFoundException('No authentication backend configured for this user.');
|
throw new PluginNotFoundException('No authentication backend configured for this user.');
|
||||||
|
} elseif (count($configForPrefix) > 1) {
|
||||||
|
$this->logger->error('Two authentication backends configured for prefix.', ['prefix' => $backend]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$plugin = $config[$backend]['plugin'];
|
$backendId = array_keys($configForPrefix)[0];
|
||||||
|
|
||||||
|
$plugin = $config[$backendId]['plugin'];
|
||||||
$pluginClass = '\\Plugins\\UserAuth\\' . $plugin;
|
$pluginClass = '\\Plugins\\UserAuth\\' . $plugin;
|
||||||
$pluginConfig = $config[$backend]['config'];
|
$pluginConfig = $config[$backendId]['config'];
|
||||||
|
|
||||||
if (!class_exists($pluginClass)) { // Check if given backend class exists
|
if (!class_exists($pluginClass)) { // Check if given backend class exists
|
||||||
$this->logger->error('The configured UserAuth plugin does not exist', ['prefix' => $backend, 'plugin' => $plugin]);
|
$this->logger->error('The configured UserAuth plugin does not exist', ['prefix' => $backend, 'plugin' => $plugin]);
|
||||||
|
@ -102,7 +112,7 @@ class UserAuth
|
||||||
throw new PluginNotFoundException('The authentication request can not be processed.');
|
throw new PluginNotFoundException('The authentication request can not be processed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->debug("UserAuth plugin was loaded", ['plugin' => $plugin, 'prefix' => $backend]);
|
$this->logger->debug("UserAuth plugin was loaded", ['plugin' => $plugin, 'prefix' => $backend, 'backend' => $backendId]);
|
||||||
|
|
||||||
return $backendObj->authenticate($username, $password);
|
return $backendObj->authenticate($username, $password);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ interface InterfaceUserAuth
|
||||||
/**
|
/**
|
||||||
* Authenticate user.
|
* Authenticate user.
|
||||||
*
|
*
|
||||||
* @param $username The key for the entry
|
* @param $username The username for authentication
|
||||||
* @param $password The value for the entry
|
* @param $password The password for authentication
|
||||||
*
|
*
|
||||||
* @return true if valid false otherwise
|
* @return true if valid false otherwise
|
||||||
*/
|
*/
|
||||||
|
|
54
backend/src/plugins/UserAuth/config.php
Normal file
54
backend/src/plugins/UserAuth/config.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Plugins\UserAuth;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This provides a simple user auth mechanism where users can be
|
||||||
|
* stored in the config file. The config property therefore should
|
||||||
|
* be a array mapping usernames to results of password_hash()
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Config implements InterfaceUserAuth
|
||||||
|
{
|
||||||
|
/** @var \Monolog\Logger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var \PDO */
|
||||||
|
private $db;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $userList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the object
|
||||||
|
*
|
||||||
|
* @param $logger Monolog logger instance for error handling
|
||||||
|
* @param $db Database connection
|
||||||
|
* @param $config The configuration for the Plugin if any was provided
|
||||||
|
*/
|
||||||
|
public function __construct(\Monolog\Logger $logger, \PDO $db, array $config = null)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->db = $db;
|
||||||
|
$this->userList = $config ? $config : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate user.
|
||||||
|
*
|
||||||
|
* @param $username The username for authentication
|
||||||
|
* @param $password The password for authentication
|
||||||
|
*
|
||||||
|
* @return true if valid false otherwise
|
||||||
|
*/
|
||||||
|
public function authenticate(string $username, string $password) : bool
|
||||||
|
{
|
||||||
|
if (!array_key_exists($username, $this->userList)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return password_verify($password, $this->userList[$username]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,8 +5,8 @@ namespace Plugins\UserAuth;
|
||||||
require '../vendor/autoload.php';
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface provides the neccessary functions for
|
* This provides the native authentication done in the
|
||||||
* a user authentication backend.
|
* PDNSManager database.
|
||||||
*/
|
*/
|
||||||
class Native implements InterfaceUserAuth
|
class Native implements InterfaceUserAuth
|
||||||
{
|
{
|
||||||
|
@ -32,8 +32,8 @@ class Native implements InterfaceUserAuth
|
||||||
/**
|
/**
|
||||||
* Authenticate user.
|
* Authenticate user.
|
||||||
*
|
*
|
||||||
* @param $username The key for the entry
|
* @param $username The username for authentication
|
||||||
* @param $password The value for the entry
|
* @param $password The password for authentication
|
||||||
*
|
*
|
||||||
* @return true if valid false otherwise
|
* @return true if valid false otherwise
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,13 +18,17 @@ return [
|
||||||
'path' => '../../test/logfile.log'
|
'path' => '../../test/logfile.log'
|
||||||
],
|
],
|
||||||
'authentication' => [
|
'authentication' => [
|
||||||
'default' => [
|
'native' => [
|
||||||
'plugin' => 'native',
|
'plugin' => 'native',
|
||||||
|
'prefix' => 'default',
|
||||||
'config' => null
|
'config' => null
|
||||||
],
|
],
|
||||||
'foo' => [
|
'foo' => [
|
||||||
'plugin' => 'native',
|
'plugin' => 'config',
|
||||||
'config' => null
|
'prefix' => 'foo',
|
||||||
|
'config' => [
|
||||||
|
'admin' => '\$2y\$10\$u9ji0cGRpd/doYEF/AztkOP3qmaaDYOGXzs0PmnGbMF7sJYzODDbO'
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
|
@ -49,7 +49,7 @@ test.run(async function () {
|
||||||
|
|
||||||
assert.equal(res.status, 422, 'Status not valid');
|
assert.equal(res.status, 422, 'Status not valid');
|
||||||
|
|
||||||
//Try to login with invalid username and password
|
//Try to login with prefix
|
||||||
var res = await req({
|
var res = await req({
|
||||||
url: '/sessions',
|
url: '/sessions',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
|
|
Loading…
Reference in a new issue