add backup code generation
This commit is contained in:
parent
28ad88b734
commit
c3ba0c28b1
@ -34,7 +34,8 @@
|
||||
"php": ">=5.6",
|
||||
"oxid-esales/oxideshop-metapackage-ce": "~6.0.3 || ~6.1.0",
|
||||
"spomky-labs/otphp": "^8.3",
|
||||
"bacon/bacon-qr-code": "^1.0"
|
||||
"bacon/bacon-qr-code": "^1.0",
|
||||
"ircmaxell/random-lib": "^1.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
@ -17,8 +17,10 @@ namespace D3\Totp\Application\Controller\Admin;
|
||||
|
||||
use D3\Totp\Application\Model\d3totp;
|
||||
use D3\Totp\Modules\Application\Model\d3_totp_user;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
|
||||
use OxidEsales\Eshop\Application\Model\User;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
|
||||
@ -30,6 +32,8 @@ class d3user_totp extends AdminDetailsController
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws DBALException
|
||||
* @throws DatabaseConnectionException
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
@ -87,6 +91,7 @@ class d3user_totp extends AdminDetailsController
|
||||
$oTotp->saveSecret($seed);
|
||||
$oTotp->assign($aParams);
|
||||
$oTotp->verify($otp, $seed);
|
||||
$this->addTplParam('aBackupCodes', $oTotp->generateBackupCodes());
|
||||
$oTotp->setId();
|
||||
}
|
||||
$oTotp->save();
|
||||
|
@ -26,6 +26,8 @@ use OxidEsales\Eshop\Core\DatabaseProvider;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Model\BaseModel;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use RandomLib\Factory;
|
||||
use RandomLib\Generator;
|
||||
|
||||
class d3totp extends BaseModel
|
||||
{
|
||||
@ -35,6 +37,7 @@ class d3totp extends BaseModel
|
||||
public $userId;
|
||||
public $totp;
|
||||
protected $timeWindow = 2;
|
||||
protected $_backupCodes = array();
|
||||
|
||||
/**
|
||||
* d3totp constructor.
|
||||
@ -116,6 +119,21 @@ class d3totp extends BaseModel
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function generateBackupCodes()
|
||||
{
|
||||
$factory = new Factory();
|
||||
$generator = $factory->getLowStrengthGenerator();
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$this->_backupCodes[] = $generator->generateString(6, Generator::CHAR_DIGITS);
|
||||
}
|
||||
|
||||
return $this->_backupCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $seed
|
||||
* @return TOTP
|
||||
@ -181,6 +199,40 @@ class d3totp extends BaseModel
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $code
|
||||
* @return false|string
|
||||
* @throws DatabaseConnectionException
|
||||
*/
|
||||
public function d3EncodeBC($code)
|
||||
{
|
||||
$oDb = DatabaseProvider::getDb();
|
||||
$salt = $this->getUser()->getFieldData('oxpasssalt');
|
||||
$sSelect = "SELECT BINARY MD5( CONCAT( " . $oDb->quote($code) . ", UNHEX( ".$oDb->quote($salt)." ) ) )";
|
||||
|
||||
return $oDb->getOne($sSelect);
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->assign(
|
||||
array(
|
||||
'bc1' => $this->d3EncodeBC($this->_backupCodes[0]),
|
||||
'bc2' => $this->d3EncodeBC($this->_backupCodes[1]),
|
||||
'bc3' => $this->d3EncodeBC($this->_backupCodes[2]),
|
||||
'bc4' => $this->d3EncodeBC($this->_backupCodes[3]),
|
||||
'bc5' => $this->d3EncodeBC($this->_backupCodes[4]),
|
||||
'bc6' => $this->d3EncodeBC($this->_backupCodes[5]),
|
||||
'bc7' => $this->d3EncodeBC($this->_backupCodes[6]),
|
||||
'bc8' => $this->d3EncodeBC($this->_backupCodes[7]),
|
||||
'bc9' => $this->d3EncodeBC($this->_backupCodes[8]),
|
||||
'bc10' => $this->d3EncodeBC($this->_backupCodes[9]),
|
||||
)
|
||||
);
|
||||
|
||||
return parent::save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $totp
|
||||
* @param $seed
|
||||
|
@ -40,6 +40,9 @@ $aLang = [
|
||||
'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 Zweifaktorauthentisierung geschützt.',
|
||||
|
||||
'D3_TOTP_BACKUPCODES' => 'Backup-Codes',
|
||||
'D3_TOTP_BACKUPCODES_DESC' => 'Mit diesen Backup-Codes 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-Autetizierung aä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_SAVE' => 'Speichern',
|
||||
|
||||
'D3_TOTP_ERROR_UNVALID' => 'Das Einmalpasswort ist ungültig.',
|
||||
|
@ -40,6 +40,9 @@ $aLang = [
|
||||
'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_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_SAVE' => 'Save',
|
||||
|
||||
'D3_TOTP_ERROR_UNVALID' => 'The one-time password is invalid.',
|
||||
|
@ -8,6 +8,12 @@
|
||||
[{assign var="readonly" value=""}]
|
||||
[{/if}]
|
||||
|
||||
<style type="text/css">
|
||||
td.edittext {
|
||||
white-space: normal;
|
||||
}
|
||||
</style>
|
||||
|
||||
<form name="transfer" id="transfer" action="[{$oViewConf->getSelfLink()}]" method="post">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
<input type="hidden" name="oxid" value="[{$oxid}]">
|
||||
@ -117,6 +123,26 @@
|
||||
<input type="submit" class="edittext" id="oLockButton" name="save" value="[{oxmultilang ident="D3_TOTP_SAVE"}]" onClick="document.myedit.fnc.value='save'" [{$readonly}]>
|
||||
</td>
|
||||
</tr>
|
||||
[{else}]
|
||||
[{if $aBackupCodes}]
|
||||
|
||||
<tr>
|
||||
<td class="edittext" colspan="2">
|
||||
<h4>[{oxmultilang ident="D3_TOTP_BACKUPCODES"}]</h4>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="backupcodes">[{oxmultilang ident="D3_TOTP_BACKUPCODES_DESC"}]</label>
|
||||
<br>
|
||||
<br>
|
||||
<textarea id="backupcodes" rows="10" cols="20">[{strip}]
|
||||
[{'
|
||||
'|implode:$aBackupCodes}]
|
||||
[{/strip}]</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
[{/if}]
|
||||
[{/if}]
|
||||
|
||||
[{/block}]
|
||||
|
@ -75,6 +75,106 @@ class Installation extends d3install_updatebase
|
||||
'sComment' => '',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC1' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC1',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #1',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC2' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC2',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #2',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC3' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC3',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #3',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC4' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC4',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #4',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC5' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC5',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #5',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC6' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC6',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #6',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC7' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC7',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #7',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC8' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC8',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #8',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC9' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC9',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #9',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
),
|
||||
'BC10' => array(
|
||||
'sTableName' => 'd3totp',
|
||||
'sFieldName' => 'BC10',
|
||||
'sType' => 'VARCHAR(64)',
|
||||
'blNull' => false,
|
||||
'sDefault' => false,
|
||||
'sComment' => 'BackupCode #10',
|
||||
'sExtra' => '',
|
||||
'blMultilang' => false,
|
||||
)
|
||||
);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user