forked from D3Public/oxtotp
Merge pull request #1 from tmloberon/tmloberon-new-bacon-version
Update composer
This commit is contained in:
commit
f0a3124303
10
README.md
Normal file
10
README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# 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
|
@ -1,45 +1,52 @@
|
|||||||
{
|
{
|
||||||
"name": "d3/oxtotp",
|
"name": "d3/oxtotp",
|
||||||
"description": "Two-factor authentication via time-based one-time password for OXID eSales shop",
|
"description": "Two-factor authentication via time-based one-time password for OXID eSales shop",
|
||||||
"type": "oxideshop-module",
|
"type": "oxideshop-module",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"oxid",
|
"oxid",
|
||||||
"modules",
|
"modules",
|
||||||
"eShop",
|
"eShop",
|
||||||
"d3",
|
"d3",
|
||||||
"2FA"
|
"2FA"
|
||||||
],
|
],
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"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": "http://www.d3data.de",
|
||||||
"role": "Owner"
|
"role": "Owner"
|
||||||
}
|
},
|
||||||
],
|
{
|
||||||
"support": {
|
"name": "Tobi Matthaiou",
|
||||||
"email": "support@shopmodule.com"
|
"email": "tm@loberon.com",
|
||||||
},
|
"homepage": "http://www.loberon.de",
|
||||||
"homepage": "https://www.oxidmodule.com/",
|
"role": "Contributor"
|
||||||
"license": [
|
}
|
||||||
"GPL-3.0-only"
|
],
|
||||||
],
|
"support": {
|
||||||
"extra": {
|
"email": "support@shopmodule.com"
|
||||||
"oxideshop": {
|
},
|
||||||
"source-directory": "/src",
|
"homepage": "https://www.oxidmodule.com/",
|
||||||
"target-directory": "d3/totp"
|
"license": [
|
||||||
}
|
"GPL-3.0-only"
|
||||||
},
|
],
|
||||||
"require": {
|
"extra": {
|
||||||
"php": ">=5.6",
|
"oxideshop": {
|
||||||
"oxid-esales/oxideshop-metapackage-ce": "~6.0.3 || ~6.1.0 || ~6.2.0",
|
"source-directory": "/src",
|
||||||
"spomky-labs/otphp": "^8.3",
|
"target-directory": "d3/totp"
|
||||||
"bacon/bacon-qr-code": "^1.0",
|
}
|
||||||
"zendframework/zend-math": "^3.2"
|
},
|
||||||
},
|
"require": {
|
||||||
"autoload": {
|
"php": ">=5.6",
|
||||||
"psr-4": {
|
"ext-xmlwriter": "*",
|
||||||
"D3\\Totp\\": "../../../source/modules/d3/totp"
|
"oxid-esales/oxideshop-metapackage-ce": "~6.0.3 || ~6.1.0 || ~6.2.0 || ~6.3.0 || ~6.4.0 || ~6.5.0",
|
||||||
}
|
"spomky-labs/otphp": "^8.3",
|
||||||
}
|
"bacon/bacon-qr-code": "^1.0 || ^2.0",
|
||||||
}
|
"zendframework/zend-math": "^3.2"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"D3\\Totp\\": "../../../source/modules/d3/totp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
47
src/Application/Factory/BaconQrCodeFactory.php
Normal file
47
src/Application/Factory/BaconQrCodeFactory.php
Normal file
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
@ -484,7 +484,7 @@ class d3totpTest extends d3TotpUnitTestCase
|
|||||||
'getFieldData',
|
'getFieldData',
|
||||||
));
|
));
|
||||||
$oUserMock->method('getFieldData')->willReturn('username');
|
$oUserMock->method('getFieldData')->willReturn('username');
|
||||||
|
|
||||||
/** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
/** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||||
$oModelMock = $this->getMock(d3totp::class, array(
|
$oModelMock = $this->getMock(d3totp::class, array(
|
||||||
'getUser',
|
'getUser',
|
||||||
@ -544,7 +544,7 @@ class d3totpTest extends d3TotpUnitTestCase
|
|||||||
'getQrCodeUri'
|
'getQrCodeUri'
|
||||||
));
|
));
|
||||||
$oTotpMock->expects($this->once())->method('getQrCodeUri')->willReturn(true);
|
$oTotpMock->expects($this->once())->method('getQrCodeUri')->willReturn(true);
|
||||||
|
|
||||||
/** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
/** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||||
$oModelMock = $this->getMock(d3totp::class, array(
|
$oModelMock = $this->getMock(d3totp::class, array(
|
||||||
'getTotp'
|
'getTotp'
|
||||||
@ -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,14 +595,14 @@ 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,
|
||||||
$this->callMethod($this->_oModel, 'd3GetWriter', [$renderer])
|
$this->callMethod($this->_oModel, 'd3GetWriter', [$renderer])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @throws ReflectionException
|
* @throws ReflectionException
|
||||||
@ -878,4 +878,4 @@ class d3totpTest extends d3TotpUnitTestCase
|
|||||||
$this->callMethod($this->_oModel, 'delete')
|
$this->callMethod($this->_oModel, 'delete')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user