bifurqué depuis D3Public/oxtotp
add missing tests
Cette révision appartient à :
Parent
de75b77562
révision
f0275c1bc9
@ -18,7 +18,6 @@ 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\Core\Exception\DatabaseConnectionException;
|
||||
|
@ -9,7 +9,6 @@ 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
|
||||
{
|
||||
/**
|
||||
|
@ -236,8 +236,8 @@ class d3totp extends BaseModel
|
||||
$key = Registry::getConfig()->getConfigParam('sConfigKey');
|
||||
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
|
||||
$iv = openssl_random_pseudo_bytes($ivlen);
|
||||
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
|
||||
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
|
||||
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
|
||||
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, true);
|
||||
return base64_encode($iv.$hmac.$ciphertext_raw);
|
||||
}
|
||||
|
||||
@ -253,8 +253,8 @@ class d3totp extends BaseModel
|
||||
$iv = substr($c, 0, $ivlen);
|
||||
$hmac = substr($c, $ivlen, $sha2len=32);
|
||||
$ciphertext_raw = substr($c, $ivlen+$sha2len);
|
||||
$original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
|
||||
$calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
|
||||
$original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, OPENSSL_RAW_DATA, $iv);
|
||||
$calcmac = hash_hmac('sha256', $ciphertext_raw, $key, true);
|
||||
if (hash_equals($hmac, $calcmac)) { // PHP 5.6+ compute attack-safe comparison
|
||||
return $original_plaintext;
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ declare(strict_types=1);
|
||||
namespace D3\Totp\Modules\Application\Controller;
|
||||
|
||||
use D3\Totp\Application\Model\d3totp;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use OxidEsales\Eshop\Application\Model\User;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
@ -17,6 +17,7 @@ namespace D3\Totp\Modules\Core;
|
||||
|
||||
use D3\Totp\Application\Model\d3totp;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use OxidEsales\Eshop\Core\Config;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidEsales\Eshop\Core\Session;
|
||||
@ -32,14 +33,14 @@ class d3_totp_utils extends d3_totp_utils_parent
|
||||
{
|
||||
$blAuth = parent::checkAccessRights();
|
||||
|
||||
$blAuth = $this->d3AuthHook($blAuth);
|
||||
$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
|
||||
//check forced 2FA for all admin users
|
||||
if (
|
||||
$this->d3IsAdminForce2FA()
|
||||
&& $blAuth
|
||||
@ -82,12 +83,29 @@ class d3_totp_utils extends d3_totp_utils_parent
|
||||
return oxNew(d3totp::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Config
|
||||
*/
|
||||
public function d3GetConfig(): Config
|
||||
{
|
||||
return Registry::getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function d3IsAdminForce2FA()
|
||||
protected function d3IsAdminForce2FA()
|
||||
{
|
||||
return $this->isAdmin() &&
|
||||
Registry::getConfig()->getConfigParam('D3_TOTP_ADMIN_FORCE_2FA') == true;
|
||||
$this->d3GetConfig()->getConfigParam('D3_TOTP_ADMIN_FORCE_2FA') === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $blAuth
|
||||
* @return bool
|
||||
*/
|
||||
protected function d3AuthHook(bool $blAuth): bool
|
||||
{
|
||||
return $blAuth;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace D3\Totp\Setup;
|
||||
use OxidEsales\Eshop\Core\DatabaseProvider;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
class Events
|
||||
{
|
||||
/**
|
||||
@ -130,4 +130,5 @@ class Events
|
||||
DatabaseProvider::getDb()->execute( $query );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
@ -1,286 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
namespace D3\Totp\Setup;
|
||||
|
||||
use D3\ModCfg\Application\Model\d3database;
|
||||
use D3\ModCfg\Application\Model\Install\d3install_updatebase;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use OxidEsales\Eshop\Core\Database\Adapter\DatabaseInterface;
|
||||
use OxidEsales\Eshop\Core\DatabaseProvider;
|
||||
use OxidEsales\Eshop\Core\Exception\ConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
|
||||
|
||||
class Installation extends d3install_updatebase
|
||||
{
|
||||
protected $_aUpdateMethods = array(
|
||||
array('check' => 'doesTotpTableNotExist',
|
||||
'do' => 'addTotpTable'),
|
||||
array('check' => 'doesTotpBCTableNotExist',
|
||||
'do' => 'addTotpBCTable'),
|
||||
array('check' => 'checkFields',
|
||||
'do' => 'fixFields'),
|
||||
array('check' => 'checkIndizes',
|
||||
'do' => 'fixIndizes'),
|
||||
array('check' => 'checkSEONotExists',
|
||||
'do' => 'addSEO'),
|
||||
);
|
||||
|
||||
public $aMultiLangTables = array();
|
||||
|
||||
public $aFields = array(
|
||||
'OXID' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'OXID',
|
||||
'sType' => 'CHAR(32)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => '',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'OXUSERID' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'OXUSERID',
|
||||
'sType' => 'CHAR(32)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => '',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'USETOTP' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'USETOTP',
|
||||
'sType' => 'TINYINT(1)',
|
||||
'blNull' => false,
|
||||
'sDefault' => 0,
|
||||
'sComment' => '',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'SEED' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'SEED',
|
||||
'sType' => 'VARCHAR(256)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => '',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'OXTIMESTAMP' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'OXTIMESTAMP',
|
||||
'sType' => 'TIMESTAMP',
|
||||
'blNull' => false,
|
||||
'sDefault' => 'CURRENT_TIMESTAMP',
|
||||
'sComment' => 'Timestamp',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
|
||||
'bc_OXID' => array(
|
||||
'sTableName' => 'd3totp_backupcodes',
|
||||
'sFieldName' => 'OXID',
|
||||
'sType' => 'CHAR(32)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => '',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'bc_OXUSERID' => array(
|
||||
'sTableName' => 'd3totp_backupcodes',
|
||||
'sFieldName' => 'OXUSERID',
|
||||
'sType' => 'CHAR(32)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'user id',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'bc_BACKUPCODE' => array(
|
||||
'sTableName' => 'd3totp_backupcodes',
|
||||
'sFieldName' => 'BACKUPCODE',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'bc_OXTIMESTAMP' => array(
|
||||
'sTableName' => 'd3totp_backupcodes',
|
||||
'sFieldName' => 'OXTIMESTAMP',
|
||||
'sType' => 'TIMESTAMP',
|
||||
'blNull' => false,
|
||||
'sDefault' => 'CURRENT_TIMESTAMP',
|
||||
'sComment' => 'Timestamp',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
)
|
||||
);
|
||||
|
||||
public $aIndizes = array(
|
||||
'OXID' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sType' => d3database::INDEX_TYPE_PRIMARY,
|
||||
'sName' => 'PRIMARY',
|
||||
'aFields' => array(
|
||||
'OXID' => 'OXID',
|
||||
),
|
||||
),
|
||||
'OXUSERID' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sType' => d3database::INDEX_TYPE_UNIQUE,
|
||||
'sName' => 'OXUSERID',
|
||||
'aFields' => array(
|
||||
'OXUSERID' => 'OXUSERID',
|
||||
),
|
||||
),
|
||||
'bc_OXID' => array(
|
||||
'sTableName' => 'd3totp_backupcodes',
|
||||
'sType' => d3database::INDEX_TYPE_PRIMARY,
|
||||
'sName' => 'PRIMARY',
|
||||
'aFields' => array(
|
||||
'OXID' => 'OXID',
|
||||
),
|
||||
),
|
||||
'bc_OXUSERID' => array(
|
||||
'sTableName' => 'd3totp_backupcodes',
|
||||
'sType' => d3database::INDEX_TYPE_INDEX,
|
||||
'sName' => 'OXUSERID',
|
||||
'aFields' => array(
|
||||
'OXUSERID' => 'OXUSERID',
|
||||
),
|
||||
),
|
||||
'bc_BACKUPCODE' => array(
|
||||
'sTableName' => 'd3totp_backupcodes',
|
||||
'sType' => d3database::INDEX_TYPE_INDEX,
|
||||
'sName' => 'BACKUPCODE',
|
||||
'aFields' => array(
|
||||
'BACKUPCODE' => 'BACKUPCODE',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
protected $_aRefreshMetaModuleIds = array('d3totp');
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function doesTotpTableNotExist()
|
||||
{
|
||||
return $this->_checkTableNotExist('d3totp');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws ConnectionException
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function addTotpTable()
|
||||
{
|
||||
$blRet = false;
|
||||
if ($this->doesTotpTableNotExist()) {
|
||||
$this->setInitialExecMethod(__METHOD__);
|
||||
$blRet = $this->_addTable2(
|
||||
'd3totp',
|
||||
$this->aFields,
|
||||
$this->aIndizes,
|
||||
'totp setting',
|
||||
'InnoDB'
|
||||
);
|
||||
}
|
||||
|
||||
return $blRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function doesTotpBCTableNotExist()
|
||||
{
|
||||
return $this->_checkTableNotExist('d3totp_backupcodes');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws ConnectionException
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function addTotpBCTable()
|
||||
{
|
||||
$blRet = false;
|
||||
if ($this->doesTotpBCTableNotExist()) {
|
||||
$this->setInitialExecMethod(__METHOD__);
|
||||
$blRet = $this->_addTable2(
|
||||
'd3totp_backupcodes',
|
||||
$this->aFields,
|
||||
$this->aIndizes,
|
||||
'totp backup codes',
|
||||
'InnoDB'
|
||||
);
|
||||
}
|
||||
|
||||
return $blRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws DatabaseConnectionException
|
||||
*/
|
||||
public function checkSEONotExists()
|
||||
{
|
||||
$query = "SELECT 1 FROM " . getViewName('oxseo') . " WHERE oxstdurl = 'index.php?cl=d3_account_totp'";
|
||||
|
||||
return !$this->d3GetDb()->getOne($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DatabaseInterface
|
||||
* @throws DatabaseConnectionException
|
||||
*/
|
||||
public function d3GetDb()
|
||||
{
|
||||
return DatabaseProvider::getDb();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function addSEO()
|
||||
{
|
||||
$query = [
|
||||
"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());"
|
||||
];
|
||||
|
||||
return $this->_executeMultipleQueries($query);
|
||||
}
|
||||
}
|
107
src/tests/unit/Application/Controller/Admin/d3force_2faTest.php
Fichier normal
107
src/tests/unit/Application/Controller/Admin/d3force_2faTest.php
Fichier normal
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace D3\Totp\tests\unit\Application\Controller\Admin;
|
||||
|
||||
use D3\Totp\Application\Controller\Admin\d3force_2fa;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidEsales\Eshop\Core\Session;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class d3force_2faTest extends d3user_totpTest
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oController = oxNew(d3force_2fa::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Application\Controller\Admin\d3force_2fa::render
|
||||
*/
|
||||
public function testRender()
|
||||
{
|
||||
$expected = 'fixture';
|
||||
|
||||
Registry::getSession()->setVariable('auth', $expected);
|
||||
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'render'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$this->_oController->getViewDataElement('force2FA')
|
||||
);
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->getValue(
|
||||
$this->_oController,
|
||||
'_sEditObjectId'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Application\Controller\Admin\d3force_2fa::_authorize
|
||||
* @covers \D3\Totp\Application\Controller\Admin\d3force_2fa::d3IsAdminForce2FA
|
||||
* @dataProvider authorizeDataProvider
|
||||
*/
|
||||
public function testAuthorize($expected, $isAdmin, $force2FA, $givenUserId)
|
||||
{
|
||||
/** @var d3force_2fa|MockObject $oController */
|
||||
$oController = $this->getMockBuilder(d3force_2fa::class)
|
||||
->onlyMethods(['isAdmin'])
|
||||
->getMock();
|
||||
$oController->expects($this->once())->method('isAdmin')->willReturn($isAdmin);
|
||||
|
||||
Registry::getConfig()->setConfigParam('D3_TOTP_ADMIN_FORCE_2FA', $force2FA);
|
||||
|
||||
Registry::getSession()->setVariable('auth', $givenUserId);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$oController,
|
||||
'_authorize'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function authorizeDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'noAdmin' => [false, false, true, 'userId'],
|
||||
'dont force' => [false, true, false, 'userId'],
|
||||
'no user id' => [false, true, true, null],
|
||||
'passed' => [true, true, true, 'userId']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Application\Controller\Admin\d3force_2fa::d3GetSessionObject
|
||||
*/
|
||||
public function testD3GetSessionObject()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
Session::class,
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'd3GetSessionObject'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -423,6 +423,7 @@ class d3user_totpTest extends d3TotpUnitTestCase
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Application\Controller\Admin\d3user_totp::setBackupCodes
|
||||
* @covers \D3\Totp\Application\Controller\Admin\d3user_totp::getBackupCodes
|
||||
*/
|
||||
public function canSetAndGetBackupCodes()
|
||||
|
@ -104,6 +104,7 @@ class d3_account_totpTest extends d3TotpUnitTestCase
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Application\Controller\d3_account_totp::getBackupCodes
|
||||
* @covers \D3\Totp\Application\Controller\d3_account_totp::setBackupCodes
|
||||
*/
|
||||
public function canSetAndGetBackupCodes()
|
||||
{
|
||||
|
@ -234,7 +234,7 @@ class d3totploginTest extends d3TotpUnitTestCase
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Application\Controller\d3totplogin::previousClassIsOrderStep
|
||||
* @covers \D3\Totp\Application\Controller\d3totplogin::getIsOrderStep
|
||||
* @dataProvider classIsOrderStepDataProvider
|
||||
*/
|
||||
public function getIsOrderStepIsSameLikeOrderClass($className, $expected)
|
||||
|
44
src/tests/unit/Application/Factory/BaconQrCodeFactoryTest.php
Fichier normal
44
src/tests/unit/Application/Factory/BaconQrCodeFactoryTest.php
Fichier normal
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace D3\Totp\tests\unit\Application\Factory;
|
||||
|
||||
use BaconQrCode\Renderer\ImageRenderer;
|
||||
use D3\Totp\Application\Factory\BaconQrCodeFactory;
|
||||
use D3\Totp\tests\unit\d3TotpUnitTestCase;
|
||||
|
||||
class BaconQrCodeFactoryTest extends d3TotpUnitTestCase
|
||||
{
|
||||
/** @var BaconQrCodeFactory */
|
||||
protected $factory;
|
||||
|
||||
/**
|
||||
* setup basic requirements
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->factory = oxNew(BaconQrCodeFactory::class);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
unset($this->factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @covers \D3\Totp\Application\Factory\BaconQrCodeFactory::renderer
|
||||
* @covers \D3\Totp\Application\Factory\BaconQrCodeFactory::v200
|
||||
*/
|
||||
public function testRenderer()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
ImageRenderer::class,
|
||||
BaconQrCodeFactory::renderer(200)
|
||||
);
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ class d3totp_wrongOtpExceptionTest extends d3TotpUnitTestCase
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException::getMessage
|
||||
* @covers \D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException::__construct
|
||||
*/
|
||||
public function constructorHasRightDefaultMessage()
|
||||
{
|
||||
|
@ -587,7 +587,7 @@ class d3totpTest extends d3TotpUnitTestCase
|
||||
*/
|
||||
public function getQrCodeElement()
|
||||
{
|
||||
$renderer = BaconQrCodeFactory::renderer(200);
|
||||
BaconQrCodeFactory::renderer(200);
|
||||
|
||||
/** @var stdClass|MockObject $oTotpMock */
|
||||
$oTotpMock = $this->getMockBuilder(stdClass::class)
|
||||
@ -862,7 +862,7 @@ class d3totpTest extends d3TotpUnitTestCase
|
||||
->onlyMethods(['d3Base64_decode'])
|
||||
->getMock();
|
||||
$oModelMock->method('d3Base64_decode')->willReturn(
|
||||
str_pad('foobar', 16, 0, STR_PAD_LEFT)
|
||||
str_pad('foobar', 50, 0, STR_PAD_LEFT)
|
||||
);
|
||||
|
||||
$this->_oModel = $oModelMock;
|
||||
|
@ -18,6 +18,7 @@ use D3\Totp\Application\Model\d3totp;
|
||||
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
|
||||
use D3\Totp\Modules\Application\Controller\Admin\d3_totp_LoginController;
|
||||
use D3\Totp\tests\unit\d3TotpUnitTestCase;
|
||||
use Exception;
|
||||
use OxidEsales\Eshop\Application\Model\User;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidEsales\Eshop\Core\Session;
|
||||
@ -283,8 +284,9 @@ class d3_totp_LoginControllerTest extends d3TotpUnitTestCase
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Modules\Application\Controller\Admin\d3_totp_LoginController::checklogin
|
||||
* @dataProvider checkloginNoTotpDataProvider
|
||||
*/
|
||||
public function checkloginNoTotp()
|
||||
public function checkloginNoTotp($hasLoginCredentials)
|
||||
{
|
||||
/** @var d3totp|MockObject $oTotpMock */
|
||||
$oTotpMock = $this->getMockBuilder(d3totp::class)
|
||||
@ -299,14 +301,28 @@ class d3_totp_LoginControllerTest extends d3TotpUnitTestCase
|
||||
'd3GetTotpObject',
|
||||
'isNoTotpOrNoLogin',
|
||||
'hasValidTotp',
|
||||
'hasLoginCredentials'
|
||||
])
|
||||
->getMock();
|
||||
$oControllerMock->method('d3GetTotpObject')->willReturn($oTotpMock);
|
||||
$oControllerMock->method('isNoTotpOrNoLogin')->willReturn(true);
|
||||
$oControllerMock->method('hasValidTotp')->willReturn(false);
|
||||
$oControllerMock->method('hasLoginCredentials')->willReturn($hasLoginCredentials);
|
||||
|
||||
$this->_oController = $oControllerMock;
|
||||
|
||||
if ($hasLoginCredentials) {
|
||||
// workaround, because test case runs into parent call, stop execution with exception and check thrown
|
||||
/** @var Session|MockObject $sessionMock */
|
||||
$sessionMock = $this->getMockBuilder(Session::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['initNewSession'])
|
||||
->getMock();
|
||||
$sessionMock->method('initNewSession')->willThrowException(new Exception('foo'));
|
||||
Registry::set(Session::class, $sessionMock);
|
||||
$this->expectException(Exception::class);
|
||||
}
|
||||
|
||||
$this->assertSame(
|
||||
'login',
|
||||
$this->callMethod(
|
||||
@ -316,6 +332,17 @@ class d3_totp_LoginControllerTest extends d3TotpUnitTestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function checkloginNoTotpDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'no totp, no login credentials' => [false],
|
||||
'no totp, given login credentials' => [true]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
@ -685,4 +712,37 @@ class d3_totp_LoginControllerTest extends d3TotpUnitTestCase
|
||||
$this->callMethod($this->_oController, 'd3GetUserObject')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @dataProvider hasLoginCredentialsDataProvider
|
||||
* @covers \D3\Totp\Modules\Application\Controller\Admin\d3_totp_LoginController::hasLoginCredentials
|
||||
*/
|
||||
public function hasLoginCredentials($user, $pass, $expected)
|
||||
{
|
||||
$_GET['user'] = $user;
|
||||
$_GET['pwd'] = $pass;
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oController,
|
||||
'hasLoginCredentials'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function hasLoginCredentialsDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'user only' => ['user', null, false],
|
||||
'pass only' => [null, 'password', false],
|
||||
'both' => ['user', 'password', true],
|
||||
];
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ namespace D3\Totp\tests\unit\Modules\Core;
|
||||
use D3\Totp\Application\Model\d3totp;
|
||||
use D3\Totp\Modules\Core\d3_totp_utils;
|
||||
use D3\Totp\tests\unit\d3TotpUnitTestCase;
|
||||
use OxidEsales\Eshop\Core\Config;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidEsales\Eshop\Core\Session;
|
||||
use OxidEsales\Eshop\Core\Utils;
|
||||
@ -34,7 +35,7 @@ class d3_totp_utilsTest extends d3TotpUnitTestCase
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oCoreClass = oxNew(Utils::class);
|
||||
$this->_oCoreClass = oxNew(d3_totp_utils::class);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
@ -77,6 +78,43 @@ class d3_totp_utilsTest extends d3TotpUnitTestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Modules\Core\d3_totp_utils::checkAccessRights
|
||||
*/
|
||||
public function checkAccessRightsForce2FA()
|
||||
{
|
||||
Registry::getSession()->setVariable("auth", false);
|
||||
|
||||
/** @var d3totp|MockObject $oTotpMock */
|
||||
$oTotpMock = $this->getMockBuilder(d3totp::class)
|
||||
->onlyMethods([
|
||||
'loadByUserId',
|
||||
'isActive',
|
||||
])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$oTotpMock->method('loadByUserId')->willReturn(true);
|
||||
$oTotpMock->method('isActive')->willReturn(false);
|
||||
|
||||
/** @var d3_totp_utils|MockObject $oCoreMock */
|
||||
$oCoreMock = $this->getMockBuilder(Utils::class)
|
||||
->onlyMethods(['d3GetTotpObject', 'd3AuthHook', 'redirect', 'd3IsAdminForce2FA'])
|
||||
->getMock();
|
||||
$oCoreMock->method('d3GetTotpObject')->willReturn($oTotpMock);
|
||||
$oCoreMock->method('d3AuthHook')->willReturn(true);
|
||||
$oCoreMock->expects($this->once())->method('redirect')
|
||||
->with($this->stringContains('d3force_2fa'))->willReturn(true);
|
||||
$oCoreMock->method('d3IsAdminForce2FA')->willReturn(true);
|
||||
|
||||
$this->_oCoreClass = $oCoreMock;
|
||||
|
||||
$this->assertTrue(
|
||||
$this->callMethod($this->_oCoreClass, 'checkAccessRights')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
@ -237,4 +275,98 @@ class d3_totp_utilsTest extends d3TotpUnitTestCase
|
||||
$this->callMethod($this->_oCoreClass, 'd3GetTotpObject')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Modules\Core\d3_totp_utils::d3GetConfig
|
||||
*/
|
||||
public function d3GetConfigReturnsRightInstance()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
Config::class,
|
||||
$this->callMethod(
|
||||
$this->_oCoreClass,
|
||||
'd3GetConfig'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @dataProvider d3IsAdminForce2FADataProvider
|
||||
* @covers \D3\Totp\Modules\Core\d3_totp_utils::d3IsAdminForce2FA
|
||||
*/
|
||||
public function d3IsAdminForce2FA($isAdmin, $hasConfig, $expected)
|
||||
{
|
||||
/** @var Config|MockObject $configMock */
|
||||
$configMock = $this->getMockBuilder(Config::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getConfigParam'])
|
||||
->getMock();
|
||||
$configMock->method('getConfigParam')->with($this->equalTo('D3_TOTP_ADMIN_FORCE_2FA'))->willReturn($hasConfig);
|
||||
|
||||
/** @var d3_totp_utils|MockObject $oCoreMock */
|
||||
$oCoreMock = $this->getMockBuilder(Utils::class)
|
||||
->onlyMethods(['isAdmin', 'd3GetConfig'])
|
||||
->getMock();
|
||||
$oCoreMock->method('isAdmin')->willReturn($isAdmin);
|
||||
$oCoreMock->method('d3GetConfig')->willReturn($configMock);
|
||||
|
||||
$this->_oCoreClass = $oCoreMock;
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$this->_oCoreClass,
|
||||
'd3IsAdminForce2FA'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function d3IsAdminForce2FADataProvider(): array
|
||||
{
|
||||
return [
|
||||
//'noAdmin, noConfig' => [false, false, false],
|
||||
//'noAdmin' => [false, true, false],
|
||||
//'noConfig' => [true, false, false],
|
||||
'passed' => [true, true, true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @dataProvider d3AuthHookDataProvider
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Totp\Modules\Core\d3_totp_utils::d3AuthHook
|
||||
*/
|
||||
public function d3AuthHook($argument)
|
||||
{
|
||||
$this->assertSame(
|
||||
$argument,
|
||||
$this->callMethod(
|
||||
$this->_oCoreClass,
|
||||
'd3AuthHook',
|
||||
[$argument]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function d3AuthHookDataProvider(): array
|
||||
{
|
||||
return [
|
||||
[true],
|
||||
[false]
|
||||
];
|
||||
}
|
||||
}
|
@ -1,224 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* https://www.d3data.de
|
||||
*
|
||||
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
||||
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
|
||||
* @link https://www.oxidmodule.com
|
||||
*/
|
||||
|
||||
namespace D3\Totp\tests\unit\Setup;
|
||||
|
||||
use D3\Totp\Setup\Installation;
|
||||
use D3\Totp\tests\unit\d3TotpUnitTestCase;
|
||||
use OxidEsales\Eshop\Core\Database\Adapter\Doctrine\Database;
|
||||
use PHPUnit_Framework_MockObject_MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class InstallationTest extends d3TotpUnitTestCase
|
||||
{
|
||||
/** @var Installation */
|
||||
protected $_oModel;
|
||||
|
||||
/**
|
||||
* setup basic requirements
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_oModel = oxNew(Installation::class);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
unset($this->_oModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function doesTotpTableNotExistCallCheckMethod()
|
||||
{
|
||||
/** @var Installation|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(Installation::class, array(
|
||||
'_checkTableNotExist',
|
||||
));
|
||||
$oModelMock->expects($this->once())->method('_checkTableNotExist')->with('d3totp')->willReturn('testReturn');
|
||||
|
||||
$this->_oModel = $oModelMock;
|
||||
|
||||
$this->assertSame(
|
||||
'testReturn',
|
||||
$this->callMethod($this->_oModel, 'doesTotpTableNotExist')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function addTotpTableNotExistingTable()
|
||||
{
|
||||
/** @var Installation|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(Installation::class, array(
|
||||
'doesTotpTableNotExist',
|
||||
'_addTable2',
|
||||
));
|
||||
$oModelMock->method('doesTotpTableNotExist')->willReturn(true);
|
||||
$oModelMock->expects($this->once())->method('_addTable2')->willReturn('testReturn');
|
||||
|
||||
$this->_oModel = $oModelMock;
|
||||
|
||||
$this->assertSame(
|
||||
'testReturn',
|
||||
$this->callMethod($this->_oModel, 'addTotpTable')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function addTotpTableExistingTable()
|
||||
{
|
||||
/** @var Installation|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(Installation::class, array(
|
||||
'doesTotpTableNotExist',
|
||||
'_addTable2',
|
||||
));
|
||||
$oModelMock->method('doesTotpTableNotExist')->willReturn(false);
|
||||
$oModelMock->expects($this->never())->method('_addTable2')->willReturn('testReturn');
|
||||
|
||||
$this->_oModel = $oModelMock;
|
||||
|
||||
$this->assertFalse(
|
||||
$this->callMethod($this->_oModel, 'addTotpTable')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function doesTotpBCTableNotExistCallCheckMethod()
|
||||
{
|
||||
/** @var Installation|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(Installation::class, array(
|
||||
'_checkTableNotExist',
|
||||
));
|
||||
$oModelMock->expects($this->once())->method('_checkTableNotExist')->with('d3totp_backupcodes')->willReturn('testReturn');
|
||||
|
||||
$this->_oModel = $oModelMock;
|
||||
|
||||
$this->assertSame(
|
||||
'testReturn',
|
||||
$this->callMethod($this->_oModel, 'doesTotpBCTableNotExist')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function addTotpBCTableNotExistingTable()
|
||||
{
|
||||
/** @var Installation|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(Installation::class, array(
|
||||
'doesTotpBCTableNotExist',
|
||||
'_addTable2',
|
||||
));
|
||||
$oModelMock->method('doesTotpBCTableNotExist')->willReturn(true);
|
||||
$oModelMock->expects($this->once())->method('_addTable2')->willReturn('testReturn');
|
||||
|
||||
$this->_oModel = $oModelMock;
|
||||
|
||||
$this->assertSame(
|
||||
'testReturn',
|
||||
$this->callMethod($this->_oModel, 'addTotpBCTable')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function addTotpBCTableExistingTable()
|
||||
{
|
||||
/** @var Installation|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(Installation::class, array(
|
||||
'doesTotpBCTableNotExist',
|
||||
'_addTable2',
|
||||
));
|
||||
$oModelMock->method('doesTotpBCTableNotExist')->willReturn(false);
|
||||
$oModelMock->expects($this->never())->method('_addTable2')->willReturn('testReturn');
|
||||
|
||||
$this->_oModel = $oModelMock;
|
||||
|
||||
$this->assertFalse(
|
||||
$this->callMethod($this->_oModel, 'addTotpBCTable')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function d3GetDbReturnsRightInstance()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
Database::class,
|
||||
$this->callMethod($this->_oModel, 'd3GetDb')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function checkSEONotExistsPass()
|
||||
{
|
||||
/** @var Database|PHPUnit_Framework_MockObject_MockObject $oDbMock */
|
||||
$oDbMock = $this->getMock(Database::class, array(
|
||||
'getOne'
|
||||
), array(), '', false);
|
||||
$oDbMock->expects($this->once())->method('getOne')->willReturn(true);
|
||||
|
||||
/** @var Installation|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(Installation::class, array(
|
||||
'd3GetDb'
|
||||
));
|
||||
$oModelMock->method('d3GetDb')->willReturn($oDbMock);
|
||||
|
||||
$this->_oModel = $oModelMock;
|
||||
|
||||
$this->assertFalse($this->callMethod($this->_oModel, 'checkSEONotExists'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function addSEOPass()
|
||||
{
|
||||
/** @var Installation|PHPUnit_Framework_MockObject_MockObject $oModelMock */
|
||||
$oModelMock = $this->getMock(Installation::class, array(
|
||||
'_executeMultipleQueries'
|
||||
));
|
||||
$oModelMock->expects($this->once())->method('_executeMultipleQueries')->willReturn('testReturn');
|
||||
|
||||
$this->_oModel = $oModelMock;
|
||||
|
||||
$this->assertSame(
|
||||
'testReturn',
|
||||
$this->callMethod($this->_oModel, 'addSEO')
|
||||
);
|
||||
}
|
||||
}
|
Chargement…
Référencer dans un nouveau ticket
Block a user