Skip to content

Commit

Permalink
Add a setting for the allowed time discrepancy
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher Mühl committed Jan 5, 2018
1 parent 3dbc7e1 commit 50d341b
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Select _Packages > Install Packages_ and search for `contao-tfa-bundle`. The but
## Usage
To enable Two-Factor-Authentication for your account, visit your backend profile and open the "_Two-Factor Authentication_" section. Scan the displayed QR code with a compatible app (we recommend **Google Authenticator**, which is available for iOS and Android), verify by typing in the code generated by your app and save.

Since the generated code is time-based and thus changes periodically, it is important that your server time is set up correctly. By default the used library for code verification is able to correct for up to 30 seconds in either direction. This might be configurable in future versions of this bundle.
Since the generated code is time-based and thus changes periodically, it is important that your server time is set up correctly. By default the used library for code verification is able to correct for up to 30 seconds in either direction. This can be changed in the security section of your application settings.

## Caveats
This bundle intercepts all backend requests to display a two-factor-authentication page for users that have 2FA enabled, but haven't yet authenticated themselves. As such the users can still log in, but they can't access any backend pages.
Expand Down
5 changes: 2 additions & 3 deletions src/EventListener/RequestListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use DieSchittigs\TwoFactorAuth\TwoFactorFactory;
use Symfony\Component\HttpFoundation\Response;
use Contao\TwoFactorAuthTemplate;
use RobThree\Auth\TwoFactorAuth;

class RequestListener
{
Expand Down Expand Up @@ -72,8 +72,7 @@ public function onKernelRequest(GetResponseEvent $event)
$secret = $this->tokenStorage->getToken()->getUser()->tfaSecret;
$code = \Input::post('2fa_code');

$auth = new TwoFactorAuth;
if ($auth->verifyCode($secret, $code)) {
if (TwoFactorFactory::verifyCode($secret, $code)) {
$this->session->set('2fa_required', false);
return;
} else {
Expand Down
9 changes: 3 additions & 6 deletions src/Resources/contao/classes/TwoFactorWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

namespace Contao;

use RobThree\Auth\TwoFactorAuth;

use DieSchittigs\TwoFactorAuth\TwoFactorFactory;

class TwoFactorWidget extends \Widget
{
Expand Down Expand Up @@ -53,8 +52,7 @@ protected function validator($secret)
}

// Verify the entered code with the secret.
$auth = new TwoFactorAuth;
if (!$auth->verifyCode($secret, $code)) {
if (!TwoFactorFactory::verifyCode($secret, $code)) {
$this->addError($GLOBALS['TL_LANG']['tl_user']['tfa_exception_invalid']);
}

Expand All @@ -74,8 +72,7 @@ public function generate()
*/
public function parse($attributes = null)
{
$title = $GLOBALS['TL_CONFIG']['websiteTitle'];
$auth = new TwoFactorAuth($title);
$auth = TwoFactorFactory::generate();

if ($this->user->tfaSecret) {
// Prefer the user's saved secret.
Expand Down
3 changes: 3 additions & 0 deletions src/Resources/contao/config/default.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

$GLOBALS['TL_CONFIG']['tfaTtopDiscrepancy'] = 1;
15 changes: 15 additions & 0 deletions src/Resources/contao/dca/tl_settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

$GLOBALS['TL_DCA']['tl_settings']['fields']['tfaTtopDiscrepancy'] = [
'label' => &$GLOBALS['TL_LANG']['tl_settings']['tfaTtopDiscrepancy'],
'inputType' => 'text',
'eval' => ['minval' => '0', 'rgxp' => 'natural', 'tl_class' => 'w50'],
'default' => '1',
];

// Add the TTOP discrepancy setting
$GLOBALS['TL_DCA']['tl_settings']['palettes']['default'] = str_replace(
'allowedTags',
'allowedTags,tfaTtopDiscrepancy',
$GLOBALS['TL_DCA']['tl_settings']['palettes']['default']
);
4 changes: 4 additions & 0 deletions src/Resources/contao/languages/de/tl_settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php

$GLOBALS['TL_LANG']['tl_settings']['tfaTtopDiscrepancy'][0] = 'Erlaubte 2FA-Diskrepanz';
$GLOBALS['TL_LANG']['tl_settings']['tfaTtopDiscrepancy'][1] = 'Gibt an wie viele Perioden der eingegebene 2FA-Code vom Server-Code abweichen kann (z.B. 1 erlaubt eine Abweichung von &plusmn;30 Sekunden, 2 erlaubt &plusmn;60 Sekunden, &hellip;)';
4 changes: 4 additions & 0 deletions src/Resources/contao/languages/en/tl_settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php

$GLOBALS['TL_LANG']['tl_settings']['tfaTtopDiscrepancy'][0] = 'Allowed 2FA discrepancy';
$GLOBALS['TL_LANG']['tl_settings']['tfaTtopDiscrepancy'][1] = 'Specifies how many periods the entered 2FA code can deviate from the server-code (e.g. 1 allows for a deviation of &plusmn;30 seconds, 2 allows for &plusmn;60 seconds, &hellip;)';
2 changes: 1 addition & 1 deletion src/Resources/contao/templates/be_2fa_field.html5
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<?php if ($this->tfaEnabled): ?>
<p class="tl_info"><?= $GLOBALS['TL_LANG']['tl_user']['tfa_activated'] ?></p>

<div class="w50 widget cbx">
<div class="w50 widget m12">
<div id="ctrl_useCE" class="tl_checkbox_single_container">
<input type="checkbox" name="deactivate_tfa" id="opt_deactivate_tfa" class="tl_checkbox" value="1">
<label for="opt_deactivate_tfa"><?= $GLOBALS['TL_LANG']['tl_user']['tfa_deactivate'] ?></label>
Expand Down
40 changes: 40 additions & 0 deletions src/TwoFactorFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace DieSchittigs\TwoFactorAuth;

use RobThree\Auth\TwoFactorAuth;


class TwoFactorFactory
{
/**
* Generates a TwoFactorAuth object with the website title as its label
*
* @return TwoFactorAuth
*/
public static function generate()
{
$title = $GLOBALS['TL_CONFIG']['websiteTitle'];
return new TwoFactorAuth($title);
}

/**
* Verifies a code with the configured discrepancy
*
* @param string $secret The secret to verify the code with
* @param string $code The code to verify
* @return boolean
*/
public static function verifyCode($secret, $code)
{
$discrepancy = (int) $GLOBALS['TL_CONFIG']['tfaTtopDiscrepancy'];

if ($discrepancy < 0) {
// Make sure the discrepancy is positive, otherwise we're stuck in an infinite loop.
$discrepancy = -$discrepancy;
}

$auth = self::generate();
return $auth->verifyCode($secret, $code, $discrepancy);
}
}

0 comments on commit 50d341b

Please sign in to comment.