From 5ed13d13d9da6100555072c8061f417e4de4eba3 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 31 Oct 2022 23:17:04 +0100 Subject: [PATCH] improve code --- .../Controller/Admin/d3user_webauthn.php | 2 +- .../Controller/Admin/d3webauthnadminlogin.php | 28 +- .../Controller/d3webauthnlogin.php | 13 +- src/Application/Model/Webauthn.php | 3 +- src/Application/Model/WebauthnConf.php | 2 + .../translations/de/d3webauthn_lang.php | 2 + .../views/admin/de/d3webauthn_lang.php | 2 + .../views/admin/en/d3webauthn_lang.php | 1 + src/IntelliSenseHelper.php | 4 - .../Component/d3_webauthn_UserComponent.php | 88 ++----- .../Admin/d3_LoginController_Webauthn.php | 63 +---- .../d3_webauthn_OrderController.php | 1 - .../d3_webauthn_PaymentController.php | 1 - .../Controller/d3_webauthn_UserController.php | 1 - .../Controller/d3_webauthn_getUserTrait.php | 14 +- .../Application/Model/d3_User_Webauthn.php | 68 +++-- src/Modules/Core/d3_webauthn_utils.php | 17 +- src/Setup/Events.php | 90 ++++++- src/Setup/Installation.php | 246 ------------------ 19 files changed, 229 insertions(+), 417 deletions(-) delete mode 100755 src/Setup/Installation.php diff --git a/src/Application/Controller/Admin/d3user_webauthn.php b/src/Application/Controller/Admin/d3user_webauthn.php index ef5449c..6fda38b 100755 --- a/src/Application/Controller/Admin/d3user_webauthn.php +++ b/src/Application/Controller/Admin/d3user_webauthn.php @@ -107,7 +107,7 @@ class d3user_webauthn extends AdminDetailsController $publicKeyCredentialCreationOptions ); } catch (WebauthnException $e) { - // ToDo: log exc message + // ToDo: log exc message and show message } $this->addTplParam('isAdmin', isAdmin()); diff --git a/src/Application/Controller/Admin/d3webauthnadminlogin.php b/src/Application/Controller/Admin/d3webauthnadminlogin.php index e8e0596..b12f3a8 100755 --- a/src/Application/Controller/Admin/d3webauthnadminlogin.php +++ b/src/Application/Controller/Admin/d3webauthnadminlogin.php @@ -22,16 +22,17 @@ use D3\Webauthn\Application\Model\WebauthnErrors; use D3\Webauthn\Application\Model\WebauthnException; use D3\Webauthn\Modules\Application\Component\d3_webauthn_UserComponent; use D3\Webauthn\Modules\Application\Model\d3_User_Webauthn; -use Exception; +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\DatabaseConnectionException; -use OxidEsales\Eshop\Core\Exception\DatabaseErrorException; use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Utils; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; class d3webauthnadminlogin extends AdminController { @@ -44,8 +45,10 @@ class d3webauthnadminlogin extends AdminController /** * @return null - * @throws DatabaseConnectionException - * @throws DatabaseErrorException + * @throws ContainerExceptionInterface + * @throws DoctrineDriverException + * @throws DoctrineException + * @throws NotFoundExceptionInterface */ public function render() { @@ -62,11 +65,16 @@ class d3webauthnadminlogin extends AdminController $this->generateCredentialRequest(); - //$this->addTplParam('navFormParams', Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_NAVFORMPARAMS)); - return parent::render(); } + /** + * @return void + * @throws DoctrineDriverException + * @throws DoctrineException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ public function generateCredentialRequest() { try { @@ -78,7 +86,11 @@ class d3webauthnadminlogin extends AdminController $this->addTplParam('webauthn_publickey_login', $publicKeyCredentialRequestOptions); $this->addTplParam('isAdmin', isAdmin()); } catch (WebauthnException $e) { - // ToDo write exc message to display and log + Registry::getSession()->setVariable(WebauthnConf::GLOBAL_SWITCH, true); + $exception = oxNew(WebauthnException::class, Registry::getLang()->translateString('D3_WEBAUTHN_ERR_LOGINPROHIBITED')); + Registry::getUtilsView()->addErrorToDisplay($exception); + Registry::getLogger()->error('webauthn request options: '.$e->getMessage()); + $this->getUtils()->redirect('index.php?cl=login'); } } diff --git a/src/Application/Controller/d3webauthnlogin.php b/src/Application/Controller/d3webauthnlogin.php index 06aa670..a72407e 100755 --- a/src/Application/Controller/d3webauthnlogin.php +++ b/src/Application/Controller/d3webauthnlogin.php @@ -22,6 +22,7 @@ use D3\Webauthn\Application\Model\WebauthnErrors; use D3\Webauthn\Application\Model\WebauthnException; use D3\Webauthn\Modules\Application\Component\d3_webauthn_UserComponent; 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\FrontendController; use OxidEsales\Eshop\Application\Model\User; @@ -39,8 +40,12 @@ class d3webauthnlogin extends FrontendController /** * @return null + * @throws ContainerExceptionInterface * @throws DatabaseConnectionException * @throws DatabaseErrorException + * @throws DoctrineDriverException + * @throws DoctrineException + * @throws NotFoundExceptionInterface */ public function render() { @@ -64,7 +69,7 @@ class d3webauthnlogin extends FrontendController /** * @return void - * @throws \Doctrine\DBAL\Driver\Exception + * @throws DoctrineDriverException * @throws DoctrineException * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface @@ -78,7 +83,11 @@ class d3webauthnlogin extends FrontendController $publicKeyCredentialRequestOptions = $webauthn->getRequestOptions($userId); $this->addTplParam('webauthn_publickey_login', $publicKeyCredentialRequestOptions); } catch (WebauthnException $e) { - // ToDo: write exc msg to display and log + Registry::getSession()->setVariable(WebauthnConf::GLOBAL_SWITCH, true); + $exception = oxNew(WebauthnException::class, Registry::getLang()->translateString('D3_WEBAUTHN_ERR_LOGINPROHIBITED')); + Registry::getUtilsView()->addErrorToDisplay($exception); + Registry::getLogger()->error('webauthn request options: '.$e->getMessage()); + $this->getUtils()->redirect('index.php?cl=start'); } $this->addTplParam('isAdmin', isAdmin()); diff --git a/src/Application/Model/Webauthn.php b/src/Application/Model/Webauthn.php index 9ae4a8a..b942d00 100644 --- a/src/Application/Model/Webauthn.php +++ b/src/Application/Model/Webauthn.php @@ -186,7 +186,8 @@ class Webauthn */ public function isActive($userId): bool { - return false == Registry::getConfig()->getConfigParam('blDisableWebauthnGlobally') + return !Registry::getConfig()->getConfigParam(WebauthnConf::GLOBAL_SWITCH) + && !Registry::getSession()->getVariable(WebauthnConf::GLOBAL_SWITCH) && $this->UserUseWebauthn($userId); } diff --git a/src/Application/Model/WebauthnConf.php b/src/Application/Model/WebauthnConf.php index 4dfd0c4..d0f8db0 100755 --- a/src/Application/Model/WebauthnConf.php +++ b/src/Application/Model/WebauthnConf.php @@ -23,4 +23,6 @@ class WebauthnConf public const WEBAUTHN_SESSION_LOGINUSER = 'd3webauthnLoginUser'; // username entered in login form public const WEBAUTHN_SESSION_CURRENTCLASS = 'd3webauthnCurrentClass'; // no usage public const WEBAUTHN_SESSION_NAVFORMPARAMS = 'd3webauthnNavFormParams'; // no usage + + public const GLOBAL_SWITCH = 'blDisableWebauthnGlobally'; } \ No newline at end of file diff --git a/src/Application/translations/de/d3webauthn_lang.php b/src/Application/translations/de/d3webauthn_lang.php index a9cb4dc..5e9cfe8 100755 --- a/src/Application/translations/de/d3webauthn_lang.php +++ b/src/Application/translations/de/d3webauthn_lang.php @@ -28,4 +28,6 @@ $aLang = array( 'D3_WEBAUTHN_ACCOUNT_TYPE1' => 'nur Auth-Stick', 'D3_WEBAUTHN_ACCOUNT_TYPE2' => 'nur Auth-Stick, Passwort als Alternative', 'D3_WEBAUTHN_ACCOUNT_TYPE3' => 'Auth-Stick und Passwort in Kombination', + + 'D3_WEBAUTHN_ERR_LOGINPROHIBITED' => 'Die Anmeldung mit Sicherheitsschlüssel ist aus technischen Gründen derzeit leider nicht möglich. Bitte verwenden Sie statt dessen Ihr Passwort.', ); diff --git a/src/Application/views/admin/de/d3webauthn_lang.php b/src/Application/views/admin/de/d3webauthn_lang.php index a3b4259..e6d1329 100755 --- a/src/Application/views/admin/de/d3webauthn_lang.php +++ b/src/Application/views/admin/de/d3webauthn_lang.php @@ -46,4 +46,6 @@ $aLang = [ 'D3_WEBAUTHN_ERR_NOTSUPPORTED' => 'Die Aktion wird nicht unterstützt.', 'D3_WEBAUTHN_ERR_UNKNOWN' => 'Die Aktion wurde wegen eines unbekannten Fehlers abgebrochen.', 'D3_WEBAUTHN_ERR_NOPUBKEYSUPPORT' => 'Ihr Browser unterstützt die Verwendung von Hardwareschlüsseln leider nicht.', + + 'D3_WEBAUTHN_ERR_LOGINPROHIBITED' => 'Die Anmeldung mit Sicherheitsschlüssel ist aus technischen Gründen derzeit leider nicht möglich. Bitte verwenden Sie statt dessen Ihr Passwort.', ]; diff --git a/src/Application/views/admin/en/d3webauthn_lang.php b/src/Application/views/admin/en/d3webauthn_lang.php index e0dc393..d5f6c91 100755 --- a/src/Application/views/admin/en/d3webauthn_lang.php +++ b/src/Application/views/admin/en/d3webauthn_lang.php @@ -47,4 +47,5 @@ $aLang = [ 'D3_WEBAUTHN_ERR_UNKNOWN' => 'The action was cancelled due to an unknown error.', 'D3_WEBAUTHN_ERR_NOPUBKEYSUPPORT' => 'Unfortunately, your browser does not support the use of hardware keys.', + 'D3_WEBAUTHN_ERR_LOGINPROHIBITED' => 'Unfortunately, logging in with a security key is currently not possible for technical reasons. Please use your password instead.', ]; diff --git a/src/IntelliSenseHelper.php b/src/IntelliSenseHelper.php index 8cfc133..f699902 100755 --- a/src/IntelliSenseHelper.php +++ b/src/IntelliSenseHelper.php @@ -24,14 +24,10 @@ namespace D3\Webauthn\Modules\Application\Component namespace D3\Webauthn\Modules\Application\Controller { - use OxidEsales\Eshop\Application\Controller\OrderController; use OxidEsales\Eshop\Application\Controller\PaymentController; - use OxidEsales\Eshop\Application\Controller\StartController; use OxidEsales\Eshop\Application\Controller\UserController; - class d3_StartController_Webauthn_parent extends StartController {} - class d3_webauthn_UserController_parent extends UserController {} class d3_webauthn_OrderController_parent extends OrderController {} diff --git a/src/Modules/Application/Component/d3_webauthn_UserComponent.php b/src/Modules/Application/Component/d3_webauthn_UserComponent.php index 4f84548..7c5ebcb 100755 --- a/src/Modules/Application/Component/d3_webauthn_UserComponent.php +++ b/src/Modules/Application/Component/d3_webauthn_UserComponent.php @@ -19,6 +19,7 @@ use Assert\AssertionFailedException; use D3\Webauthn\Application\Model\WebauthnConf; use D3\Webauthn\Application\Model\Webauthn; use D3\Webauthn\Application\Model\WebauthnException; +use D3\Webauthn\Modules\Application\Model\d3_User_Webauthn; use Doctrine\DBAL\Driver\Exception as DoctrineDriverException; use Doctrine\DBAL\Exception; use Doctrine\DBAL\Query\QueryBuilder; @@ -43,7 +44,9 @@ class d3_webauthn_UserComponent extends d3_webauthn_UserComponent_parent public function login_noredirect() { $lgn_user = Registry::getRequest()->getRequestParameter('lgn_usr'); - $userId = $this->d3GetLoginUserId($lgn_user); + /** @var d3_User_Webauthn $user */ + $user = oxNew(User::class); + $userId = $user->d3GetLoginUserId($lgn_user); if ($lgn_user && $userId) { $webauthn = $this->d3GetWebauthnObject(); @@ -63,8 +66,6 @@ class d3_webauthn_UserComponent extends d3_webauthn_UserComponent_parent $this->getParent()->getViewConfig()->getNavFormParams() ); - //$oUser->d3templogout(); - return "d3webauthnlogin"; } } @@ -80,29 +81,6 @@ class d3_webauthn_UserComponent extends d3_webauthn_UserComponent_parent return oxNew(Webauthn::class); } - /** - * @return bool|string - */ - public function checkWebauthnlogin() - { - $sWebauth = base64_decode(Registry::getRequest()->getRequestParameter('keyauth')); - - $userId = Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_CURRENTUSER); - $oUser = oxNew(User::class); - $oUser->load($userId); - - $webauthn = $this->d3GetWebauthnObject(); - - if (!$this->isNoWebauthnOrNoLogin($webauthn, $userId) && $this->hasValidWebauthn($sWebauth, $webauthn)) { - $this->d3WebauthnRelogin($oUser, $sWebauth); - $this->d3WebauthnClearSessionVariables(); - - return false; - } - - return 'd3webauthnlogin'; - } - /** * @return UtilsView */ @@ -111,7 +89,7 @@ class d3_webauthn_UserComponent extends d3_webauthn_UserComponent_parent return Registry::getUtilsView(); } - public function cancelWebauthnLogin() + public function cancelWebauthnLogin(): bool { $this->d3WebauthnClearSessionVariables(); @@ -151,16 +129,29 @@ class d3_webauthn_UserComponent extends d3_webauthn_UserComponent_parent } /** - * @param User $oUser + * @param User $user * @param $sWebauthn */ - public function d3WebauthnRelogin(User $oUser, $sWebauthn) + public function d3WebauthnRelogin(User $user, $sWebauthn) { + $setSessionCookie = Registry::getRequest()->getRequestParameter('lgn_cook'); $this->d3GetSession()->setVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH, $sWebauthn); - $this->d3GetSession()->setVariable('usr', $oUser->getId()); + $this->d3GetSession()->setVariable('usr', $user->getId()); $this->setUser(null); $this->setLoginStatus(USER_LOGIN_SUCCESS); - $this->_afterLogin($oUser); + + // cookie must be set ? + if ($setSessionCookie && Registry::getConfig()->getConfigParam('blShowRememberMe')) { + Registry::getUtilsServer()->setUserCookie( + $user->oxuser__oxusername->value, + $user->oxuser__oxpassword->value, + Registry::getConfig()->getShopId(), + 31536000, + User::USER_COOKIE_SALT + ); + } + + $this->_afterLogin($user); } public function d3WebauthnClearSessionVariables() @@ -178,39 +169,4 @@ class d3_webauthn_UserComponent extends d3_webauthn_UserComponent_parent { return Registry::getSession(); } - - /** - * @return string|null - * @throws DoctrineDriverException - * @throws Exception - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function d3GetLoginUserId($username): ?string - { - if (empty($username)) { - return null; - } - - $user = oxNew(User::class); - - /** @var QueryBuilder $qb */ - $qb = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create(); - $qb->select('oxid') - ->from($user->getViewName()) - ->where( - $qb->expr()->and( - $qb->expr()->eq( - 'oxusername', - $qb->createNamedParameter($username) - ), - $qb->expr()->eq( - 'oxshopid', - $qb->createNamedParameter(Registry::getConfig()->getShopId()) - ) - ) - )->setMaxResults(1); - - return $qb->execute()->fetchOne(); - } } \ 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 d09dcf6..a656a9d 100755 --- a/src/Modules/Application/Controller/Admin/d3_LoginController_Webauthn.php +++ b/src/Modules/Application/Controller/Admin/d3_LoginController_Webauthn.php @@ -17,6 +17,7 @@ namespace D3\Webauthn\Modules\Application\Controller\Admin; use D3\Webauthn\Application\Model\Webauthn; use D3\Webauthn\Application\Model\WebauthnConf; +use D3\Webauthn\Modules\Application\Model\d3_User_Webauthn; use Doctrine\DBAL\Driver\Exception as DoctrineException; use Doctrine\DBAL\Exception; use Doctrine\DBAL\Query\QueryBuilder; @@ -50,10 +51,16 @@ class d3_LoginController_Webauthn extends d3_LoginController_Webauthn_parent */ public function checklogin() { - $lgn_user = Registry::getRequest()->getRequestParameter('user'); - $userId = $this->d3GetLoginUserId($lgn_user); + $lgn_user = Registry::getRequest()->getRequestParameter('user') ?: + Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_LOGINUSER); - if ($lgn_user && $userId && false === Registry::getSession()->hasVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH)) { + /** @var d3_User_Webauthn $user */ + $user = $this->d3GetUserObject(); + $userId = $user->d3GetLoginUserId($lgn_user, 'malladmin'); + + if ($lgn_user && $userId && + false === Registry::getSession()->hasVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH) + ) { $webauthn = $this->d3GetWebauthnObject(); if ($webauthn->isActive($userId) @@ -72,14 +79,6 @@ class d3_LoginController_Webauthn extends d3_LoginController_Webauthn_parent $lgn_user ); -/* - Registry::getSession()->setVariable( - WebauthnConf::WEBAUTHN_SESSION_NAVFORMPARAMS, - $this->getViewConfig()->getNavFormParams() - ); -*/ - //$oUser->d3templogout(); - return "d3webauthnadminlogin"; } } @@ -87,46 +86,6 @@ class d3_LoginController_Webauthn extends d3_LoginController_Webauthn_parent return parent::checklogin(); } - /** - * @param $username - * @return string|null - * @throws DoctrineException - * @throws Exception - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - protected function d3GetLoginUserId($username): ?string - { - if (empty($username)) { - return null; - } - - $user = oxNew(User::class); - - /** @var QueryBuilder $qb */ - $qb = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create(); - $qb->select('oxid') - ->from($user->getViewName()) - ->where( - $qb->expr()->and( - $qb->expr()->eq( - 'oxusername', - $qb->createNamedParameter($username) - ), - $qb->expr()->eq( - 'oxshopid', - $qb->createNamedParameter(Registry::getConfig()->getShopId()) - ), - $qb->expr()->eq( - 'oxrights', - $qb->createNamedParameter('malladmin') - ) - ) - )->setMaxResults(1); - - return $qb->execute()->fetchOne(); - } - public function d3WebauthnCancelLogin() { $oUser = $this->d3GetUserObject(); @@ -136,7 +95,7 @@ class d3_LoginController_Webauthn extends d3_LoginController_Webauthn_parent /** * @return User */ - public function d3GetUserObject() + public function d3GetUserObject(): User { return oxNew(User::class); } diff --git a/src/Modules/Application/Controller/d3_webauthn_OrderController.php b/src/Modules/Application/Controller/d3_webauthn_OrderController.php index e4ad8b7..850bc23 100755 --- a/src/Modules/Application/Controller/d3_webauthn_OrderController.php +++ b/src/Modules/Application/Controller/d3_webauthn_OrderController.php @@ -15,7 +15,6 @@ namespace D3\Webauthn\Modules\Application\Controller; - class d3_webauthn_OrderController extends d3_webauthn_OrderController_parent { use d3_webauthn_getUserTrait; diff --git a/src/Modules/Application/Controller/d3_webauthn_PaymentController.php b/src/Modules/Application/Controller/d3_webauthn_PaymentController.php index bc16dac..45df21e 100755 --- a/src/Modules/Application/Controller/d3_webauthn_PaymentController.php +++ b/src/Modules/Application/Controller/d3_webauthn_PaymentController.php @@ -15,7 +15,6 @@ namespace D3\Webauthn\Modules\Application\Controller; - class d3_webauthn_PaymentController extends d3_webauthn_PaymentController_parent { use d3_webauthn_getUserTrait; diff --git a/src/Modules/Application/Controller/d3_webauthn_UserController.php b/src/Modules/Application/Controller/d3_webauthn_UserController.php index 3a67ee0..b304bd3 100755 --- a/src/Modules/Application/Controller/d3_webauthn_UserController.php +++ b/src/Modules/Application/Controller/d3_webauthn_UserController.php @@ -15,7 +15,6 @@ namespace D3\Webauthn\Modules\Application\Controller; - class d3_webauthn_UserController extends d3_webauthn_UserController_parent { use d3_webauthn_getUserTrait; diff --git a/src/Modules/Application/Controller/d3_webauthn_getUserTrait.php b/src/Modules/Application/Controller/d3_webauthn_getUserTrait.php index 18f93f4..4d2bb85 100755 --- a/src/Modules/Application/Controller/d3_webauthn_getUserTrait.php +++ b/src/Modules/Application/Controller/d3_webauthn_getUserTrait.php @@ -17,14 +17,22 @@ namespace D3\Webauthn\Modules\Application\Controller; use D3\Webauthn\Application\Model\Webauthn; use D3\Webauthn\Application\Model\WebauthnConf; +use Doctrine\DBAL\Driver\Exception; +use Doctrine\DBAL\Exception as DoctrineException; use OxidEsales\Eshop\Application\Model\User; use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Session; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; trait d3_webauthn_getUserTrait { /** * @return bool|object|User + * @throws Exception + * @throws DoctrineException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface */ public function getUser() { @@ -34,7 +42,7 @@ trait d3_webauthn_getUserTrait $webauthn = $this->d3GetWebauthnpObject(); if ($webauthn->isActive($user->getId()) - && false == $this->d3GetSessionObject()->getVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH) + && !$this->d3GetSessionObject()->getVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH) ) { return false; } @@ -46,7 +54,7 @@ trait d3_webauthn_getUserTrait /** * @return Webauthn */ - public function d3GetWebauthnObject() + public function d3GetWebauthnObject(): Webauthn { return oxNew(Webauthn::class); } @@ -54,7 +62,7 @@ trait d3_webauthn_getUserTrait /** * @return Session */ - public function d3GetSessionObject() + public function d3GetSessionObject(): Session { return Registry::getSession(); } diff --git a/src/Modules/Application/Model/d3_User_Webauthn.php b/src/Modules/Application/Model/d3_User_Webauthn.php index 1ef0f6a..63f0277 100755 --- a/src/Modules/Application/Model/d3_User_Webauthn.php +++ b/src/Modules/Application/Model/d3_User_Webauthn.php @@ -16,7 +16,15 @@ namespace D3\Webauthn\Modules\Application\Model; use D3\Webauthn\Application\Model\WebauthnConf; +use Doctrine\DBAL\Driver\Exception as DoctrineDriverException; +use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Query\QueryBuilder; +use OxidEsales\Eshop\Application\Model\User; use OxidEsales\Eshop\Core\Registry; +use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; +use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; use ReflectionClass; class d3_User_Webauthn extends d3_User_Webauthn_parent @@ -35,27 +43,6 @@ class d3_User_Webauthn extends d3_User_Webauthn_parent return $return; } - public function d3templogout() - { - $varname = Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH); - $object = Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_LOGIN_OBJECT); - $currentUser = Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_CURRENTUSER); - $currentClass = Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_CURRENTCLASS); - $navFormParams = Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_NAVFORMPARAMS); - $loginUser = Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_LOGINUSER); - - $return = $this->logout(); - - Registry::getSession()->setVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH, $varname); - Registry::getSession()->setVariable(WebauthnConf::WEBAUTHN_LOGIN_OBJECT, $object); - Registry::getSession()->setVariable(WebauthnConf::WEBAUTHN_SESSION_CURRENTUSER, $currentUser); - Registry::getSession()->setVariable(WebauthnConf::WEBAUTHN_SESSION_CURRENTCLASS, $currentClass); - Registry::getSession()->setVariable(WebauthnConf::WEBAUTHN_SESSION_NAVFORMPARAMS, $navFormParams); - Registry::getSession()->setVariable(WebauthnConf::WEBAUTHN_SESSION_LOGINUSER, $loginUser); - - return $return; - } - public function login($userName, $password, $setSessionCookie = false) { if (Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH)) { @@ -78,4 +65,43 @@ class d3_User_Webauthn extends d3_User_Webauthn_parent return parent::login($userName, $password, $setSessionCookie); } + + /** + * @param string $username + * @param ?string $rights + * @return string|null + * @throws ContainerExceptionInterface + * @throws DoctrineDriverException + * @throws Exception + * @throws NotFoundExceptionInterface + */ + public function d3GetLoginUserId(string $username, string $rights = null): ?string + { + if (empty($username)) { + return null; + } + + /** @var QueryBuilder $qb */ + $qb = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create(); + $qb->select('oxid') + ->from($this->getViewName()) + ->where( + $qb->expr()->and( + $qb->expr()->eq( + 'oxusername', + $qb->createNamedParameter($username) + ), + $qb->expr()->eq( + 'oxshopid', + $qb->createNamedParameter(Registry::getConfig()->getShopId()) + ), + $rights ? $qb->expr()->eq( + 'oxrights', + $qb->createNamedParameter($rights) + ) : '1' + ) + )->setMaxResults(1); + + return $qb->execute()->fetchOne(); + } } \ No newline at end of file diff --git a/src/Modules/Core/d3_webauthn_utils.php b/src/Modules/Core/d3_webauthn_utils.php index f665911..9983026 100755 --- a/src/Modules/Core/d3_webauthn_utils.php +++ b/src/Modules/Core/d3_webauthn_utils.php @@ -18,16 +18,22 @@ namespace D3\Webauthn\Modules\Core; use D3\Webauthn\Application\Model\Webauthn; use D3\Webauthn\Application\Model\WebauthnConf; use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Driver\Exception; +use Doctrine\DBAL\Exception as DoctrineException; use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Session; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; class d3_webauthn_utils extends d3_webauthn_utils_parent { /** * @return bool - * @throws DBALException - * @throws DatabaseConnectionException + * @throws Exception + * @throws DoctrineException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface */ public function checkAccessRights() { @@ -35,12 +41,11 @@ class d3_webauthn_utils extends d3_webauthn_utils_parent $userID = $this->d3GetSessionObject()->getVariable("auth"); $webauthnAuth = (bool) $this->d3GetSessionObject()->getVariable(WebauthnConf::WEBAUTHN_SESSION_AUTH); - /** @var Webauthn $webauthn */ $webauthn = $this->d3GetWebauthnObject(); if ($blAuth && $webauthn->isActive($userID) && false === $webauthnAuth) { $this->redirect('index.php?cl=login', true, 302); - if (false == defined('OXID_PHP_UNIT')) { + if (!defined('OXID_PHP_UNIT')) { // @codeCoverageIgnoreStart exit; // @codeCoverageIgnoreEnd @@ -53,7 +58,7 @@ class d3_webauthn_utils extends d3_webauthn_utils_parent /** * @return Session */ - public function d3GetSessionObject() + public function d3GetSessionObject(): Session { return Registry::getSession(); } @@ -61,7 +66,7 @@ class d3_webauthn_utils extends d3_webauthn_utils_parent /** * @return Webauthn */ - public function d3GetWebauthnObject() + public function d3GetWebauthnObject(): Webauthn { return oxNew(Webauthn::class); } diff --git a/src/Setup/Events.php b/src/Setup/Events.php index b0922d9..cf9d5b0 100755 --- a/src/Setup/Events.php +++ b/src/Setup/Events.php @@ -17,9 +17,20 @@ namespace D3\Webauthn\Setup; +use Doctrine\DBAL\Driver\Exception as DoctrineDriverException; +use Doctrine\DBAL\Exception as DoctrineException; +use Doctrine\DBAL\Query\QueryBuilder; +use Exception; use OxidEsales\Eshop\Core\DatabaseProvider; use OxidEsales\Eshop\Core\DbMetaDataHandler; +use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; +use OxidEsales\Eshop\Core\Exception\DatabaseErrorException; use OxidEsales\Eshop\Core\Registry; +use OxidEsales\Eshop\Core\UtilsView; +use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; +use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; class Events { @@ -44,6 +55,9 @@ class Events /** * Execute action on activate event + * @return void + * @throws DatabaseConnectionException + * @throws DatabaseErrorException */ public static function onActivate() { @@ -52,6 +66,8 @@ class Events self::regenerateViews(); self::clearCache(); + + self::seoUrl(); } public static function onDeactivate() @@ -60,6 +76,9 @@ class Events /** * Execute the sql at the first time of the module installation. + * @return void + * @throws DatabaseConnectionException + * @throws DatabaseErrorException */ private static function setupModule() { @@ -75,7 +94,7 @@ class Events * * @return bool */ - protected static function tableExists($sTableName) + protected static function tableExists(string $sTableName): bool { $oDbMetaDataHandler = oxNew(DbMetaDataHandler::class ); @@ -86,6 +105,8 @@ class Events * Executes given sql statement. * * @param string $sSQL Sql to execute. + * @throws DatabaseConnectionException + * @throws DatabaseErrorException */ private static function executeSQL($sSQL) { @@ -100,7 +121,7 @@ class Events * * @return bool */ - protected static function fieldExists($sFieldName, $sTableName) + protected static function fieldExists(string $sFieldName, string $sTableName): bool { $oDbMetaDataHandler = oxNew(DbMetaDataHandler::class ); @@ -117,11 +138,11 @@ class Events } /** - * Empty cache + * clear cache */ private static function clearCache() { - /** @var \OxidEsales\Eshop\Core\UtilsView $oUtilsView */ + /** @var UtilsView $oUtilsView */ $oUtilsView = Registry::getUtilsView(); $sSmartyDir = $oUtilsView->getSmartyDir(); @@ -133,4 +154,65 @@ class Events } } } + + /** + * @return void + */ + private static function seoUrl() + { + try { + if (!self::hasSeoUrl()) { + self::createSeoUrl(); + } + } catch (Exception|NotFoundExceptionInterface|DoctrineDriverException|ContainerExceptionInterface $e) { + Registry::getUtilsView()->addErrorToDisplay('error wile creating SEO URLs: '.$e->getMessage()); + } + } + + /** + * @return bool + * @throws DoctrineDriverException + * @throws DoctrineException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + private static function hasSeoUrl(): bool + { + /** @var QueryBuilder $qb */ + $qb = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create(); + $qb->select('1') + ->from('oxseo') + ->where( + $qb->expr()->and( + $qb->expr()->eq( + 'oxstdurl', + $qb->createNamedParameter('index.php?cl=d3_account_webauthn') + ), + $qb->expr()->eq( + 'oxshopid', + $qb->createNamedParameter(Registry::getConfig()->getShopId()) + ), + $qb->expr()->eq( + 'oxlang', + $qb->createNamedParameter('1') + ) + ) + ) + ->setMaxResults(1); + return $qb->execute()->fetchOne(); + } + + /** + * @return void + * @throws DatabaseConnectionException + * @throws DatabaseErrorException + */ + private static function createSeoUrl() + { + $query = "INSERT INTO `oxseo` (`OXOBJECTID`, `OXIDENT`, `OXSHOPID`, `OXLANG`, `OXSTDURL`, `OXSEOURL`, `OXTYPE`, `OXFIXED`, `OXEXPIRED`, `OXPARAMS`, `OXTIMESTAMP`) VALUES + ('ff57646b47249ee33c6b672741ac371a', 'be07f06fe03a4d5d7936f2eac5e3a87b', 1, 1, 'index.php?cl=d3_account_webauthn', 'en/key-authintication/', 'static', 0, 0, '', NOW()), + ('ff57646b47249ee33c6b672741ac371a', '220a1af77362196789eeed4741dda184', 1, 0, 'index.php?cl=d3_account_webauthn', 'key-authentisierung/', 'static', 0, 0, '', NOW());"; + + DatabaseProvider::getDb()->execute($query); + } } \ No newline at end of file diff --git a/src/Setup/Installation.php b/src/Setup/Installation.php deleted file mode 100755 index 5359b50..0000000 --- a/src/Setup/Installation.php +++ /dev/null @@ -1,246 +0,0 @@ - - * @link http://www.oxidmodule.com - */ - -namespace D3\Webauthn\Setup; - -use D3\ModCfg\Application\Model\d3database; -use D3\ModCfg\Application\Model\Install\d3install_updatebase; -use Doctrine\DBAL\DBALException; -use OxidEsales\Eshop\Core\DatabaseProvider; -use OxidEsales\Eshop\Core\Exception\ConnectionException; -use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; -use OxidEsales\Eshop\Core\Exception\DatabaseErrorException; - -class Installation extends d3install_updatebase -{ - protected $_aUpdateMethods = array( - array('check' => 'doesPublicKeyCredentialTableNotExist', - 'do' => 'addPublicKeyCredentialTable'), - array('check' => 'checkFields', - 'do' => 'fixFields'), - array('check' => 'checkIndizes', - 'do' => 'fixIndizes'), - array('check' => 'checkSEONotExists', - 'do' => 'addSEO'), - ); - - public $aMultiLangTables = array(); - - public $aFields = array( - 'OXID' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'OXID', - 'sType' => 'CHAR(32)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'NAME' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'Name', - 'sType' => 'VARCHAR(255)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'CREDENTIALID' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'CredentialId', - 'sType' => 'BINARY(48)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'TYPE' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'Type', - 'sType' => 'CHAR(20)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'TRANSPORTS' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'Transports', - 'sType' => 'VARCHAR(255)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'ATTESTATIONTYPE' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'AttestationType', - 'sType' => 'CHAR(100)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'TRUSTPATH' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'TrustPath', - 'sType' => 'VARCHAR(255)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'AAGUID' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'Aaguid', - 'sType' => 'VARCHAR(255)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'PUBLICKEY' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'PublicKey', - 'sType' => 'BINARY(77)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'USERHANDLE' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'UserHandle', - 'sType' => 'CHAR(36)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'COUNTER' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'Counter', - 'sType' => 'INT(5)', - 'blNull' => false, - 'sDefault' => false, - 'sComment' => '', - 'sExtra' => '', - 'blMultilang' => false, - ), - 'OXTIMESTAMP' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sFieldName' => 'oxtimestamp', - 'sType' => 'TIMESTAMP', - 'blNull' => false, - 'sDefault' => 'CURRENT_TIMESTAMP', - 'sComment' => 'Timestamp', - 'sExtra' => '', - 'blMultilang' => false, - ) - ); - - public $aIndizes = array( - 'OXID' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sType' => d3database::INDEX_TYPE_PRIMARY, - 'sName' => 'PRIMARY', - 'aFields' => array( - 'OXID' => 'OXID', - ), - ), - 'OXUSERID' => array( - 'sTableName' => 'd3PublicKeyCredential', - 'sType' => d3database::INDEX_TYPE_UNIQUE, - 'sName' => 'CredentialId', - 'aFields' => array( - 'CredentialId' => 'CredentialId', - ), - ) - ); - - protected $_aRefreshMetaModuleIds = array('d3webauthn'); - - /** - * @return bool - * @throws DBALException - * @throws DatabaseConnectionException - * @throws DatabaseErrorException - */ - public function doesPublicKeyCredentialTableNotExist() - { - return $this->_checkTableNotExist('d3PublicKeyCredential'); - } - - /** - * @return bool - * @throws ConnectionException - * @throws DBALException - * @throws DatabaseConnectionException - * @throws DatabaseErrorException - */ - public function addPublicKeyCredentialTable() - { - $blRet = false; - if ($this->doesPublicKeyCredentialTableNotExist()) { - $this->setInitialExecMethod(__METHOD__); - $blRet = $this->_addTable2( - 'd3PublicKeyCredential', - $this->aFields, - $this->aIndizes, - 'key credentials', - 'InnoDB' - ); - } - - return $blRet; - } - - /** - * @return bool - * @throws DatabaseConnectionException - */ - public function checkSEONotExists() - { - $query = "SELECT 1 FROM " . getViewName('oxseo') . " WHERE oxstdurl = 'index.php?cl=d3_account_webauthn'"; - - return !DatabaseProvider::getDb()->getOne($query); - } - - /** - * @return bool - * @throws DatabaseConnectionException - * @throws DatabaseErrorException - */ - public function addSEO() - { - $query = [ - "INSERT INTO `oxseo` (`OXOBJECTID`, `OXIDENT`, `OXSHOPID`, `OXLANG`, `OXSTDURL`, `OXSEOURL`, `OXTYPE`, `OXFIXED`, `OXEXPIRED`, `OXPARAMS`, `OXTIMESTAMP`) VALUES -('ff57646b47249ee33c6b672741ac371a', 'be07f06fe03a4d5d7936f2eac5e3a87b', 1, 1, 'index.php?cl=d3_account_webauthn', 'en/key-authintication/', 'static', 0, 0, '', NOW()), -('ff57646b47249ee33c6b672741ac371a', '220a1af77362196789eeed4741dda184', 1, 0, 'index.php?cl=d3_account_webauthn', 'key-authentisierung/', 'static', 0, 0, '', NOW());" - ]; - - return $this->_executeMultipleQueries($query); - } -} \ No newline at end of file