initial implementation for frontend account area

This commit is contained in:
Daniel Seifert 2019-08-02 23:58:20 +02:00
parent 6731246784
commit cea9e246ba
7 changed files with 289 additions and 8 deletions

View File

@ -0,0 +1,114 @@
<?php
namespace D3\Totp\Application\Controller;
use D3\Totp\Application\Model\d3backupcodelist;
use D3\Totp\Application\Model\d3totp;
use D3\Totp\Modules\Application\Model\d3_totp_user;
use Doctrine\DBAL\DBALException;
use Exception;
use OxidEsales\Eshop\Application\Controller\AccountController;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\StandardException;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\UtilsView;
class d3_account_totp extends AccountController
{
protected $_sThisTemplate = 'd3_account_totp.tpl';
public $aBackupCodes = [];
public function render()
{
// is logged in ?
$oUser = $this->getUser();
if (!$oUser) {
dumpvar(__LINE__);
dumpvar($this->_sThisLoginTemplate);
return $this->_sThisTemplate = $this->_sThisLoginTemplate;
}
$this->addTplParam('user', $this->getUser());
return parent::render();
}
/**
* @param $aCodes
*/
public function setBackupCodes($aCodes)
{
$this->aBackupCodes = $aCodes;
}
/**
* @return string
*/
public function getBackupCodes()
{
return implode(PHP_EOL, $this->aBackupCodes);
}
/**
* @return int
* @throws DatabaseConnectionException
*/
public function getAvailableBackupCodeCount()
{
$oBackupCodeList = oxNew(d3backupcodelist::class);
return $oBackupCodeList->getAvailableCodeCount($this->getUser()->getId());
}
public function create()
{
if (Registry::getRequest()->getRequestEscapedParameter('totp_use') === '1') {
try {
/** @var d3_totp_user $oUser */
$oUser = $this->getUser();
/** @var d3totp $oTotp */
$oTotp = oxNew(d3totp::class);
$oTotpBackupCodes = oxNew(d3backupcodelist::class);
$aParams = [
'd3totp__usetotp' => 1,
'd3totp__oxuserid' => $oUser->getId()
];
$seed = Registry::getRequest()->getRequestEscapedParameter("secret");
$otp = Registry::getRequest()->getRequestEscapedParameter("otp");
$oTotp->saveSecret($seed);
$oTotp->assign($aParams);
$oTotp->verify($otp, $seed);
$oTotpBackupCodes->generateBackupCodes($oUser->getId());
$oTotp->setId();
$oTotp->save();
$oTotpBackupCodes->save();
} catch (Exception $oExcp) {
Registry::get(UtilsView::class)->addErrorToDisplay($oExcp);
}
}
}
/**
* @throws DatabaseConnectionException
* @throws DBALException
*/
public function delete()
{
if (Registry::getRequest()->getRequestEscapedParameter('totp_use') != 1) {
$oUser = $this->getUser();
/** @var d3totp $oTotp */
$oTotp = oxNew(d3totp::class);
if ($oUser && $oUser->getId()) {
$oTotp->loadByUserId($oUser->getId());
$oTotp->delete();
}
}
}
}

View File

@ -21,10 +21,32 @@ $aLang = [
'charset' => 'UTF-8',
'D3_TOTP_INPUT' => 'Authentisierungscode',
'D3_TOTP_INPUT_HELP' => 'Das Einmalpasswort erhalten Sie von der Zweifaktorauthentisierung-App auf Ihrem Gerät.',
'D3_TOTP_INPUT_HELP' => 'Das Einmalpasswort erhalten Sie von der Zwei-Faktor-Authentisierungs-App auf Ihrem Gerät.',
'D3_TOTP_SUBMIT_LOGIN' => 'Anmelden',
'D3_TOTP_CANCEL_LOGIN' => 'Anmeldung abbrechen',
'D3_TOTP_BREADCRUMB' => 'Einmalpasswort-Anmeldung',
'D3_TOTP_ERROR_UNVALID' => 'Das Einmalpasswort ist ungültig.',
'D3_TOTP_ACCOUNT' => '2-Faktor-Authentisierung',
'D3_TOTP_ACCOUNT_USE' => '2-Faktor-Authentisierung verwenden',
'D3_TOTP_REGISTERNEW' => 'neue Registrierung erstellen',
'D3_TOTP_QRCODE' => 'QR-Code',
'D3_TOTP_QRCODE_HELP' => 'Scannen Sie diesen QR-Code mit Ihrer Authentisierungs-App, um dieses Benutzerkonto dort zu hinterlegen.',
'D3_TOTP_SECRET' => 'QR-Code kann nicht gescannt werden?',
'D3_TOTP_SECRET_HELP' => 'Setzen Sie keine App ein, die den QR-Code scannen kann, können Sie diese Zeichenkette auch in Ihr Authentisierungstool kopieren. Stellen Sie bitte zusätzlich die Passwortlänge auf 6 Zeichen und das Zeitinterval auf 30 Sekunden ein.',
'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_REGISTEREXIST' => 'vorhandene Registrierung',
'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_CONFIRM' => 'Soll die bestehende 2-Faktor-Authentisierung gelöscht werden?',
'D3_TOTP_BACKUPCODES' => 'Backupcodes',
'D3_TOTP_BACKUPCODES_DESC' => 'Mit diesen Backupcodes können Sie sich anmelden, wenn die Generierung des Einmalpasswortes nicht möglich ist (z.B. Gerät verloren oder neu installiert). Sie können dann die Einstellungen zur Verwendung der 2-Faktor-Authentisierung ändern oder einen neuen Zugang erstellen. Speichern Sie sich diese Codes bitte in diesem Moment sicher ab. Nach Verlassen dieser Seite können diese Codes nicht erneut angezeigt werden.',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcodes verfügbar',
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'Um neue Backupcodes zu erstellen, löschen Sie die bestehende Registrierung und legen diese bitte neu an.',
'D3_TOTP_ACCOUNT_SAVE' => 'Einstellungen übernehmen',
];

View File

@ -21,7 +21,7 @@ $aLang = [
'charset' => 'UTF-8',
'TOTP_INPUT' => 'Authentisierungscode',
'TOTP_INPUT_HELP' => 'Das Einmalpasswort erhalten Sie von der Zweifaktorauthentisierung-App auf Ihrem Gerät.',
'TOTP_INPUT_HELP' => 'Das Einmalpasswort erhalten Sie von der Zwei-Faktor-Authentisierungs-App auf Ihrem Gerät.',
'TOTP_CANCEL_LOGIN' => 'Anmeldung abbrechen',
'd3mxuser_totp' => '2-Faktor-Authentisierung',
@ -38,7 +38,7 @@ $aLang = [
'D3_TOTP_REGISTEREXIST' => 'vorhandene Registrierung',
'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 Zweifaktorauthentisierung 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.',
'D3_TOTP_BACKUPCODES' => 'Backupcodes',
'D3_TOTP_BACKUPCODES_DESC' => 'Mit diesen Backupcodes können Sie sich anmelden, wenn die Generierung des Einmalpasswortes nicht möglich ist (z.B. Gerät verloren oder neu installiert). Sie können dann die Einstellungen zur Verwendung der 2-Faktor-Authentisierung ändern oder einen neuen Zugang erstellen. Speichern Sie sich diese Codes bitte in diesem Moment sicher ab. Nach Verlassen dieser Seite können diese Codes nicht erneut angezeigt werden.',

View File

@ -1,4 +1,4 @@
[{$smarty.block.parent}]
<li class="list-group-item[{if $active_link == "downloads"}] active[{/if}]">
<li class="list-group-item[{if $active_link == "d3totp"}] active[{/if}]">
<a href="[{oxgetseourl ident=$oViewConf->getSelfLink()|cat:"cl=d3_account_totp"}]" title="[{oxmultilang ident="D3_TOTP_ACCOUNT"}]">[{oxmultilang ident="D3_TOTP_ACCOUNT"}]</a>
</li>

View File

@ -0,0 +1,127 @@
[{capture append="oxidBlock_content"}]
<h1 class="page-header">[{oxmultilang ident="D3_TOTP_ACCOUNT"}]</h1>
[{assign var="totp" value=$user->d3GetTotp()}]
<style type="text/css">
.registerNew {
display: none;
}
[{if false == $totp->getId()}]
.submitBtn {
display: none;
}
[{/if}]
</style>
[{block name="d3_account_totp"}]
<form action="[{$oViewConf->getSelfActionLink()}]" name="d3totpform" class="form-horizontal" method="post">
<div class="hidden">
[{$oViewConf->getHiddenSid()}]
[{$oViewConf->getNavFormParams()}]
<input type="hidden" id="fncname" name="fnc" value="">
<input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]">
</div>
<p>
<input id="totp_use" value="1" type="checkbox" name="totp_use" [{if $totp->getId()}] checked[{/if}] [{if false == $totp->getId()}]onclick="$('.registerNew').toggle(); $('.submitBtn').toggle();"[{/if}]>
<label for="totp_use">[{oxmultilang ident="D3_TOTP_ACCOUNT_USE"}]</label>
</p>
[{if false == $totp->getId()}]
<div class="registerNew panel panel-default">
<div class="panel-heading">
[{oxmultilang ident="D3_TOTP_REGISTERNEW"}]
</div>
<div class="panel-body">
<p>
[{oxmultilang ident="D3_TOTP_QRCODE"}]&nbsp;
[{$totp->getQrCodeElement()}]
</p>
<p>
[{oxmultilang ident="D3_TOTP_QRCODE_HELP"}]
</p>
<hr>
<p>
<label for="secret">[{oxmultilang ident="D3_TOTP_SECRET"}]</label>
<textarea rows="3" cols="50" id="secret" name="secret" class="editinput" readonly="readonly">[{$totp->getSecret()}]</textarea>
</p>
<p>
[{oxmultilang ident="D3_TOTP_SECRET_HELP"}]
</p>
<hr>
<p>
<label for="otp">[{oxmultilang ident="D3_TOTP_CURROTP"}]</label>
<input type="text" class="editinput" size="6" maxlength="6" id="otp" name="otp" value="" [{$readonly}]>
</p>
<p>
[{oxmultilang ident="D3_TOTP_CURROTP_HELP"}]
</p>
</div>
</div>
[{/if}]
[{if $totp->getId()}]
[{block name="d3_account_totp_deletenotes"}]
<div class="panel panel-default">
<div class="panel-heading">
[{oxmultilang ident="D3_TOTP_REGISTEREXIST"}]
</div>
<div class="panel-body">
[{oxmultilang ident="D3_TOTP_REGISTERDELETE_DESC"}]
</div>
</div>
[{/block}]
[{block name="d3_account_totp_backupcodes"}]
<div class="panel panel-default">
<div class="panel-heading">
[{oxmultilang ident="D3_TOTP_BACKUPCODES"}]
</div>
<div class="panel-body">
[{if $oView->getBackupCodes()}]
[{block name="d3_account_totp_backupcodes_list"}]
<label for="backupcodes">[{oxmultilang ident="D3_TOTP_BACKUPCODES_DESC"}]</label>
<textarea id="backupcodes" rows="10" cols="20">[{$oView->getBackupCodes()}]</textarea>
[{/block}]
[{else}]
[{block name="d3_account_totp_backupcodes_info"}]
[{oxmultilang ident="D3_TOTP_AVAILBACKUPCODECOUNT" args=$oView->getAvailableBackupCodeCount()}]<br>
[{oxmultilang ident="D3_TOTP_AVAILBACKUPCODECOUNT_DESC"}]
[{/block}]
[{/if}]
</div>
</div>
[{/block}]
[{/if}]
<p class="submitBtn">
<button type="submit" class="btn btn-primary"
[{if $totp->getId()}]
onclick="
if(false === document.getElementById('totp_use').checked && false === confirm('[{oxmultilang ident="D3_TOTP_REGISTERDELETE_CONFIRM"}]')) {return false;}
document.getElementById('fncname').value = 'delete';
"
[{else}]
onclick="document.getElementById('fncname').value = 'create';"
[{/if}]
>
[{oxmultilang ident="D3_TOTP_ACCOUNT_SAVE"}]
</button>
</p>
</form>
[{/block}]
[{/capture}]
[{capture append="oxidBlock_sidebar"}]
[{include file="page/account/inc/account_menu.tpl" active_link="d3totp"}]
[{/capture}]
[{include file="layout/page.tpl" sidebar="Left"}]

View File

@ -16,6 +16,8 @@
namespace D3\Totp\Modules\Application\Model;
use D3\Totp\Application\Model\d3totp;
use Doctrine\DBAL\DBALException;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Registry;
class d3_totp_user extends d3_totp_user_parent
@ -28,4 +30,17 @@ class d3_totp_user extends d3_totp_user_parent
return $return;
}
/**
* @return d3totp
* @throws DatabaseConnectionException
* @throws DBALException
*/
public function d3getTotp()
{
$oTotp = oxNew(d3totp::class);
$oTotp->loadByUserId($this->getId());
return $oTotp;
}
}

View File

@ -16,6 +16,7 @@
*/
use D3\Totp\Application\Controller\Admin\d3user_totp;
use D3\Totp\Application\Controller\d3_account_totp;
use D3\Totp\Application\Controller\d3totplogin;
use D3\Totp\Modules\Application\Component\d3_totp_UserComponent;
use D3\Totp\Modules\Application\Controller\Admin\d3_totp_LoginController;
@ -71,11 +72,13 @@ $aModule = [
],
'controllers' => [
'd3user_totp' => d3user_totp::class,
'd3totplogin' => d3totplogin::class
'd3totplogin' => d3totplogin::class,
'd3_account_totp' => d3_account_totp::class,
],
'templates' => [
'd3user_totp.tpl' => 'd3/totp/Application/views/admin/tpl/d3user_totp.tpl',
'd3totplogin.tpl' => 'd3/totp/Application/views/tpl/d3totplogin.tpl',
'templates' => [
'd3user_totp.tpl' => 'd3/totp/Application/views/admin/tpl/d3user_totp.tpl',
'd3totplogin.tpl' => 'd3/totp/Application/views/tpl/d3totplogin.tpl',
'd3_account_totp.tpl' => 'd3/totp/Application/views/tpl/d3_account_totp.tpl',
],
'events' => [
'onActivate' => '\D3\Totp\Setup\Events::onActivate',