forked from D3Public/oxtotp
Compare commits
17 Commits
Author | SHA1 | Date |
---|---|---|
Daniel Seifert | bb594eb3c9 | |
Daniel Seifert | 5b6dd4a4da | |
gitea Admin Panel | cdff7abe01 | |
Daniel Seifert | 6b9130fc79 | |
Daniel Seifert | 87e18c90a1 | |
gitea Admin Panel | f0a3124303 | |
Daniel Seifert | 26f5b6b460 | |
Tobias Matthaiou | d3576c2dd7 | |
Tobias Matthaiou | 96f6de6300 | |
Tobias Matthaiou | 219427fb75 | |
gitea Admin Panel | 6e72394bc7 | |
gitea Admin Panel | 4b4176cc7b | |
Daniel Seifert | 9bef2d93e7 | |
Daniel Seifert | fa34a5b762 | |
Daniel Seifert | 3816d0fa35 | |
Daniel Seifert | 86cd851e1e | |
Daniel Seifert | 6bb22efefd |
Binary file not shown.
|
@ -0,0 +1,12 @@
|
||||||
|
# oxtotp (2FA)
|
||||||
|
Modul für eine 2-Faktor-Authentisierung (2FA) zum Login in Front- und Backend zusätzlich zu Benutzername und Passwort.
|
||||||
|
|
||||||
|
- Authentisierung wird nur bei Benutzerkonten gezeigt, die dieses aktiviert haben - sonst nur Standardanmeldung die Basis der Passwortgenerierung wird fĂĽr jedes Benutzerkonto individuell angelegt</li>
|
||||||
|
|
||||||
|
- Einrichtung des Zugangs in der Auth-App kann durch scanbaren QR-Code oder kopierbare Zeichenkette erfolgen
|
||||||
|
|
||||||
|
- Validierung der Einmalpassworte und Generierung der QR-Codes werden ausschließlich innerhalb des Shops durchgeführt - keine Kommunikation nach außen nötig
|
||||||
|
|
||||||
|
- statische Backupcodes ermöglichen auch eine (begrenzte) Anmeldung ohne Zugang zum Generierungstool
|
||||||
|
|
||||||
|
- optionale Verpflichtung zur 2FA-Nutzung fĂĽr Adminuser
|
|
@ -13,8 +13,14 @@
|
||||||
{
|
{
|
||||||
"name": "D3 Data Development (Inh. Thomas Dartsch)",
|
"name": "D3 Data Development (Inh. Thomas Dartsch)",
|
||||||
"email": "info@shopmodule.com",
|
"email": "info@shopmodule.com",
|
||||||
"homepage": "http://www.d3data.de",
|
"homepage": "https://www.d3data.de",
|
||||||
"role": "Owner"
|
"role": "Owner"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tobi Matthaiou",
|
||||||
|
"email": "tm@loberon.com",
|
||||||
|
"homepage": "http://www.loberon.de",
|
||||||
|
"role": "Contributor"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
|
@ -32,11 +38,15 @@
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.6",
|
"php": ">=5.6",
|
||||||
"oxid-esales/oxideshop-metapackage-ce": "~6.0.3 || ~6.1.0 || ~6.2.0",
|
"ext-xmlwriter": "*",
|
||||||
|
"oxid-esales/oxideshop-ce": "6.2.1 - 6.7",
|
||||||
"spomky-labs/otphp": "^8.3",
|
"spomky-labs/otphp": "^8.3",
|
||||||
"bacon/bacon-qr-code": "^1.0",
|
"bacon/bacon-qr-code": "^1.0 || ^2.0",
|
||||||
"zendframework/zend-math": "^3.2"
|
"zendframework/zend-math": "^3.2"
|
||||||
},
|
},
|
||||||
|
"suggest": {
|
||||||
|
"d3/modcfg": "Provides automatic installation routines"
|
||||||
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"D3\\Totp\\": "../../../source/modules/d3/totp"
|
"D3\\Totp\\": "../../../source/modules/d3/totp"
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
Die [2-Faktor-Authentisierung](https://de.wikipedia.org/wiki/Zwei-Faktor-Authentisierung) ermöglicht es den Shopbesuchern, neben der üblichen Kombination aus Benutzername und Passwort auch ein [zeitgesteuertes Einmalpasswort](https://de.wikipedia.org/wiki/Time-based_One-time_Password_Algorithmus) zur Anmeldung abfragen zu lassen. Dies erhöht die Sicherheit im Anmeldeprozess deutlich und macht auch Anmeldungen in öffentlichen Netzwerken oder Internet-Cafés sicherer.
|
Die [2-Faktor-Authentisierung](https://de.wikipedia.org/wiki/Zwei-Faktor-Authentisierung) ermöglicht es den Shopbesuchern, neben der üblichen Kombination aus Benutzername und Passwort auch ein [zeitgesteuertes Einmalpasswort](https://de.wikipedia.org/wiki/Time-based_One-time_Password_Algorithmus) zur Anmeldung abfragen zu lassen. Dies erhöht die Sicherheit im Anmeldeprozess deutlich und macht auch Anmeldungen in öffentlichen Netzwerken oder Internet-Cafés sicherer.
|
||||||
Das abgefragte Einmalpasswort wird z.B. durch entsprechende Apps auf dem Smartphone erzeugt.
|
Das abgefragte Einmalpasswort wird z.B. durch entsprechende Apps auf dem Smartphone erzeugt. Die folgenden Apps sind Empfehlungen und können gegen andere nach dem TOTP-Standard arbeitende Apps getauscht werden.
|
||||||
|
|
||||||
|
[![Authenticator Apps bei Google Play](https://play.google.com/intl/en_us/badges/images/generic/de_badge_web_generic.png)](http://play.google.com/store/search?q=totp%20authenticator&c=apps)
|
||||||
|
|
||||||
|
[![Authenticator Apps im Apple Store](https://apps.apple.com/de/app/totp-authenticator-fast-2fa/id1404230533)](https://apps.apple.com/de/app/totp-authenticator-fast-2fa/id1404230533)
|
||||||
|
|
||||||
Die Einrichtung dieses 2. Faktors ist optional und lässt sich für jedes Benutzerkonto separat einrichten. Die Einrichtung erfolgt im "Mein Konto"-Bereich, über das Shopbackend kann die Einrichtung ebenfalls durchgeführt werden.
|
Die Einrichtung dieses 2. Faktors ist optional und lässt sich für jedes Benutzerkonto separat einrichten. Die Einrichtung erfolgt im "Mein Konto"-Bereich, über das Shopbackend kann die Einrichtung ebenfalls durchgeführt werden.
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
title: Changelog
|
title: Changelog
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 1.1.0.0 (2022-09-30)
|
||||||
|
|
||||||
|
###
|
||||||
|
- optionale Verpflichtung zur 2FA-Nutzung fĂĽr Adminbenutzer
|
||||||
|
|
||||||
## 1.0.0.0 (2019-08-19)
|
## 1.0.0.0 (2019-08-19)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"title": "<i class='fab fa-d3 d3fa-color-blue'></i> 2-Faktor-Authentisierung",
|
"title": "<i class='fab fa-d3 d3fa-color-blue'></i> 2-Faktor-Authentisierung",
|
||||||
"moduleversion": "1.0.0.0",
|
"moduleversion": "1.1.0.0",
|
||||||
"titledesc": "fĂĽr den Oxid eShop",
|
"titledesc": "fĂĽr den Oxid eShop",
|
||||||
"author": "DÂł Data Development",
|
"author": "DÂł Data Development",
|
||||||
"moduledate": "19.08.2019",
|
"moduledate": "30.09.2022",
|
||||||
"editors": "DS",
|
"editors": "DS",
|
||||||
"tagline": "",
|
"tagline": "",
|
||||||
"image": "",
|
"image": "",
|
||||||
|
|
|
@ -5,7 +5,7 @@ title: Schnellstart per Composer
|
||||||
## Schnellstart per Composer
|
## Schnellstart per Composer
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
php composer require {$composerident} –-update-no-dev
|
php composer require {$composerident} --update-no-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Detailliertere Angaben zur Installation entnehmen Sie bitte den folgenden Seiten.
|
Detailliertere Angaben zur Installation entnehmen Sie bitte den folgenden Seiten.
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace D3\Totp\Application\Factory;
|
||||||
|
|
||||||
|
use BaconQrCode\Renderer\RendererInterface;
|
||||||
|
use BaconQrCode\Renderer\Image\Svg; // v1.0.3
|
||||||
|
use BaconQrCode\Renderer\ImageRenderer; // v2.0.0
|
||||||
|
use BaconQrCode\Renderer\Image\SvgImageBackEnd; // v2.0.0
|
||||||
|
use BaconQrCode\Renderer\RendererStyle\RendererStyle; // v2.0.0
|
||||||
|
|
||||||
|
|
||||||
|
class BaconQrCodeFactory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return RendererInterface
|
||||||
|
*/
|
||||||
|
public static function renderer($size)
|
||||||
|
{
|
||||||
|
if (class_exists(Svg::class)) {
|
||||||
|
return self::v100($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::v200($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function v200($size)
|
||||||
|
{
|
||||||
|
$renderer = oxNew(
|
||||||
|
ImageRenderer::class,
|
||||||
|
oxNew(RendererStyle::class, $size),
|
||||||
|
oxNew(SvgImageBackEnd::class),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function v100($size)
|
||||||
|
{
|
||||||
|
$renderer = oxNew(Svg::class);
|
||||||
|
$renderer->setHeight($size);
|
||||||
|
$renderer->setWidth($size);
|
||||||
|
|
||||||
|
return $renderer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,9 +15,9 @@
|
||||||
|
|
||||||
namespace D3\Totp\Application\Model;
|
namespace D3\Totp\Application\Model;
|
||||||
|
|
||||||
use BaconQrCode\Renderer\Image\Svg;
|
|
||||||
use BaconQrCode\Renderer\RendererInterface;
|
use BaconQrCode\Renderer\RendererInterface;
|
||||||
use BaconQrCode\Writer;
|
use BaconQrCode\Writer;
|
||||||
|
use D3\Totp\Application\Factory\BaconQrCodeFactory;
|
||||||
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
|
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
|
||||||
use Doctrine\DBAL\DBALException;
|
use Doctrine\DBAL\DBALException;
|
||||||
use OTPHP\TOTP;
|
use OTPHP\TOTP;
|
||||||
|
@ -177,10 +177,7 @@ class d3totp extends BaseModel
|
||||||
*/
|
*/
|
||||||
public function getQrCodeElement()
|
public function getQrCodeElement()
|
||||||
{
|
{
|
||||||
$renderer = oxNew(Svg::class);
|
$renderer = BaconQrCodeFactory::renderer(200);
|
||||||
$renderer->setHeight(200);
|
|
||||||
$renderer->setWidth(200);
|
|
||||||
|
|
||||||
$writer = $this->d3GetWriter($renderer);
|
$writer = $this->d3GetWriter($renderer);
|
||||||
return $writer->writeString($this->getTotp()->getProvisioningUri());
|
return $writer->writeString($this->getTotp()->getProvisioningUri());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'
|
||||||
];
|
];
|
||||||
|
|
|
@ -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'
|
||||||
];
|
];
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
[{if !$force2FA}]
|
||||||
[{include file="bottomnaviitem.tpl"}]
|
[{include file="bottomnaviitem.tpl"}]
|
||||||
[{include file="bottomitem.tpl"}]
|
[{include file="bottomitem.tpl"}]
|
||||||
|
[{/if}]
|
||||||
|
|
|
@ -38,6 +38,22 @@ class d3_totp_utils extends d3_totp_utils_parent
|
||||||
$totp = $this->d3GetTotpObject();
|
$totp = $this->d3GetTotpObject();
|
||||||
$totp->loadByUserId($userID);
|
$totp->loadByUserId($userID);
|
||||||
|
|
||||||
|
//checkt ob alle Admin 2FA aktiviert hat
|
||||||
|
//todo braucht Unit Test
|
||||||
|
if (
|
||||||
|
$this->d3IsAdminForce2FA()
|
||||||
|
&& $blAuth
|
||||||
|
&& $totp->isActive() === false
|
||||||
|
) {
|
||||||
|
$this->redirect('index.php?cl=d3force_2fa', true, 302);
|
||||||
|
if (false == defined('OXID_PHP_UNIT')) {
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
exit;
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//staten der prĂĽfung vom einmalpasswort
|
||||||
if ($blAuth && $totp->isActive() && false === $totpAuth) {
|
if ($blAuth && $totp->isActive() && false === $totpAuth) {
|
||||||
$this->redirect('index.php?cl=login', true, 302);
|
$this->redirect('index.php?cl=login', true, 302);
|
||||||
if (false == defined('OXID_PHP_UNIT')) {
|
if (false == defined('OXID_PHP_UNIT')) {
|
||||||
|
@ -65,4 +81,13 @@ class d3_totp_utils extends d3_totp_utils_parent
|
||||||
{
|
{
|
||||||
return oxNew(d3totp::class);
|
return oxNew(d3totp::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function d3IsAdminForce2FA()
|
||||||
|
{
|
||||||
|
return $this->isAdmin() &&
|
||||||
|
Registry::getConfig()->getConfigParam('D3_TOTP_ADMIN_FORCE_2FA') == true;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
@ -40,8 +41,6 @@ use OxidEsales\Eshop\Application\Model as OxidModel;
|
||||||
*/
|
*/
|
||||||
$sMetadataVersion = '2.0';
|
$sMetadataVersion = '2.0';
|
||||||
|
|
||||||
$logo = (class_exists(d3utils::class) ? d3utils::getInstance()->getD3Logo() : 'D³');
|
|
||||||
|
|
||||||
$sModuleId = 'd3totp';
|
$sModuleId = 'd3totp';
|
||||||
/**
|
/**
|
||||||
* Module information
|
* Module information
|
||||||
|
@ -49,15 +48,19 @@ $sModuleId = 'd3totp';
|
||||||
$aModule = [
|
$aModule = [
|
||||||
'id' => $sModuleId,
|
'id' => $sModuleId,
|
||||||
'title' => [
|
'title' => [
|
||||||
'de' => $logo.' Zwei-Faktor-Authentisierung',
|
'de' =>
|
||||||
'en' => $logo.' two-factor authentication',
|
'<svg style="height:1em;width:1em"><image xlink:href="https://logos.oxidmodule.com/d3logo.svg" style="height:1em;width:1em" /></svg> '.
|
||||||
|
'Zwei-Faktor-Authentisierung',
|
||||||
|
'en' =>
|
||||||
|
'<svg style="height:1em;width:1em"><image xlink:href="https://logos.oxidmodule.com/d3logo.svg" style="height:1em;width:1em" /></svg> '.
|
||||||
|
'two-factor authentication',
|
||||||
],
|
],
|
||||||
'description' => [
|
'description' => [
|
||||||
'de' => 'Zwei-Faktor-Authentisierung (TOTP) für OXID eSales Shop',
|
'de' => 'Zwei-Faktor-Authentisierung (TOTP) für OXID eSales Shop',
|
||||||
'en' => 'Two-factor authentication (TOTP) for OXID eSales shop',
|
'en' => 'Two-factor authentication (TOTP) for OXID eSales shop',
|
||||||
],
|
],
|
||||||
'thumbnail' => 'picture.png',
|
'thumbnail' => 'picture.png',
|
||||||
'version' => '1.0.0.0',
|
'version' => '1.1.0.0',
|
||||||
'author' => 'D³ Data Development (Inh.: Thomas Dartsch)',
|
'author' => 'D³ Data Development (Inh.: Thomas Dartsch)',
|
||||||
'email' => 'support@shopmodule.com',
|
'email' => 'support@shopmodule.com',
|
||||||
'url' => 'http://www.oxidmodule.com/',
|
'url' => 'http://www.oxidmodule.com/',
|
||||||
|
@ -72,6 +75,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 +84,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 +106,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',
|
||||||
]
|
],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
namespace D3\Totp\tests\unit\Application\Model;
|
namespace D3\Totp\tests\unit\Application\Model;
|
||||||
|
|
||||||
use BaconQrCode\Renderer\Image\Svg;
|
|
||||||
use BaconQrCode\Writer;
|
use BaconQrCode\Writer;
|
||||||
|
use D3\Totp\Application\Factory\BaconQrCodeFactory;
|
||||||
use D3\Totp\Application\Model\d3backupcodelist;
|
use D3\Totp\Application\Model\d3backupcodelist;
|
||||||
use D3\Totp\Application\Model\d3totp;
|
use D3\Totp\Application\Model\d3totp;
|
||||||
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
|
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
|
||||||
|
@ -562,7 +562,7 @@ class d3totpTest extends d3TotpUnitTestCase
|
||||||
*/
|
*/
|
||||||
public function getQrCodeElement()
|
public function getQrCodeElement()
|
||||||
{
|
{
|
||||||
$renderer = oxNew(Svg::class);
|
$renderer = BaconQrCodeFactory::renderer(200);
|
||||||
|
|
||||||
/** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */
|
/** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */
|
||||||
$oTotpMock = $this->getMock(d3totp::class, array(
|
$oTotpMock = $this->getMock(d3totp::class, array(
|
||||||
|
@ -595,7 +595,7 @@ class d3totpTest extends d3TotpUnitTestCase
|
||||||
*/
|
*/
|
||||||
public function d3GetWriterReturnsRightInstance()
|
public function d3GetWriterReturnsRightInstance()
|
||||||
{
|
{
|
||||||
$renderer = oxNew(Svg::class);
|
$renderer = BaconQrCodeFactory::renderer(200);;
|
||||||
|
|
||||||
$this->assertInstanceOf(
|
$this->assertInstanceOf(
|
||||||
Writer::class,
|
Writer::class,
|
||||||
|
|
Loading…
Reference in New Issue