]> git.mxchange.org Git - friendica.git/commitdiff
Refactor ExAuth for DICE
authorPhilipp Holzer <admin+github@philipp.info>
Sat, 27 Jul 2019 22:14:39 +0000 (00:14 +0200)
committerHypolite Petovan <hypolite@mrpetovan.com>
Tue, 21 Jul 2020 06:30:12 +0000 (02:30 -0400)
bin/auth_ejabberd.php
src/Model/User.php
src/Util/ExAuth.php

index f00615f02be452a4b0e3ae458d903e4c6e13fe71..fa71faf263915b45c334ca4ce0694f3f41485b9b 100755 (executable)
@@ -80,6 +80,7 @@ $dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['auth_ejabb
 $appMode = $dice->create(Mode::class);
 
 if ($appMode->isNormal()) {
-       $oAuth = new ExAuth();
+       /** @var ExAuth $oAuth */
+       $oAuth = $dice->create(ExAuth::class);
        $oAuth->readStdin();
 }
index 3dbf88f288c883e50be93157b7e88d5414299126..c12ac31cdc694325327e0f0beecb91e514fd2fee 100644 (file)
@@ -321,7 +321,8 @@ class User
         * @param string $password
         * @param bool   $third_party
         * @return int User Id if authentication is successful
-        * @throws Exception
+        * @throws HTTPException\ForbiddenException
+        * @throws HTTPException\NotFoundException
         */
        public static function getIdFromPasswordAuthentication($user_info, $password, $third_party = false)
        {
@@ -356,7 +357,7 @@ class User
                        return $user['uid'];
                }
 
-               throw new Exception(DI::l10n()->t('Login failed'));
+               throw new HTTPException\ForbiddenException(DI::l10n()->t('Login failed'));
        }
 
        /**
@@ -370,7 +371,7 @@ class User
         *
         * @param mixed $user_info
         * @return array
-        * @throws Exception
+        * @throws HTTPException\NotFoundException
         */
        private static function getAuthenticationInfo($user_info)
        {
@@ -414,7 +415,7 @@ class User
                        }
 
                        if (!DBA::isResult($user)) {
-                               throw new Exception(DI::l10n()->t('User not found'));
+                               throw new HTTPException\NotFoundException(DI::l10n()->t('User not found'));
                        }
                }
 
index de13ee82f5964109794552572e76a6ae6c8cf307..9a531b5f7510ab88e64ab932b96829117dc70c83 100644 (file)
 
 namespace Friendica\Util;
 
-use Friendica\Database\DBA;
-use Friendica\DI;
+use Exception;
+use Friendica\App;
+use Friendica\Core\Config\IConfig;
+use Friendica\Core\PConfig\IPConfig;
+use Friendica\Database\Database;
 use Friendica\Model\User;
+use Friendica\Network\HTTPException;
 
 class ExAuth
 {
@@ -44,12 +48,43 @@ class ExAuth
        private $host;
 
        /**
-        * Create the class
-        *
+        * @var App\Mode
+        */
+       private $appMode;
+       /**
+        * @var IConfig
+        */
+       private $config;
+       /**
+        * @var IPConfig
+        */
+       private $pConfig;
+       /**
+        * @var Database
+        */
+       private $dba;
+       /**
+        * @var App\BaseURL
+        */
+       private $baseURL;
+
+       /**
+        * @param App\Mode    $appMode
+        * @param IConfig      $config
+        * @param IPConfig     $pConfig
+        * @param Database    $dba
+        * @param App\BaseURL $baseURL
+        * @throws Exception
         */
-       public function __construct()
+       public function __construct(App\Mode $appMode, IConfig $config, IPConfig $pConfig, Database $dba, App\BaseURL $baseURL)
        {
-               $this->bDebug = (int) DI::config()->get('jabber', 'debug');
+               $this->appMode = $appMode;
+               $this->config  = $config;
+               $this->pConfig = $pConfig;
+               $this->dba     = $dba;
+               $this->baseURL = $baseURL;
+
+               $this->bDebug = (int)$config->get('jabber', 'debug');
 
                openlog('auth_ejabberd', LOG_PID, LOG_USER);
 
@@ -60,14 +95,18 @@ class ExAuth
         * Standard input reading function, executes the auth with the provided
         * parameters
         *
-        * @return null
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @throws HTTPException\InternalServerErrorException
         */
        public function readStdin()
        {
+               if (!$this->appMode->isNormal()) {
+                       $this->writeLog(LOG_ERR, 'The node isn\'t ready.');
+                       return;
+               }
+
                while (!feof(STDIN)) {
                        // Quit if the database connection went down
-                       if (!DBA::connected()) {
+                       if (!$this->dba->isConnected()) {
                                $this->writeLog(LOG_ERR, 'the database connection went down');
                                return;
                        }
@@ -123,7 +162,7 @@ class ExAuth
         * Check if the given username exists
         *
         * @param array $aCommand The command array
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @throws HTTPException\InternalServerErrorException
         */
        private function isUser(array $aCommand)
        {
@@ -142,9 +181,9 @@ class ExAuth
                $sUser = str_replace(['%20', '(a)'], [' ', '@'], $aCommand[1]);
 
                // Does the hostname match? So we try directly
-               if (DI::baseUrl()->getHostname() == $aCommand[2]) {
+               if ($this->baseURL->getHostname() == $aCommand[2]) {
                        $this->writeLog(LOG_INFO, 'internal user check for ' . $sUser . '@' . $aCommand[2]);
-                       $found = DBA::exists('user', ['nickname' => $sUser]);
+                       $found = $this->dba->exists('user', ['nickname' => $sUser]);
                } else {
                        $found = false;
                }
@@ -173,7 +212,7 @@ class ExAuth
         * @param boolean $ssl  Should the check be done via SSL?
         *
         * @return boolean Was the user found?
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @throws HTTPException\InternalServerErrorException
         */
        private function checkUser($host, $user, $ssl)
        {
@@ -203,7 +242,7 @@ class ExAuth
         * Authenticate the given user and password
         *
         * @param array $aCommand The command array
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @throws Exception
         */
        private function auth(array $aCommand)
        {
@@ -221,35 +260,29 @@ class ExAuth
                // We now check if the password match
                $sUser = str_replace(['%20', '(a)'], [' ', '@'], $aCommand[1]);
 
+               $Error = false;
                // Does the hostname match? So we try directly
-               if (DI::baseUrl()->getHostname() == $aCommand[2]) {
-                       $this->writeLog(LOG_INFO, 'internal auth for ' . $sUser . '@' . $aCommand[2]);
-
-                       $aUser = DBA::selectFirst('user', ['uid', 'password', 'legacy_password'], ['nickname' => $sUser]);
-                       if (DBA::isResult($aUser)) {
-                               $uid = $aUser['uid'];
-                               $success = User::authenticate($aUser, $aCommand[3], true);
-                               $Error = $success === false;
-                       } else {
-                               $this->writeLog(LOG_WARNING, 'user not found: ' . $sUser);
-                               $Error = true;
-                               $uid = -1;
-                       }
-                       if ($Error) {
+               if ($this->baseURL->getHostname() == $aCommand[2]) {
+                       try {
+                               $this->writeLog(LOG_INFO, 'internal auth for ' . $sUser . '@' . $aCommand[2]);
+                               User::getIdFromPasswordAuthentication($sUser, $aCommand[3], true);
+                       } catch (HTTPException\ForbiddenException $ex) {
+                               // User exists, authentication failed
                                $this->writeLog(LOG_INFO, 'check against alternate password for ' . $sUser . '@' . $aCommand[2]);
-                               $sPassword = DI::pConfig()->get($uid, 'xmpp', 'password', null, true);
+                               $aUser = User::getByNickname($sUser, ['uid']);
+                               $sPassword = $this->pConfig->get($aUser['uid'], 'xmpp', 'password', null, true);
                                $Error = ($aCommand[3] != $sPassword);
+                       } catch (\Throwable $ex) {
+                               // User doesn't exist and any other failure case
+                               $this->writeLog(LOG_WARNING, $ex->getMessage() . ': ' . $sUser);
+                               $Error = true;
                        }
                } else {
                        $Error = true;
                }
 
                // If the hostnames doesn't match or there is some failure, we try to check remotely
-               if ($Error) {
-                       $Error = !$this->checkCredentials($aCommand[2], $aCommand[1], $aCommand[3], true);
-               }
-
-               if ($Error) {
+               if ($Error && !$this->checkCredentials($aCommand[2], $aCommand[1], $aCommand[3], true)) {
                        $this->writeLog(LOG_WARNING, 'authentification failed for user ' . $sUser . '@' . $aCommand[2]);
                        fwrite(STDOUT, pack('nn', 2, 0));
                } else {
@@ -297,7 +330,6 @@ class ExAuth
         * Set the hostname for this process
         *
         * @param string $host The hostname
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        private function setHost($host)
        {
@@ -309,7 +341,7 @@ class ExAuth
 
                $this->host = $host;
 
-               $lockpath = DI::config()->get('jabber', 'lockpath');
+               $lockpath = $this->config->get('jabber', 'lockpath');
                if (is_null($lockpath)) {
                        $this->writeLog(LOG_INFO, 'No lockpath defined.');
                        return;