]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Hash backup codes in the database using `password_hash` update-two-factor-bundle 3798/head
authorJeremy Benoist <jeremy.benoist@gmail.com>
Wed, 23 Jan 2019 13:43:39 +0000 (14:43 +0100)
committerJeremy Benoist <jeremy.benoist@gmail.com>
Wed, 23 Jan 2019 13:43:39 +0000 (14:43 +0100)
src/Wallabag/CoreBundle/Controller/ConfigController.php
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Config/otp_app.html.twig
src/Wallabag/UserBundle/Entity/User.php

index ed92c999aed5c2d66aab68ea951c8f7e3f974508..9257ab18df6ad092422e4003701195cf84c9d0c9 100644 (file)
@@ -197,18 +197,25 @@ class ConfigController extends Controller
         }
 
         $user = $this->getUser();
+        $secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret();
 
-        if (!$user->isGoogleTwoFactor()) {
-            $secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret();
+        $user->setGoogleAuthenticatorSecret($secret);
+        $user->setEmailTwoFactor(false);
 
-            $user->setGoogleAuthenticatorSecret($secret);
-            $user->setEmailTwoFactor(false);
-            $user->setBackupCodes((new BackupCodes())->toArray());
+        $backupCodes = (new BackupCodes())->toArray();
+        $backupCodesHashed = array_map(
+            function ($backupCode) {
+                return password_hash($backupCode, PASSWORD_DEFAULT);
+            },
+            $backupCodes
+        );
 
-            $this->container->get('fos_user.user_manager')->updateUser($user, true);
-        }
+        $user->setBackupCodes($backupCodesHashed);
+
+        $this->container->get('fos_user.user_manager')->updateUser($user, true);
 
         return $this->render('WallabagCoreBundle:Config:otp_app.html.twig', [
+            'backupCodes' => $backupCodes,
             'qr_code' => $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user),
         ]);
     }
index 2e4442e36651d3dccef3597993c45589b626b318..0919646ec3e7a51ffbd727fa736a6bbceafbf520 100644 (file)
@@ -20,7 +20,7 @@
         <li>
             <p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p>
 
-            <p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p>
+            <p><strong>{{ backupCodes|join("\n")|nl2br }}</strong></p>
         </li>
         <li>
             <p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p>
index 6aef355eb85222bee36d9f88aead804c90a71d6b..7875d78775a7e0048c4b7cda0a83678f147265f6 100644 (file)
@@ -24,7 +24,7 @@
                         <li>
                             <p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p>
 
-                            <p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p>
+                            <p><strong>{{ backupCodes|join("\n")|nl2br }}</strong></p>
                         </li>
                         <li>
                             <p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p>
index ab34e2bfc956d55cf1f3705ceb48cd3a535a22ef..43fa6a80fc2bb47b40970b936a21a2612de0a59a 100644 (file)
@@ -339,7 +339,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI
      */
     public function isBackupCode(string $code): bool
     {
-        return \in_array($code, $this->backupCodes, true);
+        return false === $this->findBackupCode($code) ? false : true;
     }
 
     /**
@@ -347,7 +347,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI
      */
     public function invalidateBackupCode(string $code): void
     {
-        $key = array_search($code, $this->backupCodes, true);
+        $key = $this->findBackupCode($code);
 
         if (false !== $key) {
             unset($this->backupCodes[$key]);
@@ -385,4 +385,24 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI
             return $this->clients->first();
         }
     }
+
+    /**
+     * Try to find a backup code from the list of backup codes of the current user.
+     *
+     * @param string $code Given code from the user
+     *
+     * @return string|false
+     */
+    private function findBackupCode(string $code)
+    {
+        foreach ($this->backupCodes as $key => $backupCode) {
+            // backup code are hashed using `password_hash`
+            // see ConfigController->otpAppAction
+            if (password_verify($code, $backupCode)) {
+                return $key;
+            }
+        }
+
+        return false;
+    }
 }