]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Add custom email for 2FA
authorJeremy Benoist <jeremy.benoist@gmail.com>
Tue, 29 Dec 2015 08:59:46 +0000 (09:59 +0100)
committerJeremy Benoist <jeremy.benoist@gmail.com>
Tue, 29 Dec 2015 10:17:06 +0000 (11:17 +0100)
Related #1490

16 files changed:
app/config/config.yml
app/config/parameters.yml.dist
app/config/tests/parameters.yml.dist.mysql
app/config/tests/parameters.yml.dist.pgsql
app/config/tests/parameters.yml.dist.sqlite
src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
src/Wallabag/UserBundle/DependencyInjection/Configuration.php [new file with mode: 0644]
src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php [new file with mode: 0644]
src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php [new file with mode: 0644]
src/Wallabag/UserBundle/Resources/config/services.yml
src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml [new file with mode: 0644]
src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml [new file with mode: 0644]
src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php [new file with mode: 0644]

index f2538c9027dd8481321f1ae2adad8d9c93899eb6..8403a458f69916a11f2745825de010a2627413c2 100644 (file)
@@ -198,6 +198,7 @@ scheb_two_factor:
         sender_email: %twofactor_sender%
         digits: 6
         template: WallabagUserBundle:Authentication:form.html.twig
+        mailer: wallabag_user.auth_code_mailer
 
 kphoen_rulerz:
     executors:
index b475d63708982ead2cd91f81d07af6503af4d205..149179c2e8afa849aa8b79795a1dae9a121003d9 100644 (file)
@@ -52,10 +52,11 @@ parameters:
     export_mobi: true
     export_pdf: true
     wallabag_url: http://v2.wallabag.org
+    wallabag_support_url: 'https://www.wallabag.org/pages/support.html'
 
     # default user config
     items_on_page: 12
     theme: material
-    language: en_US
+    language: en
     from_email: no-reply@wallabag.org
     rss_limit: 50
index 5b29690c4b04d774c4d5697fd216249c1fe0d71a..096ad8c767fc41aeeaa0ea90d01c36baf0b27576 100644 (file)
@@ -52,6 +52,7 @@ parameters:
     export_mobi: true
     export_pdf: true
     wallabag_url: http://v2.wallabag.org
+    wallabag_support_url: 'https://www.wallabag.org/pages/support.html'
 
     # default user config
     items_on_page: 12
index efdac961725ac117147fac283365b546b9a39361..ca3f6ea20ab59a3347a649203bb0590e9f7d9dd6 100644 (file)
@@ -52,6 +52,7 @@ parameters:
     export_mobi: true
     export_pdf: true
     wallabag_url: http://v2.wallabag.org
+    wallabag_support_url: 'https://www.wallabag.org/pages/support.html'
 
     # default user config
     items_on_page: 12
index 276d1147153dfebe1608f5dda9e7f375b4e2792c..92460bcfc1b12bcf6543d27becfebe7edcc341c5 100644 (file)
@@ -52,6 +52,7 @@ parameters:
     export_mobi: true
     export_pdf: true
     wallabag_url: http://v2.wallabag.org
+    wallabag_support_url: 'https://www.wallabag.org/pages/support.html'
 
     # default user config
     items_on_page: 12
index 84b78a89b8a4f7db73eee519eee2fe28c05a958b..3b3c1e9795d9aa0f06708968432a8cf03ad5926f 100644 (file)
@@ -25,7 +25,7 @@ class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface
 
         $adminConfig->setTheme('material');
         $adminConfig->setItemsPerPage(30);
-        $adminConfig->setLanguage('en_US');
+        $adminConfig->setLanguage('en');
 
         $manager->persist($adminConfig);
 
@@ -34,7 +34,7 @@ class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface
         $bobConfig = new Config($this->getReference('bob-user'));
         $bobConfig->setTheme('default');
         $bobConfig->setItemsPerPage(10);
-        $bobConfig->setLanguage('fr_FR');
+        $bobConfig->setLanguage('fr');
 
         $manager->persist($bobConfig);
 
index cc797c6323a5841dcd02bde55ca338011ebd23de..d9850f7a974b36b35c54917a332e0d1dca725686 100644 (file)
     {{ form_start(form.rss) }}
         {{ form_errors(form.rss) }}
 
+        <div class="row">
+            {% trans %}RSS feeds provided by wallabag allow you to read your saved articles with your favourite RSS reader.{% endtrans %}
+        </div>
+
         <fieldset class="w500p inline">
             <div class="row">
                 <label>Rss token</label>
         </fieldset>
 
         {% if twofactor_auth %}
+        <div class="row">
+            {% trans %}Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion{% endtrans %}
+        </div>
+
         <fieldset class="w500p inline">
             <div class="row">
                 {{ form_label(form.user.twoFactorAuthentication) }}
index d060311d4400f1784a92cbcbe561e3fa39f93d11..8743dc1dd0b207f15508376b0a734f60e0afb8d9 100644 (file)
                             </div>
 
                             {% if twofactor_auth %}
+                            <div class="row">
+                                <div class="input-field col s12">
+                                    {% trans %}Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion{% endtrans %}
+                                </div>
+                            </div>
+
                             <div class="row">
                                 <div class="input-field col s12">
                                     {{ form_widget(form.user.twoFactorAuthentication) }}
index 7b32354f8b61822af84d72d1a6056063fd753910..89ca31e2942b3f2288fe5f703d016174953ba9db 100644 (file)
@@ -44,7 +44,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
         $form = $crawler->filter('button[id=config_save]')->form();
 
         $data = array(
-            'config[theme]' => 0,
+            'config[theme]' => 'baggy',
             'config[items_per_page]' => '30',
             'config[language]' => 'en',
         );
@@ -63,7 +63,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
     {
         return array(
             array(array(
-                'config[theme]' => 0,
+                'config[theme]' => 'baggy',
                 'config[items_per_page]' => '',
                 'config[language]' => 'en',
             )),
diff --git a/src/Wallabag/UserBundle/DependencyInjection/Configuration.php b/src/Wallabag/UserBundle/DependencyInjection/Configuration.php
new file mode 100644 (file)
index 0000000..4223f8d
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+namespace Wallabag\UserBundle\DependencyInjection;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+
+class Configuration implements ConfigurationInterface
+{
+    public function getConfigTreeBuilder()
+    {
+        $treeBuilder = new TreeBuilder();
+        $rootNode = $treeBuilder->root('wallabag_user');
+
+        return $treeBuilder;
+    }
+}
diff --git a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php
new file mode 100644 (file)
index 0000000..c12a893
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+namespace Wallabag\UserBundle\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+use Symfony\Component\DependencyInjection\Loader;
+
+class WallabagUserExtension extends Extension
+{
+    public function load(array $configs, ContainerBuilder $container)
+    {
+        $configuration = new Configuration();
+        $config = $this->processConfiguration($configuration, $configs);
+
+        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
+        $loader->load('services.yml');
+    }
+
+    public function getAlias()
+    {
+        return 'wallabag_user';
+    }
+}
diff --git a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
new file mode 100644 (file)
index 0000000..f196007
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+
+namespace Wallabag\UserBundle\Mailer;
+
+use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
+use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface;
+use Symfony\Component\Translation\DataCollectorTranslator;
+
+/**
+ * Custom mailer for TwoFactorBundle email.
+ * It adds a custom template to the email so user won't get a lonely authentication code but a complete email.
+ */
+class AuthCodeMailer implements AuthCodeMailerInterface
+{
+    /**
+     * SwiftMailer.
+     *
+     * @var \Swift_Mailer
+     */
+    private $mailer;
+
+    /**
+     * Translator for email content.
+     *
+     * @var DataCollectorTranslator
+     */
+    private $translator;
+
+    /**
+     * Sender email address.
+     *
+     * @var string
+     */
+    private $senderEmail;
+
+    /**
+     * Sender name.
+     *
+     * @var string
+     */
+    private $senderName;
+
+    /**
+     * Support URL to report any bugs.
+     *
+     * @var string
+     */
+    private $supportUrl;
+
+    /**
+     * Initialize the auth code mailer with the SwiftMailer object.
+     *
+     * @param \Swift_Mailer           $mailer
+     * @param DataCollectorTranslator $translator
+     * @param string                  $senderEmail
+     * @param string                  $senderName
+     * @param string                  $supportUrl
+     */
+    public function __construct(\Swift_Mailer $mailer, DataCollectorTranslator $translator, $senderEmail, $senderName, $supportUrl)
+    {
+        $this->mailer = $mailer;
+        $this->translator = $translator;
+        $this->senderEmail = $senderEmail;
+        $this->senderName = $senderName;
+        $this->supportUrl = $supportUrl;
+    }
+
+    /**
+     * Send the auth code to the user via email.
+     *
+     * @param TwoFactorInterface $user
+     */
+    public function sendAuthCode(TwoFactorInterface $user)
+    {
+        $message = new \Swift_Message();
+        $message
+            ->setTo($user->getEmail())
+            ->setFrom($this->senderEmail, $this->senderName)
+            ->setSubject($this->translator->trans('auth_code.mailer.subject', array(), 'wallabag_user'))
+            ->setBody($this->translator->trans(
+                'auth_code.mailer.body',
+                [
+                    '%user%' => $user->getName(),
+                    '%code%' => $user->getEmailAuthCode(),
+                    '%support%' => $this->supportUrl,
+                ],
+                'wallabag_user'
+            ))
+        ;
+
+        $this->mailer->send($message);
+    }
+}
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9109b6a378ab0c2dee6970f159055a38fda8f494 100644 (file)
@@ -0,0 +1,9 @@
+services:
+    wallabag_user.auth_code_mailer:
+        class: Wallabag\UserBundle\Mailer\AuthCodeMailer
+        arguments:
+            - "@mailer"
+            - "@translator"
+            - "%scheb_two_factor.email.sender_email%"
+            - "%scheb_two_factor.email.sender_name%"
+            - "%wallabag_support_url%"
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml
new file mode 100644 (file)
index 0000000..f806d1d
--- /dev/null
@@ -0,0 +1,10 @@
+# Two factor mail
+auth_code.mailer.subject: 'Wallabag authentication Code'
+auth_code.mailer.body: |
+    Hi %user%,
+
+    Since you enable two factor authentication on your wallabag account and you just logged in from a new device (computer, phone, etc.), we send you a code to validate your connection.
+    Here is the code: %code%
+
+    Please don't hesitate to contact us if you have any problems: %support%
+    The wallabag team
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml
new file mode 100644 (file)
index 0000000..386b2d9
--- /dev/null
@@ -0,0 +1,10 @@
+# Two factor mail
+auth_code.mailer.subject: "Code d'authentification wallabag"
+auth_code.mailer.body: |
+    Bonjour %user%,
+
+    Comme vous avez activé la double authentification sur votre compte wallabag et que vous venez de vous connecter depuis un nouvel appareil (ordinateur, téléphone, etc.), nous vous envoyons un code pour valider votre connexion.
+    Voici le code à renseigner: %code%
+
+    Si vous avez un problème de connexion, n'hésitez pas à contacter le support: %support%
+    L'équipe wallabag
diff --git a/src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php b/src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php
new file mode 100644 (file)
index 0000000..9122576
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+
+namespace Wallabag\UserBundle\Tests\Mailer;
+
+use Wallabag\UserBundle\Entity\User;
+use Wallabag\UserBundle\Mailer\AuthCodeMailer;
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+use Symfony\Component\Translation\DataCollectorTranslator;
+
+/**
+ * @see https://www.pmg.com/blog/integration-testing-swift-mailer/
+ */
+final class CountableMemorySpool extends \Swift_MemorySpool implements \Countable
+{
+    public function count()
+    {
+        return count($this->messages);
+    }
+
+    public function getMessages()
+    {
+        return $this->messages;
+    }
+}
+
+class AuthCodeMailerTest extends \PHPUnit_Framework_TestCase
+{
+    protected $mailer;
+    protected $spool;
+    protected $dataCollector;
+
+    protected function setUp()
+    {
+        $this->spool = new CountableMemorySpool();
+        $transport = new \Swift_Transport_SpoolTransport(
+            new \Swift_Events_SimpleEventDispatcher(),
+            $this->spool
+        );
+        $this->mailer = new \Swift_Mailer($transport);
+
+        $translator = new Translator('en');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array(
+            'auth_code.mailer.subject' => 'auth_code subject',
+            'auth_code.mailer.body' => 'Hi %user%, here is the code: %code% and the support: %support%',
+        ), 'en', 'wallabag_user');
+
+        $this->dataCollector = new DataCollectorTranslator($translator);
+    }
+
+    public function testSendEmail()
+    {
+        $user = new User();
+        $user->setTwoFactorAuthentication(true);
+        $user->setEmailAuthCode(666666);
+        $user->setEmail('test@wallabag.io');
+        $user->setName('Bob');
+
+        $authCodeMailer = new AuthCodeMailer(
+            $this->mailer,
+            $this->dataCollector,
+            'nobody@test.io',
+            'wallabag test',
+            'http://0.0.0.0'
+        );
+
+        $authCodeMailer->sendAuthCode($user);
+
+        $this->assertCount(1, $this->spool);
+
+        $msg = $this->spool->getMessages()[0];
+        $this->assertArrayHasKey('test@wallabag.io', $msg->getTo());
+        $this->assertEquals(array('nobody@test.io' => 'wallabag test'), $msg->getFrom());
+        $this->assertEquals('auth_code subject', $msg->getSubject());
+        $this->assertContains('Hi Bob, here is the code: 666666 and the support: http://0.0.0.0', $msg->toString());
+    }
+}