Merge pull request #2 from tmloberon/tmloberon-force-2fa

Require administrators to activate 2FA.
This commit is contained in:
gitea Admin Panel 2022-09-26 15:01:29 +02:00 committed by GitHub
commit cdff7abe01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 201 additions and 71 deletions

View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace D3\Totp\Application\Controller\Admin;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Session;
class d3force_2fa extends d3user_totp
{
public function render()
{
$this->addTplParam('force2FA', true);
$userID = $this->d3GetSessionObject()->getVariable("auth");
$this->_sEditObjectId = $userID;
return parent::render();
}
protected function _authorize()
{
$userID = $this->d3GetSessionObject()->getVariable("auth");
return ($this->d3IsAdminForce2FA() && !empty($userID));
}
/**
* @return Session
*/
private function d3GetSessionObject()
{
return Registry::getSession();
}
/**
* @return bool
*/
private function d3IsAdminForce2FA()
{
return $this->isAdmin() &&
Registry::getConfig()->getConfigParam('D3_TOTP_ADMIN_FORCE_2FA') == true;
}
}

View File

@ -34,6 +34,11 @@ $aLang = [
'D3_TOTP_CURROTP' => 'Bestätigung mit Einmalpasswort', 'D3_TOTP_CURROTP' => 'Bestätigung mit Einmalpasswort',
'D3_TOTP_CURROTP_HELP' => 'Haben Sie dieses Kundenkonto in Ihrer Authentisierungs-App registriert, generieren Sie damit ein Einmalpasswort, tragen Sie es hier ein und senden das Formular direkt darauf hin ab.', 'D3_TOTP_CURROTP_HELP' => 'Haben Sie dieses Kundenkonto in Ihrer Authentisierungs-App registriert, generieren Sie damit ein Einmalpasswort, tragen Sie es hier ein und senden das Formular direkt darauf hin ab.',
'D3_TOTP_FORCE2FATITLE' => 'Verpflichtet Zwei-Faktor-Authentisierung',
'D3_TOTP_FORCE2FASUB' => 'Alle Administratoren müssen es aktivieren',
'D3_TOTP_ADMINBACKEND' => 'Admin-Oberfläche',
'D3_TOTP_ADMINCONTINUE' => 'weiter',
'D3_TOTP_REGISTEREXIST' => 'vorhandene Registrierung', 'D3_TOTP_REGISTEREXIST' => 'vorhandene Registrierung',
'D3_TOTP_REGISTERDELETE' => 'Registrierung löschen', 'D3_TOTP_REGISTERDELETE' => 'Registrierung löschen',
'D3_TOTP_REGISTERDELETE_DESC' => 'Um die Registrierung zu ändern, löschen Sie diese bitte vorerst. Sie können sofort im Anschluss eine neue Registrierung anlegen.<br>Wenn Sie die Registrierung löschen, ist das Konto nicht mehr durch die Zwei-Faktor-Authentisierung geschützt.', 'D3_TOTP_REGISTERDELETE_DESC' => 'Um die Registrierung zu ändern, löschen Sie diese bitte vorerst. Sie können sofort im Anschluss eine neue Registrierung anlegen.<br>Wenn Sie die Registrierung löschen, ist das Konto nicht mehr durch die Zwei-Faktor-Authentisierung geschützt.',
@ -48,4 +53,6 @@ $aLang = [
'D3_TOTP_ERROR_UNVALID' => 'Das Einmalpasswort ist ungültig.', 'D3_TOTP_ERROR_UNVALID' => 'Das Einmalpasswort ist ungültig.',
'D3_TOTP_ALREADY_EXIST' => 'Die Registrierung wurde schon gespeichert.', 'D3_TOTP_ALREADY_EXIST' => 'Die Registrierung wurde schon gespeichert.',
'SHOP_MODULE_D3_TOTP_ADMIN_FORCE_2FA' => 'Administratoren sind verpflichtet 2FA zu aktivieren'
]; ];

View File

@ -34,6 +34,11 @@ $aLang = [
'D3_TOTP_CURROTP' => 'Confirmation with one-time password', 'D3_TOTP_CURROTP' => 'Confirmation with one-time password',
'D3_TOTP_CURROTP_HELP' => 'If you have registered this customer account in your authentication app, you generate a one-time password, enter it here and send the form out immediately.', 'D3_TOTP_CURROTP_HELP' => 'If you have registered this customer account in your authentication app, you generate a one-time password, enter it here and send the form out immediately.',
'D3_TOTP_FORCE2FATITLE' => 'Mandates two-factor authentication',
'D3_TOTP_FORCE2FASUB' => 'All administrators need to activate it',
'D3_TOTP_ADMINBACKEND' => 'Admin-Backend',
'D3_TOTP_ADMINCONTINUE' => 'continue',
'D3_TOTP_REGISTEREXIST' => 'existing registration', 'D3_TOTP_REGISTEREXIST' => 'existing registration',
'D3_TOTP_REGISTERDELETE' => 'Delete registration', 'D3_TOTP_REGISTERDELETE' => 'Delete registration',
'D3_TOTP_REGISTERDELETE_DESC' => 'To change the registration, please delete it. You can then immediately create a new registration. <br> If you delete the registration, the account is no longer protected by the two-factor authentication.', 'D3_TOTP_REGISTERDELETE_DESC' => 'To change the registration, please delete it. You can then immediately create a new registration. <br> If you delete the registration, the account is no longer protected by the two-factor authentication.',
@ -48,4 +53,6 @@ $aLang = [
'D3_TOTP_ERROR_UNVALID' => 'The one-time password is invalid.', 'D3_TOTP_ERROR_UNVALID' => 'The one-time password is invalid.',
'D3_TOTP_ALREADY_EXIST' => 'The registration has already been saved.', 'D3_TOTP_ALREADY_EXIST' => 'The registration has already been saved.',
'SHOP_MODULE_D3_TOTP_ADMIN_FORCE_2FA' => 'Administrators are required to activate 2FA'
]; ];

View File

@ -14,8 +14,25 @@
td.edittext { td.edittext {
white-space: normal; white-space: normal;
} }
.hero {
display: inline-block;
}
.hero > h1 {
padding: 0.3em 0;
}
.hero > div {
text-align: right;
color: #6c7c98;
}
</style> </style>
[{if $force2FA}]
<div class="hero">
<h1>[{oxmultilang ident="D3_TOTP_FORCE2FATITLE"}]</h1>
<div>[{oxmultilang ident="D3_TOTP_FORCE2FASUB"}]</div>
</div>
[{/if}]
<form name="transfer" id="transfer" action="[{$oViewConf->getSelfLink()}]" method="post"> <form name="transfer" id="transfer" action="[{$oViewConf->getSelfLink()}]" method="post">
[{$oViewConf->getHiddenSid()}] [{$oViewConf->getHiddenSid()}]
<input type="hidden" name="oxid" value="[{$oxid}]"> <input type="hidden" name="oxid" value="[{$oxid}]">
@ -60,6 +77,22 @@
[{oxinputhelp ident="D3_TOTP_QRCODE_HELP"}] [{oxinputhelp ident="D3_TOTP_QRCODE_HELP"}]
</td> </td>
</tr> </tr>
[{elseif $force2FA}]
<tr>
<td class="edittext" colspan="2">
<h4>[{oxmultilang ident="D3_TOTP_ADMINBACKEND"}]</h4>
</td>
</tr>
<tr>
<td class="edittext" colspan="2">
<input
type="submit" class="edittext" id="oLockButton" name="delete"
value="[{oxmultilang ident="D3_TOTP_ADMINCONTINUE"}]"
onClick="document.myedit.fnc.value='';document.myedit.cl.value='admin_start'"
>
</td>
</tr>
[{else}] [{else}]
<tr> <tr>
<td class="edittext" colspan="2"> <td class="edittext" colspan="2">
@ -153,5 +186,7 @@
[{/if}] [{/if}]
</form> </form>
[{include file="bottomnaviitem.tpl"}] [{if !$force2FA}]
[{include file="bottomitem.tpl"}] [{include file="bottomnaviitem.tpl"}]
[{include file="bottomitem.tpl"}]
[{/if}]

View File

@ -1,68 +1,93 @@
<?php <?php
/** /**
* This Software is the property of Data Development and is protected * This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware. * by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license * Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by * is a violation of the license agreement and will be prosecuted by
* civil and criminal law. * civil and criminal law.
* http://www.shopmodule.com * http://www.shopmodule.com
* *
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch) * @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com> * @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com * @link http://www.oxidmodule.com
*/ */
namespace D3\Totp\Modules\Core; namespace D3\Totp\Modules\Core;
use D3\Totp\Application\Model\d3totp; use D3\Totp\Application\Model\d3totp;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Session; use OxidEsales\Eshop\Core\Session;
class d3_totp_utils extends d3_totp_utils_parent class d3_totp_utils extends d3_totp_utils_parent
{ {
/** /**
* @return bool * @return bool
* @throws DBALException * @throws DBALException
* @throws DatabaseConnectionException * @throws DatabaseConnectionException
*/ */
public function checkAccessRights() public function checkAccessRights()
{ {
$blAuth = parent::checkAccessRights(); $blAuth = parent::checkAccessRights();
$userID = $this->d3GetSessionObject()->getVariable("auth"); $userID = $this->d3GetSessionObject()->getVariable("auth");
$totpAuth = (bool) $this->d3GetSessionObject()->getVariable(d3totp::TOTP_SESSION_VARNAME); $totpAuth = (bool) $this->d3GetSessionObject()->getVariable(d3totp::TOTP_SESSION_VARNAME);
/** @var d3totp $totp */ /** @var d3totp $totp */
$totp = $this->d3GetTotpObject(); $totp = $this->d3GetTotpObject();
$totp->loadByUserId($userID); $totp->loadByUserId($userID);
if ($blAuth && $totp->isActive() && false === $totpAuth) { //checkt ob alle Admin 2FA aktiviert hat
$this->redirect('index.php?cl=login', true, 302); //todo braucht Unit Test
if (false == defined('OXID_PHP_UNIT')) { if (
// @codeCoverageIgnoreStart $this->d3IsAdminForce2FA()
exit; && $blAuth
// @codeCoverageIgnoreEnd && $totp->isActive() === false
} ) {
} $this->redirect('index.php?cl=d3force_2fa', true, 302);
if (false == defined('OXID_PHP_UNIT')) {
return $blAuth; // @codeCoverageIgnoreStart
} exit;
// @codeCoverageIgnoreEnd
/** }
* @return Session }
*/
public function d3GetSessionObject() //staten der prüfung vom einmalpasswort
{ if ($blAuth && $totp->isActive() && false === $totpAuth) {
return Registry::getSession(); $this->redirect('index.php?cl=login', true, 302);
} if (false == defined('OXID_PHP_UNIT')) {
// @codeCoverageIgnoreStart
/** exit;
* @return d3totp // @codeCoverageIgnoreEnd
*/ }
public function d3GetTotpObject() }
{
return oxNew(d3totp::class); return $blAuth;
} }
}
/**
* @return Session
*/
public function d3GetSessionObject()
{
return Registry::getSession();
}
/**
* @return d3totp
*/
public function d3GetTotpObject()
{
return oxNew(d3totp::class);
}
/**
* @return bool
*/
private function d3IsAdminForce2FA()
{
return $this->isAdmin() &&
Registry::getConfig()->getConfigParam('D3_TOTP_ADMIN_FORCE_2FA') == true;
}
}

View File

@ -16,6 +16,7 @@
*/ */
use D3\Totp\Application\Controller\Admin\d3user_totp; use D3\Totp\Application\Controller\Admin\d3user_totp;
use D3\Totp\Application\Controller\Admin\d3force_2fa;
use D3\Totp\Application\Controller\d3_account_totp; use D3\Totp\Application\Controller\d3_account_totp;
use D3\Totp\Application\Controller\d3totplogin; use D3\Totp\Application\Controller\d3totplogin;
use D3\Totp\Modules\Application\Component\d3_totp_UserComponent; use D3\Totp\Modules\Application\Component\d3_totp_UserComponent;
@ -72,6 +73,7 @@ $aModule = [
], ],
'controllers' => [ 'controllers' => [
'd3user_totp' => d3user_totp::class, 'd3user_totp' => d3user_totp::class,
'd3force_2fa' => d3force_2fa::class,
'd3totplogin' => d3totplogin::class, 'd3totplogin' => d3totplogin::class,
'd3_account_totp' => d3_account_totp::class, 'd3_account_totp' => d3_account_totp::class,
], ],
@ -80,6 +82,14 @@ $aModule = [
'd3totplogin.tpl' => 'd3/totp/Application/views/tpl/d3totplogin.tpl', 'd3totplogin.tpl' => 'd3/totp/Application/views/tpl/d3totplogin.tpl',
'd3_account_totp.tpl' => 'd3/totp/Application/views/tpl/d3_account_totp.tpl', 'd3_account_totp.tpl' => 'd3/totp/Application/views/tpl/d3_account_totp.tpl',
], ],
'settings' => [
[
'group' => 'main',
'name' => 'D3_TOTP_ADMIN_FORCE_2FA',
'type' => 'bool',
'value' => false,
]
],
'events' => [ 'events' => [
'onActivate' => '\D3\Totp\Setup\Events::onActivate', 'onActivate' => '\D3\Totp\Setup\Events::onActivate',
'onDeactivate' => '\D3\Totp\Setup\Events::onDeactivate', 'onDeactivate' => '\D3\Totp\Setup\Events::onDeactivate',
@ -94,6 +104,6 @@ $aModule = [
'template' => 'page/account/inc/account_menu.tpl', 'template' => 'page/account/inc/account_menu.tpl',
'block' => 'account_menu', 'block' => 'account_menu',
'file' => 'Application/views/blocks/page/account/inc/account_menu.tpl', 'file' => 'Application/views/blocks/page/account/inc/account_menu.tpl',
] ],
] ]
]; ];