move OTP check from login controller check to onAdminLoginEvent for webauthn compatibility

This commit is contained in:
Daniel Seifert 2022-11-24 00:51:56 +01:00
parent 749c654b4e
commit c86984df5f
Signed by: DanielS
GPG Key ID: 6A513E13AEE66170
7 changed files with 151 additions and 15 deletions

View File

@ -19,8 +19,10 @@ use D3\Totp\Application\Model\d3backupcodelist;
use D3\Totp\Application\Model\d3totp; use D3\Totp\Application\Model\d3totp;
use D3\Totp\Application\Model\d3totp_conf; use D3\Totp\Application\Model\d3totp_conf;
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException; use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
use D3\Totp\Modules\Application\Controller\Admin\d3_totp_LoginController;
use D3\Totp\Modules\Application\Model\d3_totp_user; use D3\Totp\Modules\Application\Model\d3_totp_user;
use OxidEsales\Eshop\Application\Controller\Admin\AdminController; use OxidEsales\Eshop\Application\Controller\Admin\AdminController;
use OxidEsales\Eshop\Application\Controller\Admin\LoginController;
use OxidEsales\Eshop\Application\Model\User; use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
@ -85,6 +87,9 @@ class d3totpadminlogin extends AdminController
$this->d3TotpGetUtils()->redirect('index.php?cl=login'); $this->d3TotpGetUtils()->redirect('index.php?cl=login');
} }
$this->addTplParam('selectedProfile', Registry::getRequest()->getRequestEscapedParameter('profile'));
$this->addTplParam('selectedChLanguage', Registry::getRequest()->getRequestEscapedParameter('chlanguage'));
return parent::render(); return parent::render();
} }
@ -154,14 +159,20 @@ class d3totpadminlogin extends AdminController
$this->d3TotpHasValidTotp($sTotp, $totp); $this->d3TotpHasValidTotp($sTotp, $totp);
$adminProfiles = $session->getVariable("aAdminProfiles"); $selectedProfile = Registry::getRequest()->getRequestEscapedParameter('profile');
$selectedLanguage = Registry::getRequest()->getRequestEscapedParameter('chlanguage');
$session->initNewSession(); $session->initNewSession();
$session->setVariable("aAdminProfiles", $adminProfiles); $session->setVariable(d3totp_conf::SESSION_ADMIN_PROFILE, $selectedProfile);
$session->setVariable(d3totp_conf::SESSION_ADMIN_CHLANGUAGE, $selectedLanguage);
$session->setVariable(d3totp_conf::OXID_ADMIN_AUTH, $userId); $session->setVariable(d3totp_conf::OXID_ADMIN_AUTH, $userId);
$session->setVariable(d3totp_conf::SESSION_ADMIN_AUTH, $userId); $session->setVariable(d3totp_conf::SESSION_ADMIN_AUTH, $userId);
$session->deleteVariable(d3totp_conf::SESSION_ADMIN_CURRENTUSER); $session->deleteVariable(d3totp_conf::SESSION_ADMIN_CURRENTUSER);
/** @var d3_totp_LoginController $loginController */
$loginController = oxNew(LoginController::class);
$loginController->d3totpAfterLogin();
return "admin_start"; return "admin_start";
} catch (d3totp_wrongOtpException $e) { } catch (d3totp_wrongOtpException $e) {
Registry::getUtilsView()->addErrorToDisplay($e); Registry::getUtilsView()->addErrorToDisplay($e);

View File

@ -25,4 +25,6 @@ class d3totp_conf
public const SESSION_NAVFORMPARAMS = 'd3Totp_navFormParams'; public const SESSION_NAVFORMPARAMS = 'd3Totp_navFormParams';
public const SESSION_ADMIN_AUTH = 'd3Totp_auth'; // has valid totp, user is logged in completly public const SESSION_ADMIN_AUTH = 'd3Totp_auth'; // has valid totp, user is logged in completly
public const SESSION_ADMIN_CURRENTUSER = 'd3Totp_currentUser'; // oxid assigned to user from entered username public const SESSION_ADMIN_CURRENTUSER = 'd3Totp_currentUser'; // oxid assigned to user from entered username
public const SESSION_ADMIN_PROFILE = 'd3Totp_currentProfile'; // selected profile
public const SESSION_ADMIN_CHLANGUAGE = 'd3Totp_currentChLanguage'; // selected language
} }

View File

@ -21,6 +21,8 @@
<input type="hidden" name="fnc" value="checklogin"> <input type="hidden" name="fnc" value="checklogin">
<input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]"> <input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]">
<input type="hidden" name="profile" value="[{$selectedProfile}]">
<input type="hidden" name="chlanguage" value="[{$selectedChLanguage}]">
<h3>[{oxmultilang ident="TOTP_INPUT"}]</h3> <h3>[{oxmultilang ident="TOTP_INPUT"}]</h3>

View File

@ -65,8 +65,13 @@ namespace D3\Totp\Modules\Core
{ {
use OxidEsales\Eshop\Core\Utils; use OxidEsales\Eshop\Core\Utils;
use OxidEsales\EshopCommunity\Core\SystemEventHandler;
class d3_totp_utils_parent extends Utils class d3_totp_utils_parent extends Utils
{ {
} }
class totpSystemEventHandler_parent extends SystemEventHandler
{
}
} }

View File

@ -50,24 +50,49 @@ class d3_totp_LoginController extends d3_totp_LoginController_parent
*/ */
public function checklogin() public function checklogin()
{ {
Registry::getSession()->setVariable(
d3totp_conf::SESSION_ADMIN_PROFILE,
Registry::getRequest()->getRequestEscapedParameter('profile')
);
Registry::getSession()->setVariable(
d3totp_conf::SESSION_ADMIN_CHLANGUAGE,
Registry::getRequest()->getRequestEscapedParameter('chlanguage')
);
// parent::checklogin(); // parent::checklogin();
$return = $this->d3CallMockableParent('checklogin'); return $this->d3CallMockableParent('checklogin');
}
$totp = $this->d3GetTotpObject(); public function d3totpAfterLogin()
$totp->loadByUserId(Registry::getSession()->getVariable("auth")); {
$myUtilsServer = Registry::getUtilsServer();
$sProfile = Registry::getSession()->getVariable(d3totp_conf::SESSION_ADMIN_PROFILE);
if ($this->d3TotpLoginMissing($totp)) { // #533
$userId = $this->d3TotpGetSession()->getVariable('auth'); if (isset($sProfile)) {
$aProfiles = Registry::getSession()->getVariable("aAdminProfiles");
/** @var d3_totp_user $user */ if ($aProfiles && isset($aProfiles[$sProfile])) {
$user = $this->d3TotpGetUserObject(); // setting cookie to store last locally used profile
$user->logout(); $myUtilsServer->setOxCookie("oxidadminprofile", $sProfile . "@" . implode("@", $aProfiles[$sProfile]), time() + 31536000, "/");
Registry::getSession()->setVariable("profile", $aProfiles[$sProfile]);
$this->d3TotpGetSession()->setVariable(d3totp_conf::SESSION_ADMIN_CURRENTUSER, $userId); Registry::getSession()->deleteVariable(d3totp_conf::SESSION_ADMIN_PROFILE);
return "d3totpadminlogin"; }
} else {
//deleting cookie info, as setting profile to default
$myUtilsServer->setOxCookie("oxidadminprofile", "", time() - 3600, "/");
} }
return $return; // languages
$iLang = Registry::getSession()->getVariable(d3totp_conf::SESSION_ADMIN_CHLANGUAGE);
$aLanguages = Registry::getLang()->getAdminTplLanguageArray();
if (!isset($aLanguages[$iLang])) {
$iLang = key($aLanguages);
}
$myUtilsServer->setOxCookie("oxidadminlanguage", $aLanguages[$iLang]->abbr, time() + 31536000, "/");
Registry::getLang()->setTplLanguage($iLang);
Registry::getSession()->deleteVariable(d3totp_conf::SESSION_ADMIN_CHLANGUAGE);
} }
/** /**

View File

@ -0,0 +1,88 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\Totp\Modules\Core;
use D3\Totp\Application\Model\d3totp;
use D3\Totp\Application\Model\d3totp_conf;
use D3\Totp\Modules\Application\Model\d3_totp_user;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Session;
class totpSystemEventHandler extends totpSystemEventHandler_parent
{
public function onAdminLogin()
{
$this->d3RequestTotp();
parent::onAdminLogin();
}
protected function d3requestTotp()
{
$totp = $this->d3GetTotpObject();
$userId = $this->d3TotpGetSession()->getVariable('auth');
$totp->loadByUserId($userId);
if ($this->d3TotpLoginMissing($totp)) {
/** @var d3_totp_user $user */
$user = $this->d3TotpGetUserObject();
$user->logout();
$this->d3TotpGetSession()->setVariable(d3totp_conf::SESSION_ADMIN_CURRENTUSER, $userId);
Registry::getUtils()->redirect(
'index.php?cl=d3totpadminlogin&amp;'.
'profile='.$this->d3TotpGetSession()->getVariable(d3totp_conf::SESSION_ADMIN_PROFILE).'&amp;'.
'chlanguage='.$this->d3TotpGetSession()->getVariable(d3totp_conf::SESSION_ADMIN_CHLANGUAGE)
);
}
}
/**
* @return d3totp
*/
public function d3GetTotpObject()
{
return oxNew(d3totp::class);
}
/**
* @return Session
*/
public function d3TotpGetSession()
{
return Registry::getSession();
}
/**
* @param d3totp $totp
* @return bool
*/
public function d3TotpLoginMissing($totp)
{
return $totp->isActive()
&& false == $this->d3TotpGetSession()->getVariable(d3totp_conf::SESSION_ADMIN_AUTH);
}
/**
* @return d3_totp_user
*/
protected function d3TotpGetUserObject(): d3_totp_user
{
return oxNew( User::class );
}
}

View File

@ -25,12 +25,14 @@ use D3\Totp\Modules\Application\Controller\d3_totp_PaymentController;
use D3\Totp\Modules\Application\Controller\d3_totp_UserController; use D3\Totp\Modules\Application\Controller\d3_totp_UserController;
use D3\Totp\Modules\Application\Model\d3_totp_user; use D3\Totp\Modules\Application\Model\d3_totp_user;
use D3\Totp\Modules\Core\d3_totp_utils; use D3\Totp\Modules\Core\d3_totp_utils;
use D3\Totp\Modules\Core\totpSystemEventHandler;
use D3\Totp\Setup as ModuleSetup; use D3\Totp\Setup as ModuleSetup;
use OxidEsales\Eshop\Application\Component\UserComponent; use OxidEsales\Eshop\Application\Component\UserComponent;
use OxidEsales\Eshop\Application\Controller\Admin\LoginController; use OxidEsales\Eshop\Application\Controller\Admin\LoginController;
use OxidEsales\Eshop\Application\Controller\OrderController; use OxidEsales\Eshop\Application\Controller\OrderController;
use OxidEsales\Eshop\Application\Controller\PaymentController; use OxidEsales\Eshop\Application\Controller\PaymentController;
use OxidEsales\Eshop\Application\Controller\UserController; use OxidEsales\Eshop\Application\Controller\UserController;
use OxidEsales\Eshop\Core\SystemEventHandler;
use OxidEsales\Eshop\Core\Utils; use OxidEsales\Eshop\Core\Utils;
use OxidEsales\Eshop\Application\Model as OxidModel; use OxidEsales\Eshop\Application\Model as OxidModel;
@ -67,6 +69,7 @@ $aModule = [
LoginController::class => d3_totp_LoginController::class, LoginController::class => d3_totp_LoginController::class,
Utils::class => d3_totp_utils::class, Utils::class => d3_totp_utils::class,
UserComponent::class => d3_totp_UserComponent::class, UserComponent::class => d3_totp_UserComponent::class,
SystemEventHandler::class => totpSystemEventHandler::class
], ],
'controllers' => [ 'controllers' => [
'd3user_totp' => d3user_totp::class, 'd3user_totp' => d3user_totp::class,