restore assertAuth in component instead in frontend controller, prevent check login parent call (OTP doesnt require this anymore)

This commit is contained in:
Daniel Seifert 2022-11-24 01:02:20 +01:00
parent e866141a34
commit 26556eb889
Signed by: DanielS
GPG Key ID: 6A513E13AEE66170
6 changed files with 176 additions and 58 deletions

View File

@ -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 */
$loginController = oxNew(LoginController::class);
return $loginController->checklogin();
$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);
$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]);

View File

@ -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
*/

View File

@ -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

View File

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

View File

@ -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
*/

View File

@ -11,8 +11,6 @@
* @link https://www.oxidmodule.com
*/
// Include totp test config
namespace D3\Webauthn\tests;
use D3\ModCfg\Tests\additional_abstract;