add test for totp login controller

This commit is contained in:
Daniel Seifert 2019-08-05 22:59:26 +02:00
parent d20322867d
commit ff9f1722af
6 changed files with 307 additions and 7 deletions

View File

@ -20,6 +20,7 @@ use D3\Totp\Application\Model\d3totp;
use OxidEsales\Eshop\Application\Controller\FrontendController; use OxidEsales\Eshop\Application\Controller\FrontendController;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Utils;
class d3totplogin extends FrontendController class d3totplogin extends FrontendController
{ {
@ -30,22 +31,32 @@ class d3totplogin extends FrontendController
if (Registry::getSession()->hasVariable(d3totp::TOTP_SESSION_VARNAME) || if (Registry::getSession()->hasVariable(d3totp::TOTP_SESSION_VARNAME) ||
false == Registry::getSession()->hasVariable(d3totp::TOTP_SESSION_CURRENTUSER) false == Registry::getSession()->hasVariable(d3totp::TOTP_SESSION_CURRENTUSER)
) { ) {
Registry::getUtils()->redirect('index.php?cl=start', true, 302); $this->getUtils()->redirect('index.php?cl=start', true, 302);
if (false == defined('OXID_PHP_UNIT')) {
exit; exit;
} }
}
$this->addTplParam('navFormParams', Registry::getSession()->getVariable(d3totp::TOTP_SESSION_NAVFORMPARAMS)); $this->addTplParam('navFormParams', Registry::getSession()->getVariable(d3totp::TOTP_SESSION_NAVFORMPARAMS));
return parent::render(); return parent::render();
} }
/**
* @return Utils
*/
public function getUtils()
{
return Registry::getUtils();
}
/** /**
* @return string|void * @return string|void
* @throws DatabaseConnectionException * @throws DatabaseConnectionException
*/ */
public function getBackupCodeCountMessage() public function getBackupCodeCountMessage()
{ {
$oBackupCodeList = oxNew(d3backupcodelist::class); $oBackupCodeList = $this->getBackupCodeListObject();
$iCount = $oBackupCodeList->getAvailableCodeCount(Registry::getSession()->getVariable(d3totp::TOTP_SESSION_CURRENTUSER)); $iCount = $oBackupCodeList->getAvailableCodeCount(Registry::getSession()->getVariable(d3totp::TOTP_SESSION_CURRENTUSER));
if ($iCount < 4) { if ($iCount < 4) {
@ -58,6 +69,14 @@ class d3totplogin extends FrontendController
return; return;
} }
/**
* @return d3backupcodelist
*/
public function getBackupCodeListObject()
{
return oxNew(d3backupcodelist::class);
}
public function getPreviousClass() public function getPreviousClass()
{ {
return Registry::getSession()->getVariable(d3totp::TOTP_SESSION_CURRENTCLASS); return Registry::getSession()->getVariable(d3totp::TOTP_SESSION_CURRENTCLASS);

View File

@ -44,7 +44,7 @@ $aLang = [
'D3_TOTP_BACKUPCODES' => 'Backupcodes', 'D3_TOTP_BACKUPCODES' => 'Backupcodes',
'D3_TOTP_BACKUPCODES_DESC' => 'Mit diesen Backupcodes können Sie sich anmelden, wenn die Generierung des Einmalpasswortes nicht möglich ist (z.B. Gerät verloren oder neu installiert). Sie können dann die Einstellungen zur Verwendung der 2-Faktor-Authentisierung ändern oder einen neuen Zugang erstellen. Speichern Sie sich diese Codes bitte in diesem Moment sicher ab. Nach Verlassen dieser Seite können diese Codes nicht erneut angezeigt werden.', 'D3_TOTP_BACKUPCODES_DESC' => 'Mit diesen Backupcodes können Sie sich anmelden, wenn die Generierung des Einmalpasswortes nicht möglich ist (z.B. Gerät verloren oder neu installiert). Sie können dann die Einstellungen zur Verwendung der 2-Faktor-Authentisierung ändern oder einen neuen Zugang erstellen. Speichern Sie sich diese Codes bitte in diesem Moment sicher ab. Nach Verlassen dieser Seite können diese Codes nicht erneut angezeigt werden.',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcodes verfügbar', 'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcode(s) verfügbar',
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'Um neue Backupcodes zu erstellen, löschen Sie die bestehende Registrierung und legen diese bitte neu an.', 'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'Um neue Backupcodes zu erstellen, löschen Sie die bestehende Registrierung und legen diese bitte neu an.',
'D3_TOTP_ACCOUNT_SAVE' => 'Einstellungen übernehmen', 'D3_TOTP_ACCOUNT_SAVE' => 'Einstellungen übernehmen',

View File

@ -44,7 +44,7 @@ $aLang = [
'D3_TOTP_BACKUPCODES' => 'backup codes', 'D3_TOTP_BACKUPCODES' => 'backup codes',
'D3_TOTP_BACKUPCODES_DESC' => 'You can use these backup codes to log on if it is not possible to generate the one-time password (e.g. device lost or newly installed). You can then change the settings to use 2-factor authentication or create a new account. Please save these codes securely at this moment. After leaving this page, these codes cannot be displayed again.', 'D3_TOTP_BACKUPCODES_DESC' => 'You can use these backup codes to log on if it is not possible to generate the one-time password (e.g. device lost or newly installed). You can then change the settings to use 2-factor authentication or create a new account. Please save these codes securely at this moment. After leaving this page, these codes cannot be displayed again.',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'still %1$s backup codes available', 'D3_TOTP_AVAILBACKUPCODECOUNT' => 'still %1$s backup code(s) available',
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'To create new backup codes, delete the existing registry and create a new one.', 'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'To create new backup codes, delete the existing registry and create a new one.',
'D3_TOTP_ACCOUNT_SAVE' => 'Confirm settings', 'D3_TOTP_ACCOUNT_SAVE' => 'Confirm settings',

View File

@ -42,7 +42,7 @@ $aLang = [
'D3_TOTP_BACKUPCODES' => 'Backupcodes', 'D3_TOTP_BACKUPCODES' => 'Backupcodes',
'D3_TOTP_BACKUPCODES_DESC' => 'Mit diesen Backupcodes können Sie sich anmelden, wenn die Generierung des Einmalpasswortes nicht möglich ist (z.B. Gerät verloren oder neu installiert). Sie können dann die Einstellungen zur Verwendung der 2-Faktor-Authentisierung ändern oder einen neuen Zugang erstellen. Speichern Sie sich diese Codes bitte in diesem Moment sicher ab. Nach Verlassen dieser Seite können diese Codes nicht erneut angezeigt werden.', 'D3_TOTP_BACKUPCODES_DESC' => 'Mit diesen Backupcodes können Sie sich anmelden, wenn die Generierung des Einmalpasswortes nicht möglich ist (z.B. Gerät verloren oder neu installiert). Sie können dann die Einstellungen zur Verwendung der 2-Faktor-Authentisierung ändern oder einen neuen Zugang erstellen. Speichern Sie sich diese Codes bitte in diesem Moment sicher ab. Nach Verlassen dieser Seite können diese Codes nicht erneut angezeigt werden.',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcodes verfügbar', 'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcode(s) verfügbar',
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'Um neue Backupcodes zu erstellen, löschen Sie die bestehende Registrierung und legen diese bitte neu an.', 'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'Um neue Backupcodes zu erstellen, löschen Sie die bestehende Registrierung und legen diese bitte neu an.',
'D3_TOTP_SAVE' => 'Speichern', 'D3_TOTP_SAVE' => 'Speichern',

View File

@ -42,7 +42,7 @@ $aLang = [
'D3_TOTP_BACKUPCODES' => 'backup codes', 'D3_TOTP_BACKUPCODES' => 'backup codes',
'D3_TOTP_BACKUPCODES_DESC' => 'You can use these backup codes to log on if it is not possible to generate the one-time password (e.g. device lost or newly installed). You can then change the settings to use 2-factor authentication or create a new 2FA login. Please save these codes safely at this moment. After leaving this page, these codes cannot be displayed again.', 'D3_TOTP_BACKUPCODES_DESC' => 'You can use these backup codes to log on if it is not possible to generate the one-time password (e.g. device lost or newly installed). You can then change the settings to use 2-factor authentication or create a new 2FA login. Please save these codes safely at this moment. After leaving this page, these codes cannot be displayed again.',
'D3_TOTP_AVAILBACKUPCODECOUNT' => '%1$s backup codes still available', 'D3_TOTP_AVAILBACKUPCODECOUNT' => '%1$s backup code(s) still available',
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'To create new backup codes, delete the existing registry and create a new one.', 'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'To create new backup codes, delete the existing registry and create a new one.',
'D3_TOTP_SAVE' => 'Save', 'D3_TOTP_SAVE' => 'Save',

View File

@ -0,0 +1,281 @@
<?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\tests\unit\Application\Controller;
use D3\Totp\Application\Controller\d3totplogin;
use D3\Totp\Application\Model\d3backupcodelist;
use D3\Totp\Application\Model\d3totp;
use D3\Totp\tests\unit\d3TotpUnitTestCase;
use Doctrine\DBAL\DBALException;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Utils;
use PHPUnit_Framework_MockObject_MockObject;
use ReflectionException;
class d3totploginTest extends d3TotpUnitTestCase
{
/** @var d3totplogin */
protected $_oController;
/**
* setup basic requirements
* @throws DBALException
* @throws DatabaseConnectionException
* @throws DatabaseErrorException
*/
public function setUp()
{
parent::setUp();
$this->_oController = oxNew(d3totplogin::class);
Registry::getSession()->deleteVariable(d3totp::TOTP_SESSION_CURRENTUSER);
Registry::getSession()->deleteVariable(d3totp::TOTP_SESSION_CURRENTCLASS);
}
public function tearDown()
{
parent::tearDown();
unset($this->_oController);
}
/**
* @test
* @throws ReflectionException
*/
public function renderRedirectIfNoTotp()
{
/** @var Utils|PHPUnit_Framework_MockObject_MockObject $oUtilsMock */
$oUtilsMock = $this->getMock(Utils::class, array(
'redirect'
));
$oUtilsMock->expects($this->once())->method('redirect')->willReturn(true);
/** @var d3totplogin|PHPUnit_Framework_MockObject_MockObject $oControllerMock */
$oControllerMock = $this->getMock(d3totplogin::class, array(
'getUtils'
));
$oControllerMock->method('getUtils')->willReturn($oUtilsMock);
$this->_oController = $oControllerMock;
$this->callMethod($this->_oController, 'render');
}
/**
* @test
* @throws ReflectionException
*/
public function renderDontRedirect()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTUSER, 'foo');
/** @var Utils|PHPUnit_Framework_MockObject_MockObject $oUtilsMock */
$oUtilsMock = $this->getMock(Utils::class, array(
'redirect'
));
$oUtilsMock->expects($this->never())->method('redirect')->willReturn(true);
/** @var d3totplogin|PHPUnit_Framework_MockObject_MockObject $oControllerMock */
$oControllerMock = $this->getMock(d3totplogin::class, array(
'getUtils'
));
$oControllerMock->method('getUtils')->willReturn($oUtilsMock);
$this->_oController = $oControllerMock;
$this->assertSame(
'd3totplogin.tpl',
$this->callMethod($this->_oController, 'render')
);
}
/**
* @test
* @throws ReflectionException
*/
public function getUtilsReturnsRightInstance()
{
$this->assertInstanceOf(
Utils::class,
$this->callMethod($this->_oController, 'getUtils')
);
}
/**
* @test
* @throws ReflectionException
*/
public function getBackupCodeCountMessageReturnMessage()
{
/** @var d3backupcodelist|PHPUnit_Framework_MockObject_MockObject $oBackupCodesListMock */
$oBackupCodesListMock = $this->getMock(d3backupcodelist::class, array(
'getAvailableCodeCount'
));
$oBackupCodesListMock->method('getAvailableCodeCount')->willReturn(1);
/** @var d3totplogin|PHPUnit_Framework_MockObject_MockObject $oControllerMock */
$oControllerMock = $this->getMock(d3totplogin::class, array(
'getBackupCodeListObject'
));
$oControllerMock->method('getBackupCodeListObject')->willReturn($oBackupCodesListMock);
$this->_oController = $oControllerMock;
$this->assertGreaterThan(
0,
strpos(
$this->callMethod($this->_oController, 'getBackupCodeCountMessage'),
' 1 '
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function getBackupCodeCountMessageReturnNoMessage()
{
/** @var d3backupcodelist|PHPUnit_Framework_MockObject_MockObject $oBackupCodesListMock */
$oBackupCodesListMock = $this->getMock(d3backupcodelist::class, array(
'getAvailableCodeCount'
));
$oBackupCodesListMock->method('getAvailableCodeCount')->willReturn(1234);
/** @var d3totplogin|PHPUnit_Framework_MockObject_MockObject $oControllerMock */
$oControllerMock = $this->getMock(d3totplogin::class, array(
'getBackupCodeListObject'
));
$oControllerMock->method('getBackupCodeListObject')->willReturn($oBackupCodesListMock);
$this->_oController = $oControllerMock;
$this->assertEmpty(
$this->callMethod($this->_oController, 'getBackupCodeCountMessage')
);
}
/**
* @test
* @throws ReflectionException
*/
public function getBackupCodeListObjectReturnsRightInstance()
{
$this->assertInstanceOf(
d3backupcodelist::class,
$this->callMethod($this->_oController, 'getBackupCodeListObject')
);
}
/**
* @test
* @throws ReflectionException
*/
public function canGetPreviousClass()
{
$className = "testClass";
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, $className);
$this->assertSame(
$className,
$this->callMethod($this->_oController, 'getPreviousClass')
);
}
/**
* @test
* @throws ReflectionException
*/
public function orderClassIsOrderStep()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, 'order');
$this->assertTrue(
$this->callMethod(
$this->_oController,
'previousClassIsOrderStep'
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function startClassIsNoOrderStep()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, 'start');
$this->assertFalse(
$this->callMethod(
$this->_oController,
'previousClassIsOrderStep'
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function getIsOrderStepIsSameLikeOrderClass()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, 'order');
$this->assertTrue(
$this->callMethod(
$this->_oController,
'getIsOrderStep'
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function getIsOrderStepIsSameLikeStartClass()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, 'start');
$this->assertFalse(
$this->callMethod(
$this->_oController,
'getIsOrderStep'
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function canGetBreadCrumb()
{
$aBreadCrumb = $this->callMethod($this->_oController, 'getBreadCrumb');
$this->assertInternalType('string', $aBreadCrumb[0]['title']);
$this->assertTrue(strlen($aBreadCrumb[0]['title']) > 1);
$this->assertInternalType('string', $aBreadCrumb[0]['link']);
$this->assertTrue(strlen($aBreadCrumb[0]['link']) > 1);
}
}