From 26556eb889cfe2ab0d88a5e2855fc22d1f8d6867 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 24 Nov 2022 01:02:20 +0100 Subject: [PATCH] restore assertAuth in component instead in frontend controller, prevent check login parent call (OTP doesnt require this anymore) --- .../Controller/Admin/d3webauthnadminlogin.php | 63 +++++++++++++-- .../Controller/d3webauthnlogin.php | 49 ------------ src/Application/Model/WebauthnConf.php | 2 + .../Component/d3_webauthn_UserComponent.php | 77 +++++++++++++++++++ .../Admin/d3_LoginController_Webauthn.php | 41 ++++++++++ src/tests/additional.inc.php | 2 - 6 files changed, 176 insertions(+), 58 deletions(-) diff --git a/src/Application/Controller/Admin/d3webauthnadminlogin.php b/src/Application/Controller/Admin/d3webauthnadminlogin.php index 666975e..900912a 100755 --- a/src/Application/Controller/Admin/d3webauthnadminlogin.php +++ b/src/Application/Controller/Admin/d3webauthnadminlogin.php @@ -21,16 +21,18 @@ use D3\Webauthn\Application\Model\Exceptions\WebauthnGetException; use D3\Webauthn\Application\Model\Webauthn; use D3\Webauthn\Application\Model\WebauthnConf; use D3\Webauthn\Application\Model\Exceptions\WebauthnException; -use D3\Webauthn\Modules\Application\Component\d3_webauthn_UserComponent; +use D3\Webauthn\Modules\Application\Controller\Admin\d3_LoginController_Webauthn; use D3\Webauthn\Modules\Application\Model\d3_User_Webauthn; use Doctrine\DBAL\Driver\Exception as DoctrineDriverException; use Doctrine\DBAL\Exception as DoctrineException; use OxidEsales\Eshop\Application\Controller\Admin\AdminController; use OxidEsales\Eshop\Application\Controller\Admin\LoginController; use OxidEsales\Eshop\Application\Controller\FrontendController; -use OxidEsales\Eshop\Application\Model\User; +use OxidEsales\Eshop\Core\Exception\ConnectionException; +use OxidEsales\Eshop\Core\Exception\CookieException; +use OxidEsales\Eshop\Core\Exception\UserException; use OxidEsales\Eshop\Core\Registry; -use OxidEsales\Eshop\Core\Routing\ControllerClassNameResolver; +use OxidEsales\Eshop\Core\SystemEventHandler; use OxidEsales\Eshop\Core\Utils; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; @@ -108,9 +110,11 @@ class d3webauthnadminlogin extends AdminController */ public function d3AssertAuthn(): ?string { + $myUtilsView = Registry::getUtilsView(); /** @var d3_User_Webauthn $user */ $user = $this->d3GetUserObject(); $userId = $this->d3GetSession()->getVariable(WebauthnConf::WEBAUTHN_ADMIN_SESSION_CURRENTUSER); + $selectedProfile = $this->d3GetSession()->getVariable(WebauthnConf::WEBAUTHN_ADMIN_PROFILE); try { $error = Registry::getRequest()->getRequestEscapedParameter('error'); @@ -124,13 +128,58 @@ class d3webauthnadminlogin extends AdminController if (strlen((string) $credential)) { $webAuthn = $this->d3GetWebauthnObject(); $webAuthn->assertAuthn($credential); - $user->load($userId); - $this->d3GetSession()->setVariable(WebauthnConf::WEBAUTHN_ADMIN_SESSION_AUTH, true); - /** @var d3_webauthn_UserComponent $userCmp */ + $user->load($userId); + $session = $this->d3GetSession(); + $adminProfiles = $session->getVariable("aAdminProfiles"); + $selectedLanguage = $session->getVariable(WebauthnConf::WEBAUTHN_ADMIN_CHLANGUAGE); + $session->initNewSession(); + $session->setVariable("aAdminProfiles", $adminProfiles); + $session->setVariable(WebauthnConf::OXID_ADMIN_AUTH, $userId); + $session->setVariable(WebauthnConf::WEBAUTHN_ADMIN_PROFILE, $selectedProfile); + $session->setVariable(WebauthnConf::WEBAUTHN_ADMIN_CHLANGUAGE, $selectedLanguage); + + $cookie = Registry::getUtilsServer()->getOxCookie(); + if ($cookie === null) { + throw oxNew(CookieException::class, 'ERROR_MESSAGE_COOKIE_NOCOOKIE'); + } + + if ($user->oxuser__oxrights->value === 'user') { + throw oxNew(UserException::class, 'ERROR_MESSAGE_USER_NOVALIDLOGIN'); + } + $iSubshop = (int) $user->oxuser__oxrights->value; + if ($iSubshop) { + Registry::getSession()->setVariable("shp", $iSubshop); + Registry::getSession()->setVariable('currentadminshop', $iSubshop); + Registry::getConfig()->setShopId($iSubshop); + } + + //execute onAdminLogin() event + $oEvenHandler = oxNew(SystemEventHandler::class); + $oEvenHandler->onAdminLogin(Registry::getConfig()->getShopId()); + + /** @var d3_LoginController_Webauthn $loginController */ $loginController = oxNew(LoginController::class); - return $loginController->checklogin(); + $loginController->d3webauthnAfterLogin(); + + return "admin_start"; } + } catch (UserException $oEx) { + $myUtilsView->addErrorToDisplay('LOGIN_ERROR'); + $oStr = getStr(); + $this->addTplParam('user', $oStr->htmlspecialchars($userId)); + $this->addTplParam('profile', $oStr->htmlspecialchars($selectedProfile)); + + return null; + } catch (CookieException $oEx) { + $myUtilsView->addErrorToDisplay('LOGIN_NO_COOKIE_SUPPORT'); + $oStr = getStr(); + $this->addTplParam('user', $oStr->htmlspecialchars($userId)); + $this->addTplParam('profile', $oStr->htmlspecialchars($selectedProfile)); + + return null; + } catch (ConnectionException $oEx) { + $myUtilsView->addErrorToDisplay($oEx); } catch (WebauthnException $e) { $this->d3GetUtilsViewObject()->addErrorToDisplay($e); $this->d3GetLoggerObject()->error($e->getDetailedErrorMessage(), ['UserId' => $userId]); diff --git a/src/Application/Controller/d3webauthnlogin.php b/src/Application/Controller/d3webauthnlogin.php index 12339e3..105072e 100755 --- a/src/Application/Controller/d3webauthnlogin.php +++ b/src/Application/Controller/d3webauthnlogin.php @@ -145,55 +145,6 @@ class d3webauthnlogin extends FrontendController return $this->previousClassIsOrderStep(); } - /** - * @return void - */ - public function d3AssertAuthn(): void - { - /** @var d3_User_Webauthn $user */ - $user = $this->d3GetUserObject(); - $userId = $this->d3GetSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_CURRENTUSER); - - try { - $error = Registry::getRequest()->getRequestEscapedParameter('error'); - if (strlen((string) $error)) { - /** @var WebauthnGetException $e */ - $e = oxNew(WebauthnGetException::class, $error); - throw $e; - } - - $credential = Registry::getRequest()->getRequestEscapedParameter('credential'); - if (strlen((string) $credential)) { - $webAuthn = $this->d3GetWebauthnObject(); - $webAuthn->assertAuthn($credential); - $user->load($userId); - - // relogin, don't extract from this try block - $setSessionCookie = Registry::getRequest()->getRequestParameter('lgn_cook'); - $this->d3GetSession()->setVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH, $credential); - $this->d3GetSession()->setVariable(WebauthnConf::OXID_FRONTEND_AUTH, $user->getId()); - $this->setUser(null); - $this->setLoginStatus(USER_LOGIN_SUCCESS); - - // cookie must be set ? - if ($setSessionCookie && Registry::getConfig()->getConfigParam('blShowRememberMe')) { - Registry::getUtilsServer()->setUserCookie( - $user->oxuser__oxusername->value, - $user->oxuser__oxpassword->value, - Registry::getConfig()->getShopId() - ); - } - - $this->_afterLogin($user); - } - } catch (WebauthnException $e) { - $this->d3GetUtilsViewObject()->addErrorToDisplay($e); - $this->d3GetLoggerObject()->error($e->getDetailedErrorMessage(), ['UserId' => $userId]); - $this->d3GetLoggerObject()->debug($e->getTraceAsString()); - $user->logout(); - } - } - /** * @return array */ diff --git a/src/Application/Model/WebauthnConf.php b/src/Application/Model/WebauthnConf.php index 5f097ce..4680ec2 100755 --- a/src/Application/Model/WebauthnConf.php +++ b/src/Application/Model/WebauthnConf.php @@ -31,6 +31,8 @@ class WebauthnConf public const WEBAUTHN_ADMIN_SESSION_CURRENTUSER = 'd3webauthn_be_currentUser'; // oxid assigned to user from entered username public const WEBAUTHN_ADMIN_SESSION_LOGINUSER = 'd3webauthn_be_loginUser'; // username entered in login form public const WEBAUTHN_ADMIN_SESSION_CURRENTCLASS= 'd3webauthn_be_currentClass'; // no usage + public const WEBAUTHN_ADMIN_PROFILE = 'd3webauthn_be_profile'; + public const WEBAUTHN_ADMIN_CHLANGUAGE = 'd3webauthn_be_chlanguage'; public const WEBAUTHN_SESSION_NAVFORMPARAMS = 'd3webauthn_navFormParams'; // no usage public const WEBAUTHN_SESSION_NAVPARAMS = 'd3webauthn_navigationParams'; // no usage diff --git a/src/Modules/Application/Component/d3_webauthn_UserComponent.php b/src/Modules/Application/Component/d3_webauthn_UserComponent.php index 9cba4d8..6d8d92b 100755 --- a/src/Modules/Application/Component/d3_webauthn_UserComponent.php +++ b/src/Modules/Application/Component/d3_webauthn_UserComponent.php @@ -15,6 +15,8 @@ declare(strict_types=1); namespace D3\Webauthn\Modules\Application\Component; +use D3\Webauthn\Application\Model\Exceptions\WebauthnException; +use D3\Webauthn\Application\Model\Exceptions\WebauthnGetException; use D3\Webauthn\Application\Model\WebauthnConf; use D3\Webauthn\Application\Model\Webauthn; use D3\Webauthn\Modules\Application\Model\d3_User_Webauthn; @@ -23,8 +25,10 @@ use Doctrine\DBAL\Exception; use OxidEsales\Eshop\Application\Model\User; use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Session; +use OxidEsales\Eshop\Core\UtilsView; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; class d3_webauthn_UserComponent extends d3_webauthn_UserComponent_parent { @@ -98,6 +102,55 @@ class d3_webauthn_UserComponent extends d3_webauthn_UserComponent_parent $this->d3WebauthnGetSession()->deleteVariable(WebauthnConf::WEBAUTHN_LOGIN_OBJECT); } + /** + * @return void + */ + public function d3AssertAuthn(): void + { + /** @var d3_User_Webauthn $user */ + $user = $this->d3WebauthnGetUserObject(); + $userId = $this->d3WebauthnGetSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_CURRENTUSER); + + try { + $error = Registry::getRequest()->getRequestEscapedParameter('error'); + if (strlen((string) $error)) { + /** @var WebauthnGetException $e */ + $e = oxNew(WebauthnGetException::class, $error); + throw $e; + } + + $credential = Registry::getRequest()->getRequestEscapedParameter('credential'); + if (strlen((string) $credential)) { + $webAuthn = $this->d3GetWebauthnObject(); + $webAuthn->assertAuthn($credential); + $user->load($userId); + + // relogin, don't extract from this try block + $setSessionCookie = Registry::getRequest()->getRequestParameter('lgn_cook'); + $this->d3WebauthnGetSession()->setVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH, $credential); + $this->d3WebauthnGetSession()->setVariable(WebauthnConf::OXID_FRONTEND_AUTH, $user->getId()); + $this->setUser(null); + $this->setLoginStatus(USER_LOGIN_SUCCESS); + + // cookie must be set ? + if ($setSessionCookie && Registry::getConfig()->getConfigParam('blShowRememberMe')) { + Registry::getUtilsServer()->setUserCookie( + $user->oxuser__oxusername->value, + $user->oxuser__oxpassword->value, + Registry::getConfig()->getShopId() + ); + } + + $this->_afterLogin($user); + } + } catch (WebauthnException $e) { + $this->d3GetUtilsViewObject()->addErrorToDisplay($e); + $this->d3GetLoggerObject()->error($e->getDetailedErrorMessage(), ['UserId' => $userId]); + $this->d3GetLoggerObject()->debug($e->getTraceAsString()); + $user->logout(); + } + } + /** * @return Session */ @@ -105,4 +158,28 @@ class d3_webauthn_UserComponent extends d3_webauthn_UserComponent_parent { return Registry::getSession(); } + + /** + * @return User + */ + public function d3WebauthnGetUserObject(): User + { + return oxNew(User::class); + } + + /** + * @return UtilsView + */ + public function d3GetUtilsViewObject(): UtilsView + { + return Registry::getUtilsView(); + } + + /** + * @return LoggerInterface + */ + public function d3GetLoggerObject(): LoggerInterface + { + return Registry::getLogger(); + } } \ No newline at end of file diff --git a/src/Modules/Application/Controller/Admin/d3_LoginController_Webauthn.php b/src/Modules/Application/Controller/Admin/d3_LoginController_Webauthn.php index 8709891..9617b94 100755 --- a/src/Modules/Application/Controller/Admin/d3_LoginController_Webauthn.php +++ b/src/Modules/Application/Controller/Admin/d3_LoginController_Webauthn.php @@ -56,6 +56,15 @@ class d3_LoginController_Webauthn extends d3_LoginController_Webauthn_parent false === Registry::getSession()->hasVariable(WebauthnConf::WEBAUTHN_ADMIN_SESSION_AUTH) && (!strlen(trim((string) $password))) ) { + Registry::getSession()->setVariable( + WebauthnConf::WEBAUTHN_ADMIN_PROFILE, + Registry::getRequest()->getRequestEscapedParameter('profile') + ); + Registry::getSession()->setVariable( + WebauthnConf::WEBAUTHN_ADMIN_CHLANGUAGE, + Registry::getRequest()->getRequestEscapedParameter('chlanguage') + ); + $webauthn = $this->d3GetWebauthnObject(); if ($webauthn->isActive($userId) @@ -81,6 +90,38 @@ class d3_LoginController_Webauthn extends d3_LoginController_Webauthn_parent return parent::checklogin(); } + public function d3webauthnAfterLogin() + { + $myUtilsServer = Registry::getUtilsServer(); + $sProfile = Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_ADMIN_PROFILE); + + // #533 + if (isset($sProfile)) { + $aProfiles = Registry::getSession()->getVariable("aAdminProfiles"); + if ($aProfiles && isset($aProfiles[$sProfile])) { + // setting cookie to store last locally used profile + $myUtilsServer->setOxCookie("oxidadminprofile", $sProfile . "@" . implode("@", $aProfiles[$sProfile]), time() + 31536000, "/"); + Registry::getSession()->setVariable("profile", $aProfiles[$sProfile]); + Registry::getSession()->deleteVariable(WebauthnConf::WEBAUTHN_ADMIN_PROFILE); + } + } else { + //deleting cookie info, as setting profile to default + $myUtilsServer->setOxCookie("oxidadminprofile", "", time() - 3600, "/"); + } + + // languages + $iLang = Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_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(WebauthnConf::WEBAUTHN_ADMIN_CHLANGUAGE); + } + /** * @return void */ diff --git a/src/tests/additional.inc.php b/src/tests/additional.inc.php index fb09dff..9b9823d 100644 --- a/src/tests/additional.inc.php +++ b/src/tests/additional.inc.php @@ -11,8 +11,6 @@ * @link https://www.oxidmodule.com */ -// Include totp test config - namespace D3\Webauthn\tests; use D3\ModCfg\Tests\additional_abstract;