diff options
author | Jeremy Benoist <jeremy.benoist@gmail.com> | 2019-01-23 14:43:39 +0100 |
---|---|---|
committer | Jeremy Benoist <jeremy.benoist@gmail.com> | 2019-01-23 14:43:39 +0100 |
commit | 4654a83b6438b88e3b7062a21d18999d9df2fb8e (patch) | |
tree | f20677c3d68c1ea756f0835ff179a0d7d3431a67 | |
parent | 7485a272ffbcc045e6002b4bf4ea289ce0a0f3b4 (diff) | |
download | wallabag-4654a83b6438b88e3b7062a21d18999d9df2fb8e.tar.gz wallabag-4654a83b6438b88e3b7062a21d18999d9df2fb8e.tar.zst wallabag-4654a83b6438b88e3b7062a21d18999d9df2fb8e.zip |
Hash backup codes in the database using `password_hash`update-two-factor-bundle
4 files changed, 38 insertions, 11 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index ed92c999..9257ab18 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php | |||
@@ -197,18 +197,25 @@ class ConfigController extends Controller | |||
197 | } | 197 | } |
198 | 198 | ||
199 | $user = $this->getUser(); | 199 | $user = $this->getUser(); |
200 | $secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret(); | ||
200 | 201 | ||
201 | if (!$user->isGoogleTwoFactor()) { | 202 | $user->setGoogleAuthenticatorSecret($secret); |
202 | $secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret(); | 203 | $user->setEmailTwoFactor(false); |
203 | 204 | ||
204 | $user->setGoogleAuthenticatorSecret($secret); | 205 | $backupCodes = (new BackupCodes())->toArray(); |
205 | $user->setEmailTwoFactor(false); | 206 | $backupCodesHashed = array_map( |
206 | $user->setBackupCodes((new BackupCodes())->toArray()); | 207 | function ($backupCode) { |
208 | return password_hash($backupCode, PASSWORD_DEFAULT); | ||
209 | }, | ||
210 | $backupCodes | ||
211 | ); | ||
207 | 212 | ||
208 | $this->container->get('fos_user.user_manager')->updateUser($user, true); | 213 | $user->setBackupCodes($backupCodesHashed); |
209 | } | 214 | |
215 | $this->container->get('fos_user.user_manager')->updateUser($user, true); | ||
210 | 216 | ||
211 | return $this->render('WallabagCoreBundle:Config:otp_app.html.twig', [ | 217 | return $this->render('WallabagCoreBundle:Config:otp_app.html.twig', [ |
218 | 'backupCodes' => $backupCodes, | ||
212 | 'qr_code' => $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user), | 219 | 'qr_code' => $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user), |
213 | ]); | 220 | ]); |
214 | } | 221 | } |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig index 2e4442e3..0919646e 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig | |||
@@ -20,7 +20,7 @@ | |||
20 | <li> | 20 | <li> |
21 | <p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p> | 21 | <p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p> |
22 | 22 | ||
23 | <p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p> | 23 | <p><strong>{{ backupCodes|join("\n")|nl2br }}</strong></p> |
24 | </li> | 24 | </li> |
25 | <li> | 25 | <li> |
26 | <p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p> | 26 | <p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/otp_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/otp_app.html.twig index 6aef355e..7875d787 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/otp_app.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/otp_app.html.twig | |||
@@ -24,7 +24,7 @@ | |||
24 | <li> | 24 | <li> |
25 | <p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p> | 25 | <p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p> |
26 | 26 | ||
27 | <p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p> | 27 | <p><strong>{{ backupCodes|join("\n")|nl2br }}</strong></p> |
28 | </li> | 28 | </li> |
29 | <li> | 29 | <li> |
30 | <p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p> | 30 | <p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p> |
diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php index ab34e2bf..43fa6a80 100644 --- a/src/Wallabag/UserBundle/Entity/User.php +++ b/src/Wallabag/UserBundle/Entity/User.php | |||
@@ -339,7 +339,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI | |||
339 | */ | 339 | */ |
340 | public function isBackupCode(string $code): bool | 340 | public function isBackupCode(string $code): bool |
341 | { | 341 | { |
342 | return \in_array($code, $this->backupCodes, true); | 342 | return false === $this->findBackupCode($code) ? false : true; |
343 | } | 343 | } |
344 | 344 | ||
345 | /** | 345 | /** |
@@ -347,7 +347,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI | |||
347 | */ | 347 | */ |
348 | public function invalidateBackupCode(string $code): void | 348 | public function invalidateBackupCode(string $code): void |
349 | { | 349 | { |
350 | $key = array_search($code, $this->backupCodes, true); | 350 | $key = $this->findBackupCode($code); |
351 | 351 | ||
352 | if (false !== $key) { | 352 | if (false !== $key) { |
353 | unset($this->backupCodes[$key]); | 353 | unset($this->backupCodes[$key]); |
@@ -385,4 +385,24 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI | |||
385 | return $this->clients->first(); | 385 | return $this->clients->first(); |
386 | } | 386 | } |
387 | } | 387 | } |
388 | |||
389 | /** | ||
390 | * Try to find a backup code from the list of backup codes of the current user. | ||
391 | * | ||
392 | * @param string $code Given code from the user | ||
393 | * | ||
394 | * @return string|false | ||
395 | */ | ||
396 | private function findBackupCode(string $code) | ||
397 | { | ||
398 | foreach ($this->backupCodes as $key => $backupCode) { | ||
399 | // backup code are hashed using `password_hash` | ||
400 | // see ConfigController->otpAppAction | ||
401 | if (password_verify($code, $backupCode)) { | ||
402 | return $key; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | return false; | ||
407 | } | ||
388 | } | 408 | } |