]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Added a button to disable 2FA when enabled
authorNicolas Lœuillet <nicolas@loeuillet.org>
Mon, 13 Apr 2020 14:59:02 +0000 (16:59 +0200)
committerNicolas Lœuillet <nicolas@loeuillet.org>
Mon, 13 Apr 2020 15:00:53 +0000 (17:00 +0200)
20 files changed:
src/Wallabag/CoreBundle/Controller/ConfigController.php
src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ja.yml
src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ru.yml
src/Wallabag/CoreBundle/Resources/translations/messages.th.yml
src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
src/Wallabag/CoreBundle/Resources/translations/messages.zh.yml
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php

index 6655ef93da56781438fb769cd437adbf2e349ae0..56efe82bb88775a8f3e5fac4134a53bec85e72b8 100644 (file)
@@ -192,6 +192,30 @@ class ConfigController extends Controller
         ]);
     }
 
+    /**
+     * Disable 2FA using email.
+     *
+     * @Route("/config/otp/email/disable", name="disable_otp_email")
+     */
+    public function disableOtpEmailAction()
+    {
+        if (!$this->getParameter('twofactor_auth')) {
+            return $this->createNotFoundException('two_factor not enabled');
+        }
+
+        $user = $this->getUser();
+        $user->setEmailTwoFactor(false);
+
+        $this->container->get('fos_user.user_manager')->updateUser($user, true);
+
+        $this->addFlash(
+            'notice',
+            'flashes.config.notice.otp_disabled'
+        );
+
+        return $this->redirect($this->generateUrl('config') . '#set3');
+    }
+
     /**
      * Enable 2FA using email.
      *
@@ -219,6 +243,32 @@ class ConfigController extends Controller
         return $this->redirect($this->generateUrl('config') . '#set3');
     }
 
+    /**
+     * Disable 2FA using OTP app.
+     *
+     * @Route("/config/otp/app/disable", name="disable_otp_app")
+     */
+    public function disableOtpAppAction()
+    {
+        if (!$this->getParameter('twofactor_auth')) {
+            return $this->createNotFoundException('two_factor not enabled');
+        }
+
+        $user = $this->getUser();
+
+        $user->setGoogleAuthenticatorSecret('');
+        $user->setBackupCodes(null);
+
+        $this->container->get('fos_user.user_manager')->updateUser($user, true);
+
+        $this->addFlash(
+            'notice',
+            'flashes.config.notice.otp_disabled'
+        );
+
+        return $this->redirect($this->generateUrl('config') . '#set3');
+    }
+
     /**
      * Enable 2FA using OTP app, user will need to confirm the generated code from the app.
      *
@@ -248,6 +298,11 @@ class ConfigController extends Controller
 
         $this->container->get('fos_user.user_manager')->updateUser($user, true);
 
+        $this->addFlash(
+            'notice',
+            'flashes.config.notice.otp_enabled'
+        );
+
         return $this->render('WallabagCoreBundle:Config:otp_app.html.twig', [
             'backupCodes' => $backupCodes,
             'qr_code' => $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user),
index 53b60c729469a8a4f4a8376246eabe8b2259c9cb..fc43e9fd22df74646bd659e9ad33a865af6d0835 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             # entries_reset: Entries reset
             # archived_reset: Archived entries deleted
             # otp_enabled: Two-factor authentication enabled
+            # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
     entry:
index b9694be84c8a656b7c568e6f3e3dd61d4a8bec0a..53c960b62e98422dac6dfdcb8f017f02b40248ac 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: Einträge zurücksetzen
             archived_reset: Archiverte Einträge zurücksetzen
             # otp_enabled: Two-factor authentication enabled
+            # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
     entry:
index e8b1ea1542d25f6659af50f38ecf2ae2fab304c7..c6e3cd42a7ea18c672dfc255c880c2e73cbf3365 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: Entries reset
             archived_reset: Archived entries deleted
             otp_enabled: Two-factor authentication enabled
+            otp_disabled: Two-factor authentication disabled
             tagging_rules_imported: Tagging rules imported
             tagging_rules_not_imported: Error while importing tagging rules
     entry:
index 6fd44f8e37070e4d5938451cc5e5876e540a5566..72e36449744de18b09fb49bfe5cbb6c2a06d4621 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: Artículos reiniciados
             archived_reset: Artículos archivados borrados
             otp_enabled: Autenticación de dos pasos activada
+            # otp_disabled: Two-factor authentication disabled
             tagging_rules_imported: Reglas de etiquetado importadas
             tagging_rules_not_imported: Un error se ha producico en la importación de las reglas de etiquetado
     entry:
index 627923b074894385d45abbbf8048154d526e8043..8da90018b066c6bf0e72564892ad7211e30bc7ec 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             # entries_reset: Entries reset
             # archived_reset: Archived entries deleted
             # otp_enabled: Two-factor authentication enabled
+            # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
     entry:
index 542dc25cc5381ddc65070bef88c25d2a3cb8d087..d54547819a0b167cae60e21eadfe986a979853d2 100644 (file)
@@ -614,6 +614,7 @@ flashes:
             entries_reset: "Articles supprimés"
             archived_reset: "Articles archivés supprimés"
             otp_enabled: "Authentification à double-facteur activée"
+            otp_disabled: "Authentification à double-facteur désactivée"
             tagging_rules_imported: Règles bien importées
             tagging_rules_not_imported: Impossible d'importer les règles
     entry:
index 5d017a4014bae5b96524af8a3ad70b699bf4d771..99a8dc2dbfe26b91db0fe7d32f46b551d2a429cc 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: Reset articoli
             # archived_reset: Archived entries deleted
             # otp_enabled: Two-factor authentication enabled
+            # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
     entry:
index 9de8c571668005df00c863f0d1ea961d9800df01..a1eaa5ddd755076553b27f3699aeb9772783fa77 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: 記事がリセットされました
             archived_reset: アーカイブ済みの記事がリセットされました
             otp_enabled: 2要素認証が有効化されました
+            # otp_disabled: Two-factor authentication disabled
             tagging_rules_imported: タグ付けルールがインポートされました
             tagging_rules_not_imported: タグ付けルールのインポート中にエラーが発生しました
     entry:
index e0fb1933cd6e61e17bb4407ca439cd93e1a464c4..598243db0a5ffe79ee0e2700e254fdf069206ecf 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: Articles levats
             archived_reset: Articles archivat suprimits
             otp_enabled: Autentificacion en dos temps activada
+            # otp_disabled: Two-factor authentication disabled
             tagging_rules_imported: Règlas d’etiquetatge importadas
             tagging_rules_not_imported: Error en important las règlas d’etiquetatge
     entry:
index dfaf9e892278bfce6230cf122237e56e940a4704..af8447fe9165782ec4003e6b7d669aa405e883c8 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: Zresetuj wpisy
             archived_reset: Zarchiwizowane wpisy usunięte
             # otp_enabled: Two-factor authentication enabled
+            # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
     entry:
index 8908c0cc8a351a0593be8bc6af5c6c2155c07092..d993cb059a9b87093519a5fec262c491d13ffbd0 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: Artigos reinicializados
             archived_reset: Artigos arquivados apagados
             otp_enabled: Autenticação de dois fatores ativada
+            # otp_disabled: Two-factor authentication disabled
             tagging_rules_imported: Regras de tags importadas
             tagging_rules_not_imported: Erro ao importar regras de tags
     entry:
index b269578a0085eb8c2db4380b167a1e711c724fa5..bc8b72e0b15523a32d8ce51cad4368c48b0f35c9 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             # entries_reset: Entries reset
             # archived_reset: Archived entries deleted
             # otp_enabled: Two-factor authentication enabled
+            # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
     entry:
index 648bbc80c71195103a00fbac340f799a8a919353..2f7f55e535f319da6b88999cda83f90bc4b1cf2f 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: "Записи сброшены"
             # archived_reset: Archived entries deleted
             # otp_enabled: Two-factor authentication enabled
+            # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
     entry:
index 4de87adc7a1c7742178f621daa69593370367185..48e1c34ad13aafe67f494cc2e604ea32ff2c73e2 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: รีเซ็ตรายการ
             archived_reset: การลบเอกสารของรายการ
             # otp_enabled: Two-factor authentication enabled
+            # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
     entry:
index 9afa648cda92cf6bb327ce4ae1fa70e69b326796..19029c0b1cabcd262db74f090dac40bf947fbcb3 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             # entries_reset: Entries reset
             # archived_reset: Archived entries deleted
             # otp_enabled: Two-factor authentication enabled
+            # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
     entry:
index a34e38520032abc3f4d57e034e1c81639fb587b2..f48ce37a89ae69dfdebbeca1841a6cfb560d2149 100644 (file)
@@ -613,6 +613,7 @@ flashes:
             entries_reset: 项目列表已重置
             archived_reset: 所有存档项目已删除
             otp_enabled: 两步验证已启用
+            # otp_disabled: Two-factor authentication disabled
             tagging_rules_imported: 标签规则已导入
             tagging_rules_not_imported: 导入标签规则时发生了错误
     entry:
index f719bea252e44a532ad099838cad299b181cc039..eb395eac475af6b492414ede4c78c7d4cd42c622 100644 (file)
                 <tr>
                     <td>{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}</td>
                     <td>{% if app.user.isEmailTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
-                    <td><a href="{{ path('config_otp_email') }}" class="waves-effect waves-light btn{% if app.user.isEmailTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_email'|trans }}</a></td>
+                    <td><a href="{{ path('config_otp_email') }}" class="waves-effect waves-light btn{% if app.user.isEmailTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_email'|trans }}</a>  {% if app.user.isEmailTwoFactor %}<a href="{{ path('disable_otp_email') }}" class="waves-effect waves-light btn">Disable</a>{% endif %}</td>
                 </tr>
                 <tr>
                     <td>{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}</td>
                     <td>{% if app.user.isGoogleTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
-                    <td><a href="{{ path('config_otp_app') }}" class="waves-effect waves-light btn{% if app.user.isGoogleTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_app'|trans }}</a></td>
+                    <td><a href="{{ path('config_otp_app') }}" class="waves-effect waves-light btn{% if app.user.isGoogleTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_app'|trans }}</a> {% if app.user.isGoogleTwoFactor %}<a href="{{ path('disable_otp_app') }}" class="waves-effect waves-light btn">Disable</a>{% endif %}</td>
                 </tr>
             </tbody>
         </table>
index d8e9694d5ce16be5fd73e06ace424fa171b81c03..42d1f2a6a05a22326081679461014c0c8ea15223 100644 (file)
                                             <tr>
                                                 <td>{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}</td>
                                                 <td>{% if app.user.isEmailTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
-                                                <td><a href="{{ path('config_otp_email') }}" class="waves-effect waves-light btn{% if app.user.isEmailTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_email'|trans }}</a></td>
+                                                <td><a href="{{ path('config_otp_email') }}" class="waves-effect waves-light btn{% if app.user.isEmailTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_email'|trans }}</a> {% if app.user.isEmailTwoFactor %}<a href="{{ path('disable_otp_email') }}" class="waves-effect waves-light btn">Disable</a>{% endif %}</td>
                                             </tr>
                                             <tr>
                                                 <td>{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}</td>
                                                 <td>{% if app.user.isGoogleTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
-                                                <td><a href="{{ path('config_otp_app') }}" class="waves-effect waves-light btn{% if app.user.isGoogleTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_app'|trans }}</a></td>
+                                                <td><a href="{{ path('config_otp_app') }}" class="waves-effect waves-light btn{% if app.user.isGoogleTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_app'|trans }}</a> {% if app.user.isGoogleTwoFactor %}<a href="{{ path('disable_otp_app') }}" class="waves-effect waves-light btn">Disable</a>{% endif %}</td>
                                             </tr>
                                         </tbody>
                                     </table>
index fa93c9c21aaba0341610a12f095b15077c4eeabc..b3b3a19a74a8c43c427d3896c51ec9d7d791717c 100644 (file)
@@ -1045,6 +1045,29 @@ class ConfigControllerTest extends WallabagCoreTestCase
         $em->flush();
     }
 
+    public function testUserDisable2faEmail()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/config/otp/email/disable');
+
+        $this->assertSame(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
+        $this->assertContains('flashes.config.notice.otp_disabled', $alert[0]);
+
+        // restore user
+        $em = $this->getEntityManager();
+        $user = $em
+            ->getRepository('WallabagUserBundle:User')
+            ->findOneByUsername('admin');
+
+        $this->assertFalse($user->isEmailTwoFactor());
+    }
+
     public function testUserEnable2faGoogle()
     {
         $this->logInAs('admin');
@@ -1099,6 +1122,30 @@ class ConfigControllerTest extends WallabagCoreTestCase
         $this->assertEmpty($user->getBackupCodes());
     }
 
+    public function testUserDisable2faGoogle()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/config/otp/app/disable');
+
+        $this->assertSame(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
+        $this->assertContains('flashes.config.notice.otp_disabled', $alert[0]);
+
+        // restore user
+        $em = $this->getEntityManager();
+        $user = $em
+            ->getRepository('WallabagUserBundle:User')
+            ->findOneByUsername('admin');
+
+        $this->assertEmpty($user->getGoogleAuthenticatorSecret());
+        $this->assertEmpty($user->getBackupCodes());
+    }
+
     public function testExportTaggingRule()
     {
         $this->logInAs('admin');