geforked van D3Public/oxtotp
Vergelijk commits
17 Commits
Auteur | SHA1 | Datum |
---|---|---|
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 |
Binair bestand niet weergegeven.
|
@ -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
|
100
composer.json
100
composer.json
|
@ -1,45 +1,55 @@
|
|||
{
|
||||
"name": "d3/oxtotp",
|
||||
"description": "Two-factor authentication via time-based one-time password for OXID eSales shop",
|
||||
"type": "oxideshop-module",
|
||||
"keywords": [
|
||||
"oxid",
|
||||
"modules",
|
||||
"eShop",
|
||||
"d3",
|
||||
"2FA"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "D3 Data Development (Inh. Thomas Dartsch)",
|
||||
"email": "info@shopmodule.com",
|
||||
"homepage": "http://www.d3data.de",
|
||||
"role": "Owner"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"email": "support@shopmodule.com"
|
||||
},
|
||||
"homepage": "https://www.oxidmodule.com/",
|
||||
"license": [
|
||||
"GPL-3.0-only"
|
||||
],
|
||||
"extra": {
|
||||
"oxideshop": {
|
||||
"source-directory": "/src",
|
||||
"target-directory": "d3/totp"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6",
|
||||
"oxid-esales/oxideshop-metapackage-ce": "~6.0.3 || ~6.1.0 || ~6.2.0",
|
||||
"spomky-labs/otphp": "^8.3",
|
||||
"bacon/bacon-qr-code": "^1.0",
|
||||
"zendframework/zend-math": "^3.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"D3\\Totp\\": "../../../source/modules/d3/totp"
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "d3/oxtotp",
|
||||
"description": "Two-factor authentication via time-based one-time password for OXID eSales shop",
|
||||
"type": "oxideshop-module",
|
||||
"keywords": [
|
||||
"oxid",
|
||||
"modules",
|
||||
"eShop",
|
||||
"d3",
|
||||
"2FA"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "D3 Data Development (Inh. Thomas Dartsch)",
|
||||
"email": "info@shopmodule.com",
|
||||
"homepage": "https://www.d3data.de",
|
||||
"role": "Owner"
|
||||
},
|
||||
{
|
||||
"name": "Tobi Matthaiou",
|
||||
"email": "tm@loberon.com",
|
||||
"homepage": "http://www.loberon.de",
|
||||
"role": "Contributor"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"email": "support@shopmodule.com"
|
||||
},
|
||||
"homepage": "https://www.oxidmodule.com/",
|
||||
"license": [
|
||||
"GPL-3.0-only"
|
||||
],
|
||||
"extra": {
|
||||
"oxideshop": {
|
||||
"source-directory": "/src",
|
||||
"target-directory": "d3/totp"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6",
|
||||
"ext-xmlwriter": "*",
|
||||
"oxid-esales/oxideshop-ce": "6.2.1 - 6.7",
|
||||
"spomky-labs/otphp": "^8.3",
|
||||
"bacon/bacon-qr-code": "^1.0 || ^2.0",
|
||||
"zendframework/zend-math": "^3.2"
|
||||
},
|
||||
"suggest": {
|
||||
"d3/modcfg": "Provides automatic installation routines"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"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.
|
||||
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.
|
||||
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
title: Changelog
|
||||
---
|
||||
|
||||
## 1.1.0.0 (2022-09-30)
|
||||
|
||||
###
|
||||
- optionale Verpflichtung zur 2FA-Nutzung für Adminbenutzer
|
||||
|
||||
## 1.0.0.0 (2019-08-19)
|
||||
|
||||
### Added
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"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",
|
||||
"author": "D³ Data Development",
|
||||
"moduledate": "19.08.2019",
|
||||
"moduledate": "30.09.2022",
|
||||
"editors": "DS",
|
||||
"tagline": "",
|
||||
"image": "",
|
||||
|
|
|
@ -5,7 +5,7 @@ title: Schnellstart per Composer
|
|||
## Schnellstart per Composer
|
||||
|
||||
```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.
|
|
@ -1,27 +1,27 @@
|
|||
CREATE TABLE IF NOT EXISTS `d3totp` (
|
||||
`OXID` CHAR(32) NOT NULL ,
|
||||
`OXUSERID` CHAR(32) NOT NULL ,
|
||||
`USETOTP` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`SEED` VARCHAR(256) NOT NULL ,
|
||||
`OXTIMESTAMP` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Timestamp',
|
||||
PRIMARY KEY (`OXID`) ,
|
||||
UNIQUE KEY `OXUSERID` (`OXUSERID`)
|
||||
)
|
||||
ENGINE=InnoDB
|
||||
COMMENT='totp setting';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `d3totp_backupcodes` (
|
||||
`OXID` CHAR(32) NOT NULL ,
|
||||
`OXUSERID` CHAR(32) NOT NULL COMMENT 'user id',
|
||||
`BACKUPCODE` VARCHAR(64) NOT NULL COMMENT 'BackupCode',
|
||||
`OXTIMESTAMP` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Timestamp',
|
||||
PRIMARY KEY (`OXID`) ,
|
||||
KEY `OXUSERID` (`OXUSERID`) ,
|
||||
KEY `BACKUPCODE` (`BACKUPCODE`)
|
||||
)
|
||||
ENGINE=InnoDB
|
||||
COMMENT='totp backup codes';
|
||||
|
||||
INSERT INTO `oxseo` (`OXOBJECTID`, `OXIDENT`, `OXSHOPID`, `OXLANG`, `OXSTDURL`, `OXSEOURL`, `OXTYPE`, `OXFIXED`, `OXEXPIRED`, `OXPARAMS`, `OXTIMESTAMP`) VALUES
|
||||
('39f744f17e974988e515558698a29df4', '76282e134ad4e40a3578e121a6cb1f6a', 1, 1, 'index.php?cl=d3_account_totp', 'en/2-factor-authintication/', 'static', 0, 0, '', NOW()),
|
||||
('39f744f17e974988e515558698a29df4', 'c1f8b5506e2b5d6ac184dcc5ebdfb591', 1, 0, 'index.php?cl=d3_account_totp', '2-faktor-authentisierung/', 'static', 0, 0, '', NOW());
|
||||
CREATE TABLE IF NOT EXISTS `d3totp` (
|
||||
`OXID` CHAR(32) NOT NULL ,
|
||||
`OXUSERID` CHAR(32) NOT NULL ,
|
||||
`USETOTP` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`SEED` VARCHAR(256) NOT NULL ,
|
||||
`OXTIMESTAMP` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Timestamp',
|
||||
PRIMARY KEY (`OXID`) ,
|
||||
UNIQUE KEY `OXUSERID` (`OXUSERID`)
|
||||
)
|
||||
ENGINE=InnoDB
|
||||
COMMENT='totp setting';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `d3totp_backupcodes` (
|
||||
`OXID` CHAR(32) NOT NULL ,
|
||||
`OXUSERID` CHAR(32) NOT NULL COMMENT 'user id',
|
||||
`BACKUPCODE` VARCHAR(64) NOT NULL COMMENT 'BackupCode',
|
||||
`OXTIMESTAMP` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Timestamp',
|
||||
PRIMARY KEY (`OXID`) ,
|
||||
KEY `OXUSERID` (`OXUSERID`) ,
|
||||
KEY `BACKUPCODE` (`BACKUPCODE`)
|
||||
)
|
||||
ENGINE=InnoDB
|
||||
COMMENT='totp backup codes';
|
||||
|
||||
INSERT INTO `oxseo` (`OXOBJECTID`, `OXIDENT`, `OXSHOPID`, `OXLANG`, `OXSTDURL`, `OXSEOURL`, `OXTYPE`, `OXFIXED`, `OXEXPIRED`, `OXPARAMS`, `OXTIMESTAMP`) VALUES
|
||||
('39f744f17e974988e515558698a29df4', '76282e134ad4e40a3578e121a6cb1f6a', 1, 1, 'index.php?cl=d3_account_totp', 'en/2-factor-authintication/', 'static', 0, 0, '', NOW()),
|
||||
('39f744f17e974988e515558698a29df4', 'c1f8b5506e2b5d6ac184dcc5ebdfb591', 1, 0, 'index.php?cl=d3_account_totp', '2-faktor-authentisierung/', 'static', 0, 0, '', NOW());
|
||||
|
|
|
@ -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;
|
||||
|
||||
use BaconQrCode\Renderer\Image\Svg;
|
||||
use BaconQrCode\Renderer\RendererInterface;
|
||||
use BaconQrCode\Writer;
|
||||
use D3\Totp\Application\Factory\BaconQrCodeFactory;
|
||||
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use OTPHP\TOTP;
|
||||
|
@ -177,10 +177,7 @@ class d3totp extends BaseModel
|
|||
*/
|
||||
public function getQrCodeElement()
|
||||
{
|
||||
$renderer = oxNew(Svg::class);
|
||||
$renderer->setHeight(200);
|
||||
$renderer->setWidth(200);
|
||||
|
||||
$renderer = BaconQrCodeFactory::renderer(200);
|
||||
$writer = $this->d3GetWriter($renderer);
|
||||
return $writer->writeString($this->getTotp()->getProvisioningUri());
|
||||
}
|
||||
|
|
|
@ -34,6 +34,11 @@ $aLang = [
|
|||
'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_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_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.',
|
||||
|
@ -48,4 +53,6 @@ $aLang = [
|
|||
|
||||
'D3_TOTP_ERROR_UNVALID' => 'Das Einmalpasswort ist ungültig.',
|
||||
'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_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_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.',
|
||||
|
@ -48,4 +53,6 @@ $aLang = [
|
|||
|
||||
'D3_TOTP_ERROR_UNVALID' => 'The one-time password is invalid.',
|
||||
'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 {
|
||||
white-space: normal;
|
||||
}
|
||||
.hero {
|
||||
display: inline-block;
|
||||
}
|
||||
.hero > h1 {
|
||||
padding: 0.3em 0;
|
||||
}
|
||||
.hero > div {
|
||||
text-align: right;
|
||||
color: #6c7c98;
|
||||
}
|
||||
</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">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
<input type="hidden" name="oxid" value="[{$oxid}]">
|
||||
|
@ -60,6 +77,22 @@
|
|||
[{oxinputhelp ident="D3_TOTP_QRCODE_HELP"}]
|
||||
</td>
|
||||
</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}]
|
||||
<tr>
|
||||
<td class="edittext" colspan="2">
|
||||
|
@ -153,5 +186,7 @@
|
|||
[{/if}]
|
||||
</form>
|
||||
|
||||
[{include file="bottomnaviitem.tpl"}]
|
||||
[{include file="bottomitem.tpl"}]
|
||||
[{if !$force2FA}]
|
||||
[{include file="bottomnaviitem.tpl"}]
|
||||
[{include file="bottomitem.tpl"}]
|
||||
[{/if}]
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This Software is the property of Data Development and is protected
|
||||
* by copyright law - it is NOT Freeware.
|
||||
* Any unauthorized use of this software without a valid license
|
||||
* is a violation of the license agreement and will be prosecuted by
|
||||
* civil and criminal law.
|
||||
* http://www.shopmodule.com
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
|
||||
* @link http://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
namespace D3\Totp\Modules\Application\Component
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Application\Component\UserComponent;
|
||||
|
||||
class d3_totp_UserComponent_parent extends UserComponent { }
|
||||
}
|
||||
|
||||
namespace D3\Totp\Modules\Application\Controller
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Application\Controller\OrderController;
|
||||
use OxidEsales\Eshop\Application\Controller\PaymentController;
|
||||
use OxidEsales\Eshop\Application\Controller\UserController;
|
||||
|
||||
class d3_totp_UserController_parent extends UserController { }
|
||||
|
||||
class d3_totp_PaymentController_parent extends PaymentController { }
|
||||
|
||||
class d3_totp_OrderController_parent extends OrderController { }
|
||||
}
|
||||
|
||||
namespace D3\Totp\Modules\Application\Controller\Admin
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Application\Controller\Admin\LoginController;
|
||||
|
||||
class d3_totp_LoginController_parent extends LoginController { }
|
||||
}
|
||||
|
||||
namespace D3\Totp\Modules\Application\Model
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Application\Model\User;
|
||||
|
||||
class d3_totp_user_parent extends User { }
|
||||
}
|
||||
|
||||
namespace D3\Totp\Modules\Core
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Core\Utils;
|
||||
|
||||
class d3_totp_utils_parent extends Utils { }
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This Software is the property of Data Development and is protected
|
||||
* by copyright law - it is NOT Freeware.
|
||||
* Any unauthorized use of this software without a valid license
|
||||
* is a violation of the license agreement and will be prosecuted by
|
||||
* civil and criminal law.
|
||||
* http://www.shopmodule.com
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
|
||||
* @link http://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
namespace D3\Totp\Modules\Application\Component
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Application\Component\UserComponent;
|
||||
|
||||
class d3_totp_UserComponent_parent extends UserComponent { }
|
||||
}
|
||||
|
||||
namespace D3\Totp\Modules\Application\Controller
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Application\Controller\OrderController;
|
||||
use OxidEsales\Eshop\Application\Controller\PaymentController;
|
||||
use OxidEsales\Eshop\Application\Controller\UserController;
|
||||
|
||||
class d3_totp_UserController_parent extends UserController { }
|
||||
|
||||
class d3_totp_PaymentController_parent extends PaymentController { }
|
||||
|
||||
class d3_totp_OrderController_parent extends OrderController { }
|
||||
}
|
||||
|
||||
namespace D3\Totp\Modules\Application\Controller\Admin
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Application\Controller\Admin\LoginController;
|
||||
|
||||
class d3_totp_LoginController_parent extends LoginController { }
|
||||
}
|
||||
|
||||
namespace D3\Totp\Modules\Application\Model
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Application\Model\User;
|
||||
|
||||
class d3_totp_user_parent extends User { }
|
||||
}
|
||||
|
||||
namespace D3\Totp\Modules\Core
|
||||
{
|
||||
|
||||
use OxidEsales\Eshop\Core\Utils;
|
||||
|
||||
class d3_totp_utils_parent extends Utils { }
|
||||
}
|
|
@ -1,68 +1,93 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This Software is the property of Data Development and is protected
|
||||
* by copyright law - it is NOT Freeware.
|
||||
* Any unauthorized use of this software without a valid license
|
||||
* is a violation of the license agreement and will be prosecuted by
|
||||
* civil and criminal law.
|
||||
* http://www.shopmodule.com
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
|
||||
* @link http://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
namespace D3\Totp\Modules\Core;
|
||||
|
||||
use D3\Totp\Application\Model\d3totp;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidEsales\Eshop\Core\Session;
|
||||
|
||||
class d3_totp_utils extends d3_totp_utils_parent
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
*/
|
||||
public function checkAccessRights()
|
||||
{
|
||||
$blAuth = parent::checkAccessRights();
|
||||
|
||||
$userID = $this->d3GetSessionObject()->getVariable("auth");
|
||||
$totpAuth = (bool) $this->d3GetSessionObject()->getVariable(d3totp::TOTP_SESSION_VARNAME);
|
||||
/** @var d3totp $totp */
|
||||
$totp = $this->d3GetTotpObject();
|
||||
$totp->loadByUserId($userID);
|
||||
|
||||
if ($blAuth && $totp->isActive() && false === $totpAuth) {
|
||||
$this->redirect('index.php?cl=login', true, 302);
|
||||
if (false == defined('OXID_PHP_UNIT')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
exit;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
return $blAuth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Session
|
||||
*/
|
||||
public function d3GetSessionObject()
|
||||
{
|
||||
return Registry::getSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return d3totp
|
||||
*/
|
||||
public function d3GetTotpObject()
|
||||
{
|
||||
return oxNew(d3totp::class);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This Software is the property of Data Development and is protected
|
||||
* by copyright law - it is NOT Freeware.
|
||||
* Any unauthorized use of this software without a valid license
|
||||
* is a violation of the license agreement and will be prosecuted by
|
||||
* civil and criminal law.
|
||||
* http://www.shopmodule.com
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
|
||||
* @link http://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
namespace D3\Totp\Modules\Core;
|
||||
|
||||
use D3\Totp\Application\Model\d3totp;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidEsales\Eshop\Core\Session;
|
||||
|
||||
class d3_totp_utils extends d3_totp_utils_parent
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
*/
|
||||
public function checkAccessRights()
|
||||
{
|
||||
$blAuth = parent::checkAccessRights();
|
||||
|
||||
$userID = $this->d3GetSessionObject()->getVariable("auth");
|
||||
$totpAuth = (bool) $this->d3GetSessionObject()->getVariable(d3totp::TOTP_SESSION_VARNAME);
|
||||
/** @var d3totp $totp */
|
||||
$totp = $this->d3GetTotpObject();
|
||||
$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) {
|
||||
$this->redirect('index.php?cl=login', true, 302);
|
||||
if (false == defined('OXID_PHP_UNIT')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
exit;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
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\d3totplogin;
|
||||
use D3\Totp\Modules\Application\Component\d3_totp_UserComponent;
|
||||
|
@ -40,8 +41,6 @@ use OxidEsales\Eshop\Application\Model as OxidModel;
|
|||
*/
|
||||
$sMetadataVersion = '2.0';
|
||||
|
||||
$logo = (class_exists(d3utils::class) ? d3utils::getInstance()->getD3Logo() : 'D³');
|
||||
|
||||
$sModuleId = 'd3totp';
|
||||
/**
|
||||
* Module information
|
||||
|
@ -49,15 +48,19 @@ $sModuleId = 'd3totp';
|
|||
$aModule = [
|
||||
'id' => $sModuleId,
|
||||
'title' => [
|
||||
'de' => $logo.' Zwei-Faktor-Authentisierung',
|
||||
'en' => $logo.' two-factor authentication',
|
||||
'de' =>
|
||||
'<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' => [
|
||||
'de' => 'Zwei-Faktor-Authentisierung (TOTP) für OXID eSales Shop',
|
||||
'en' => 'Two-factor authentication (TOTP) for OXID eSales shop',
|
||||
],
|
||||
'thumbnail' => 'picture.png',
|
||||
'version' => '1.0.0.0',
|
||||
'version' => '1.1.0.0',
|
||||
'author' => 'D³ Data Development (Inh.: Thomas Dartsch)',
|
||||
'email' => 'support@shopmodule.com',
|
||||
'url' => 'http://www.oxidmodule.com/',
|
||||
|
@ -72,6 +75,7 @@ $aModule = [
|
|||
],
|
||||
'controllers' => [
|
||||
'd3user_totp' => d3user_totp::class,
|
||||
'd3force_2fa' => d3force_2fa::class,
|
||||
'd3totplogin' => d3totplogin::class,
|
||||
'd3_account_totp' => d3_account_totp::class,
|
||||
],
|
||||
|
@ -80,6 +84,14 @@ $aModule = [
|
|||
'd3totplogin.tpl' => 'd3/totp/Application/views/tpl/d3totplogin.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' => [
|
||||
'onActivate' => '\D3\Totp\Setup\Events::onActivate',
|
||||
'onDeactivate' => '\D3\Totp\Setup\Events::onDeactivate',
|
||||
|
@ -94,6 +106,6 @@ $aModule = [
|
|||
'template' => 'page/account/inc/account_menu.tpl',
|
||||
'block' => 'account_menu',
|
||||
'file' => 'Application/views/blocks/page/account/inc/account_menu.tpl',
|
||||
]
|
||||
],
|
||||
]
|
||||
];
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
namespace D3\Totp\tests\unit\Application\Model;
|
||||
|
||||
use BaconQrCode\Renderer\Image\Svg;
|
||||
use BaconQrCode\Writer;
|
||||
use D3\Totp\Application\Factory\BaconQrCodeFactory;
|
||||
use D3\Totp\Application\Model\d3backupcodelist;
|
||||
use D3\Totp\Application\Model\d3totp;
|
||||
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
|
||||
|
@ -484,7 +484,7 @@ class d3totpTest extends d3TotpUnitTestCase
|
|||
'getFieldData',
|
||||
));
|
||||
$oUserMock->method('getFieldData')->willReturn('username');
|
||||
|
||||
|
||||
/** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(d3totp::class, array(
|
||||
'getUser',
|
||||
|
@ -544,7 +544,7 @@ class d3totpTest extends d3TotpUnitTestCase
|
|||
'getQrCodeUri'
|
||||
));
|
||||
$oTotpMock->expects($this->once())->method('getQrCodeUri')->willReturn(true);
|
||||
|
||||
|
||||
/** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(d3totp::class, array(
|
||||
'getTotp'
|
||||
|
@ -562,7 +562,7 @@ class d3totpTest extends d3TotpUnitTestCase
|
|||
*/
|
||||
public function getQrCodeElement()
|
||||
{
|
||||
$renderer = oxNew(Svg::class);
|
||||
$renderer = BaconQrCodeFactory::renderer(200);
|
||||
|
||||
/** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */
|
||||
$oTotpMock = $this->getMock(d3totp::class, array(
|
||||
|
@ -595,14 +595,14 @@ class d3totpTest extends d3TotpUnitTestCase
|
|||
*/
|
||||
public function d3GetWriterReturnsRightInstance()
|
||||
{
|
||||
$renderer = oxNew(Svg::class);
|
||||
$renderer = BaconQrCodeFactory::renderer(200);;
|
||||
|
||||
$this->assertInstanceOf(
|
||||
Writer::class,
|
||||
$this->callMethod($this->_oModel, 'd3GetWriter', [$renderer])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
|
@ -878,4 +878,4 @@ class d3totpTest extends d3TotpUnitTestCase
|
|||
$this->callMethod($this->_oModel, 'delete')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Laden…
Verwijs in nieuw issue