浏览代码

Updated config structure for auth backends, and added config backend

Lukas Metzger 7 年之前
父节点
当前提交
0e6a90fa8f

+ 2 - 1
backend/src/config/ConfigDefault.php

@@ -18,8 +18,9 @@ $defaultConfig = [
         'config' => null
     ],
     'authentication' => [
-        'default' => [
+        'native' => [
             'plugin' => 'native',
+            'prefix' => 'default',
             'config' => null
         ]
     ],

+ 19 - 9
backend/src/operations/UserAuth.php

@@ -43,18 +43,19 @@ class UserAuth
     public function authenticate(string $username, string $password) : int
     {
         if (strpos($username, '/') === false) { // no explicit backend specification
-            $backend = 'default';
+            $prefix = 'default';
             $name = $username;
         } else {
             $parts = preg_split('/\//', $username, 2);
-            $backend = $parts[0];
+            $prefix = $parts[0];
             $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 {
-            if ($this->authenticateBackend($backend, $name, $password)) {
+            $backend = '';
+            if ($this->authenticateBackend($prefix, $name, $password, $backend)) {
                 return $this->localUser($backend, $name, $password);
             } else {
                 return -1;
@@ -71,23 +72,32 @@ class UserAuth
      * @param   $backend    The name of the backend to use
      * @param   $username   The username 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
      * 
      * @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'];
 
-        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]);
             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;
-        $pluginConfig = $config[$backend]['config'];
+        $pluginConfig = $config[$backendId]['config'];
 
         if (!class_exists($pluginClass)) { // Check if given backend class exists
             $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.');
         }
 
-        $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);
     }

+ 2 - 2
backend/src/plugins/UserAuth/InterfaceUserAuth.php

@@ -22,8 +22,8 @@ interface InterfaceUserAuth
     /**
      * Authenticate user.
      * 
-     * @param   $username   The key for the entry
-     * @param   $password   The value for the entry
+     * @param   $username   The username for authentication
+     * @param   $password   The password for authentication
      * 
      * @return  true if valid false otherwise
      */

+ 54 - 0
backend/src/plugins/UserAuth/config.php

@@ -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]);
+    }
+}

+ 4 - 4
backend/src/plugins/UserAuth/native.php

@@ -5,8 +5,8 @@ namespace Plugins\UserAuth;
 require '../vendor/autoload.php';
 
 /**
- * This interface provides the neccessary functions for
- * a user authentication backend.
+ * This provides the native authentication done in the
+ * PDNSManager database.
  */
 class Native implements InterfaceUserAuth
 {
@@ -32,8 +32,8 @@ class Native implements InterfaceUserAuth
     /**
      * Authenticate user.
      * 
-     * @param   $username   The key for the entry
-     * @param   $password   The value for the entry
+     * @param   $username   The username for authentication
+     * @param   $password   The password for authentication
      * 
      * @return  true if valid false otherwise
      */

+ 7 - 3
backend/test/test.sh

@@ -18,13 +18,17 @@ return [
         'path' => '../../test/logfile.log'
     ],
     'authentication' => [
-        'default' => [
+        'native' => [
             'plugin' => 'native',
+            'prefix' => 'default',
             'config' => null
         ],
         'foo' => [
-            'plugin' => 'native',
-            'config' => null
+            'plugin' => 'config',
+            'prefix' => 'foo',
+            'config' => [
+                'admin' => '\$2y\$10\$u9ji0cGRpd/doYEF/AztkOP3qmaaDYOGXzs0PmnGbMF7sJYzODDbO'
+            ]
         ]
     ]
 ];

+ 1 - 1
backend/test/tests/session.js

@@ -49,7 +49,7 @@ test.run(async function () {
 
         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({
             url: '/sessions',
             method: 'post',