aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas Lœuillet <nicolas@loeuillet.org>2015-12-29 20:32:58 +0100
committerNicolas Lœuillet <nicolas@loeuillet.org>2015-12-29 20:32:58 +0100
commite6a228c43bf98f64d2d046314bae224c5b87399e (patch)
tree950c2c0533d4425b6572cfa9de84c40c44956b12
parentc997cfcc9c161241a6398b0942a1a869688d807a (diff)
parentab64c3d9ac591d30447428bd357b5b8c3a9bbcd7 (diff)
downloadwallabag-e6a228c43bf98f64d2d046314bae224c5b87399e.tar.gz
wallabag-e6a228c43bf98f64d2d046314bae224c5b87399e.tar.zst
wallabag-e6a228c43bf98f64d2d046314bae224c5b87399e.zip
Merge pull request #1544 from wallabag/2fa-email
v2 – Add custom email for 2FA
-rw-r--r--.travis.yml1
-rw-r--r--app/config/config.yml1
-rw-r--r--app/config/parameters.yml.dist3
-rw-r--r--app/config/tests/parameters.yml.dist.mysql1
-rw-r--r--app/config/tests/parameters.yml.dist.pgsql1
-rw-r--r--app/config/tests/parameters.yml.dist.sqlite1
-rw-r--r--src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php4
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig8
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig6
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php4
-rw-r--r--src/Wallabag/UserBundle/DependencyInjection/Configuration.php17
-rw-r--r--src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php25
-rw-r--r--src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php93
-rw-r--r--src/Wallabag/UserBundle/Resources/config/services.yml9
-rw-r--r--src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml10
-rw-r--r--src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml10
-rw-r--r--src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php78
17 files changed, 266 insertions, 6 deletions
diff --git a/.travis.yml b/.travis.yml
index 4542fdcb..7a7c9056 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,7 +32,6 @@ matrix:
32 - php: hhvm 32 - php: hhvm
33 env: DB=pgsql # driver for PostgreSQL currently unsupported by HHVM, requires 3rd party dependency 33 env: DB=pgsql # driver for PostgreSQL currently unsupported by HHVM, requires 3rd party dependency
34 allow_failures: 34 allow_failures:
35 - php: 7.0
36 - php: hhvm 35 - php: hhvm
37 36
38branches: 37branches:
diff --git a/app/config/config.yml b/app/config/config.yml
index f2538c90..8403a458 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -198,6 +198,7 @@ scheb_two_factor:
198 sender_email: %twofactor_sender% 198 sender_email: %twofactor_sender%
199 digits: 6 199 digits: 6
200 template: WallabagUserBundle:Authentication:form.html.twig 200 template: WallabagUserBundle:Authentication:form.html.twig
201 mailer: wallabag_user.auth_code_mailer
201 202
202kphoen_rulerz: 203kphoen_rulerz:
203 executors: 204 executors:
diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist
index b475d637..149179c2 100644
--- a/app/config/parameters.yml.dist
+++ b/app/config/parameters.yml.dist
@@ -52,10 +52,11 @@ parameters:
52 export_mobi: true 52 export_mobi: true
53 export_pdf: true 53 export_pdf: true
54 wallabag_url: http://v2.wallabag.org 54 wallabag_url: http://v2.wallabag.org
55 wallabag_support_url: 'https://www.wallabag.org/pages/support.html'
55 56
56 # default user config 57 # default user config
57 items_on_page: 12 58 items_on_page: 12
58 theme: material 59 theme: material
59 language: en_US 60 language: en
60 from_email: no-reply@wallabag.org 61 from_email: no-reply@wallabag.org
61 rss_limit: 50 62 rss_limit: 50
diff --git a/app/config/tests/parameters.yml.dist.mysql b/app/config/tests/parameters.yml.dist.mysql
index 5b29690c..096ad8c7 100644
--- a/app/config/tests/parameters.yml.dist.mysql
+++ b/app/config/tests/parameters.yml.dist.mysql
@@ -52,6 +52,7 @@ parameters:
52 export_mobi: true 52 export_mobi: true
53 export_pdf: true 53 export_pdf: true
54 wallabag_url: http://v2.wallabag.org 54 wallabag_url: http://v2.wallabag.org
55 wallabag_support_url: 'https://www.wallabag.org/pages/support.html'
55 56
56 # default user config 57 # default user config
57 items_on_page: 12 58 items_on_page: 12
diff --git a/app/config/tests/parameters.yml.dist.pgsql b/app/config/tests/parameters.yml.dist.pgsql
index efdac961..ca3f6ea2 100644
--- a/app/config/tests/parameters.yml.dist.pgsql
+++ b/app/config/tests/parameters.yml.dist.pgsql
@@ -52,6 +52,7 @@ parameters:
52 export_mobi: true 52 export_mobi: true
53 export_pdf: true 53 export_pdf: true
54 wallabag_url: http://v2.wallabag.org 54 wallabag_url: http://v2.wallabag.org
55 wallabag_support_url: 'https://www.wallabag.org/pages/support.html'
55 56
56 # default user config 57 # default user config
57 items_on_page: 12 58 items_on_page: 12
diff --git a/app/config/tests/parameters.yml.dist.sqlite b/app/config/tests/parameters.yml.dist.sqlite
index 276d1147..92460bcf 100644
--- a/app/config/tests/parameters.yml.dist.sqlite
+++ b/app/config/tests/parameters.yml.dist.sqlite
@@ -52,6 +52,7 @@ parameters:
52 export_mobi: true 52 export_mobi: true
53 export_pdf: true 53 export_pdf: true
54 wallabag_url: http://v2.wallabag.org 54 wallabag_url: http://v2.wallabag.org
55 wallabag_support_url: 'https://www.wallabag.org/pages/support.html'
55 56
56 # default user config 57 # default user config
57 items_on_page: 12 58 items_on_page: 12
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php
index 84b78a89..3b3c1e97 100644
--- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php
+++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php
@@ -25,7 +25,7 @@ class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface
25 25
26 $adminConfig->setTheme('material'); 26 $adminConfig->setTheme('material');
27 $adminConfig->setItemsPerPage(30); 27 $adminConfig->setItemsPerPage(30);
28 $adminConfig->setLanguage('en_US'); 28 $adminConfig->setLanguage('en');
29 29
30 $manager->persist($adminConfig); 30 $manager->persist($adminConfig);
31 31
@@ -34,7 +34,7 @@ class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface
34 $bobConfig = new Config($this->getReference('bob-user')); 34 $bobConfig = new Config($this->getReference('bob-user'));
35 $bobConfig->setTheme('default'); 35 $bobConfig->setTheme('default');
36 $bobConfig->setItemsPerPage(10); 36 $bobConfig->setItemsPerPage(10);
37 $bobConfig->setLanguage('fr_FR'); 37 $bobConfig->setLanguage('fr');
38 38
39 $manager->persist($bobConfig); 39 $manager->persist($bobConfig);
40 40
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
index cc797c63..d9850f7a 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
@@ -40,6 +40,10 @@
40 {{ form_start(form.rss) }} 40 {{ form_start(form.rss) }}
41 {{ form_errors(form.rss) }} 41 {{ form_errors(form.rss) }}
42 42
43 <div class="row">
44 {% trans %}RSS feeds provided by wallabag allow you to read your saved articles with your favourite RSS reader.{% endtrans %}
45 </div>
46
43 <fieldset class="w500p inline"> 47 <fieldset class="w500p inline">
44 <div class="row"> 48 <div class="row">
45 <label>Rss token</label> 49 <label>Rss token</label>
@@ -101,6 +105,10 @@
101 </fieldset> 105 </fieldset>
102 106
103 {% if twofactor_auth %} 107 {% if twofactor_auth %}
108 <div class="row">
109 {% trans %}Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion{% endtrans %}
110 </div>
111
104 <fieldset class="w500p inline"> 112 <fieldset class="w500p inline">
105 <div class="row"> 113 <div class="row">
106 {{ form_label(form.user.twoFactorAuthentication) }} 114 {{ form_label(form.user.twoFactorAuthentication) }}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
index d060311d..8743dc1d 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
@@ -133,6 +133,12 @@
133 {% if twofactor_auth %} 133 {% if twofactor_auth %}
134 <div class="row"> 134 <div class="row">
135 <div class="input-field col s12"> 135 <div class="input-field col s12">
136 {% trans %}Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion{% endtrans %}
137 </div>
138 </div>
139
140 <div class="row">
141 <div class="input-field col s12">
136 {{ form_widget(form.user.twoFactorAuthentication) }} 142 {{ form_widget(form.user.twoFactorAuthentication) }}
137 {{ form_label(form.user.twoFactorAuthentication) }} 143 {{ form_label(form.user.twoFactorAuthentication) }}
138 {{ form_errors(form.user.twoFactorAuthentication) }} 144 {{ form_errors(form.user.twoFactorAuthentication) }}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
index 7b32354f..89ca31e2 100644
--- a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
+++ b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
@@ -44,7 +44,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
44 $form = $crawler->filter('button[id=config_save]')->form(); 44 $form = $crawler->filter('button[id=config_save]')->form();
45 45
46 $data = array( 46 $data = array(
47 'config[theme]' => 0, 47 'config[theme]' => 'baggy',
48 'config[items_per_page]' => '30', 48 'config[items_per_page]' => '30',
49 'config[language]' => 'en', 49 'config[language]' => 'en',
50 ); 50 );
@@ -63,7 +63,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
63 { 63 {
64 return array( 64 return array(
65 array(array( 65 array(array(
66 'config[theme]' => 0, 66 'config[theme]' => 'baggy',
67 'config[items_per_page]' => '', 67 'config[items_per_page]' => '',
68 'config[language]' => 'en', 68 'config[language]' => 'en',
69 )), 69 )),
diff --git a/src/Wallabag/UserBundle/DependencyInjection/Configuration.php b/src/Wallabag/UserBundle/DependencyInjection/Configuration.php
new file mode 100644
index 00000000..4223f8db
--- /dev/null
+++ b/src/Wallabag/UserBundle/DependencyInjection/Configuration.php
@@ -0,0 +1,17 @@
1<?php
2
3namespace Wallabag\UserBundle\DependencyInjection;
4
5use Symfony\Component\Config\Definition\Builder\TreeBuilder;
6use Symfony\Component\Config\Definition\ConfigurationInterface;
7
8class Configuration implements ConfigurationInterface
9{
10 public function getConfigTreeBuilder()
11 {
12 $treeBuilder = new TreeBuilder();
13 $rootNode = $treeBuilder->root('wallabag_user');
14
15 return $treeBuilder;
16 }
17}
diff --git a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php
new file mode 100644
index 00000000..c12a8937
--- /dev/null
+++ b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php
@@ -0,0 +1,25 @@
1<?php
2
3namespace Wallabag\UserBundle\DependencyInjection;
4
5use Symfony\Component\DependencyInjection\ContainerBuilder;
6use Symfony\Component\Config\FileLocator;
7use Symfony\Component\HttpKernel\DependencyInjection\Extension;
8use Symfony\Component\DependencyInjection\Loader;
9
10class WallabagUserExtension extends Extension
11{
12 public function load(array $configs, ContainerBuilder $container)
13 {
14 $configuration = new Configuration();
15 $config = $this->processConfiguration($configuration, $configs);
16
17 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
18 $loader->load('services.yml');
19 }
20
21 public function getAlias()
22 {
23 return 'wallabag_user';
24 }
25}
diff --git a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
new file mode 100644
index 00000000..f1960070
--- /dev/null
+++ b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
@@ -0,0 +1,93 @@
1<?php
2
3namespace Wallabag\UserBundle\Mailer;
4
5use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
6use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface;
7use Symfony\Component\Translation\DataCollectorTranslator;
8
9/**
10 * Custom mailer for TwoFactorBundle email.
11 * It adds a custom template to the email so user won't get a lonely authentication code but a complete email.
12 */
13class AuthCodeMailer implements AuthCodeMailerInterface
14{
15 /**
16 * SwiftMailer.
17 *
18 * @var \Swift_Mailer
19 */
20 private $mailer;
21
22 /**
23 * Translator for email content.
24 *
25 * @var DataCollectorTranslator
26 */
27 private $translator;
28
29 /**
30 * Sender email address.
31 *
32 * @var string
33 */
34 private $senderEmail;
35
36 /**
37 * Sender name.
38 *
39 * @var string
40 */
41 private $senderName;
42
43 /**
44 * Support URL to report any bugs.
45 *
46 * @var string
47 */
48 private $supportUrl;
49
50 /**
51 * Initialize the auth code mailer with the SwiftMailer object.
52 *
53 * @param \Swift_Mailer $mailer
54 * @param DataCollectorTranslator $translator
55 * @param string $senderEmail
56 * @param string $senderName
57 * @param string $supportUrl
58 */
59 public function __construct(\Swift_Mailer $mailer, DataCollectorTranslator $translator, $senderEmail, $senderName, $supportUrl)
60 {
61 $this->mailer = $mailer;
62 $this->translator = $translator;
63 $this->senderEmail = $senderEmail;
64 $this->senderName = $senderName;
65 $this->supportUrl = $supportUrl;
66 }
67
68 /**
69 * Send the auth code to the user via email.
70 *
71 * @param TwoFactorInterface $user
72 */
73 public function sendAuthCode(TwoFactorInterface $user)
74 {
75 $message = new \Swift_Message();
76 $message
77 ->setTo($user->getEmail())
78 ->setFrom($this->senderEmail, $this->senderName)
79 ->setSubject($this->translator->trans('auth_code.mailer.subject', array(), 'wallabag_user'))
80 ->setBody($this->translator->trans(
81 'auth_code.mailer.body',
82 [
83 '%user%' => $user->getName(),
84 '%code%' => $user->getEmailAuthCode(),
85 '%support%' => $this->supportUrl,
86 ],
87 'wallabag_user'
88 ))
89 ;
90
91 $this->mailer->send($message);
92 }
93}
diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml
index e69de29b..9109b6a3 100644
--- a/src/Wallabag/UserBundle/Resources/config/services.yml
+++ b/src/Wallabag/UserBundle/Resources/config/services.yml
@@ -0,0 +1,9 @@
1services:
2 wallabag_user.auth_code_mailer:
3 class: Wallabag\UserBundle\Mailer\AuthCodeMailer
4 arguments:
5 - "@mailer"
6 - "@translator"
7 - "%scheb_two_factor.email.sender_email%"
8 - "%scheb_two_factor.email.sender_name%"
9 - "%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
index 00000000..f806d1d6
--- /dev/null
+++ b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml
@@ -0,0 +1,10 @@
1# Two factor mail
2auth_code.mailer.subject: 'Wallabag authentication Code'
3auth_code.mailer.body: |
4 Hi %user%,
5
6 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.
7 Here is the code: %code%
8
9 Please don't hesitate to contact us if you have any problems: %support%
10 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
index 00000000..386b2d9e
--- /dev/null
+++ b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml
@@ -0,0 +1,10 @@
1# Two factor mail
2auth_code.mailer.subject: "Code d'authentification wallabag"
3auth_code.mailer.body: |
4 Bonjour %user%,
5
6 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.
7 Voici le code à renseigner: %code%
8
9 Si vous avez un problème de connexion, n'hésitez pas à contacter le support: %support%
10 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
index 00000000..9122576a
--- /dev/null
+++ b/src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php
@@ -0,0 +1,78 @@
1<?php
2
3namespace Wallabag\UserBundle\Tests\Mailer;
4
5use Wallabag\UserBundle\Entity\User;
6use Wallabag\UserBundle\Mailer\AuthCodeMailer;
7use Symfony\Component\Translation\Translator;
8use Symfony\Component\Translation\Loader\ArrayLoader;
9use Symfony\Component\Translation\DataCollectorTranslator;
10
11/**
12 * @see https://www.pmg.com/blog/integration-testing-swift-mailer/
13 */
14final class CountableMemorySpool extends \Swift_MemorySpool implements \Countable
15{
16 public function count()
17 {
18 return count($this->messages);
19 }
20
21 public function getMessages()
22 {
23 return $this->messages;
24 }
25}
26
27class AuthCodeMailerTest extends \PHPUnit_Framework_TestCase
28{
29 protected $mailer;
30 protected $spool;
31 protected $dataCollector;
32
33 protected function setUp()
34 {
35 $this->spool = new CountableMemorySpool();
36 $transport = new \Swift_Transport_SpoolTransport(
37 new \Swift_Events_SimpleEventDispatcher(),
38 $this->spool
39 );
40 $this->mailer = new \Swift_Mailer($transport);
41
42 $translator = new Translator('en');
43 $translator->addLoader('array', new ArrayLoader());
44 $translator->addResource('array', array(
45 'auth_code.mailer.subject' => 'auth_code subject',
46 'auth_code.mailer.body' => 'Hi %user%, here is the code: %code% and the support: %support%',
47 ), 'en', 'wallabag_user');
48
49 $this->dataCollector = new DataCollectorTranslator($translator);
50 }
51
52 public function testSendEmail()
53 {
54 $user = new User();
55 $user->setTwoFactorAuthentication(true);
56 $user->setEmailAuthCode(666666);
57 $user->setEmail('test@wallabag.io');
58 $user->setName('Bob');
59
60 $authCodeMailer = new AuthCodeMailer(
61 $this->mailer,
62 $this->dataCollector,
63 'nobody@test.io',
64 'wallabag test',
65 'http://0.0.0.0'
66 );
67
68 $authCodeMailer->sendAuthCode($user);
69
70 $this->assertCount(1, $this->spool);
71
72 $msg = $this->spool->getMessages()[0];
73 $this->assertArrayHasKey('test@wallabag.io', $msg->getTo());
74 $this->assertEquals(array('nobody@test.io' => 'wallabag test'), $msg->getFrom());
75 $this->assertEquals('auth_code subject', $msg->getSubject());
76 $this->assertContains('Hi Bob, here is the code: 666666 and the support: http://0.0.0.0', $msg->toString());
77 }
78}