mirror of
https://github.com/wallabag/wallabag.git
synced 2024-11-27 03:21:01 +00:00
Handle forgot password
This commit is contained in:
parent
f37d1427a1
commit
6894d48e03
15 changed files with 481 additions and 8 deletions
|
@ -44,5 +44,11 @@ monolog:
|
||||||
assetic:
|
assetic:
|
||||||
use_controller: true
|
use_controller: true
|
||||||
|
|
||||||
#swiftmailer:
|
swiftmailer:
|
||||||
# delivery_address: me@example.com
|
# see http://mailcatcher.me/
|
||||||
|
transport: smtp
|
||||||
|
host: 'localhost'
|
||||||
|
port: 1025
|
||||||
|
username: null
|
||||||
|
password: null
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ web_profiler:
|
||||||
intercept_redirects: false
|
intercept_redirects: false
|
||||||
|
|
||||||
swiftmailer:
|
swiftmailer:
|
||||||
disable_delivery: true
|
# to be able to read emails sent
|
||||||
|
spool:
|
||||||
|
type: file
|
||||||
|
|
||||||
doctrine:
|
doctrine:
|
||||||
dbal:
|
dbal:
|
||||||
|
|
|
@ -41,3 +41,4 @@ parameters:
|
||||||
items_on_page: 12
|
items_on_page: 12
|
||||||
theme: baggy
|
theme: baggy
|
||||||
language: en_US
|
language: en_US
|
||||||
|
from_email: no-reply@wallabag.org
|
||||||
|
|
|
@ -59,4 +59,5 @@ security:
|
||||||
- { path: ^/api/salt, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
- { path: ^/api/salt, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||||
- { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
- { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||||
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||||
|
- { path: ^/forgot-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||||
- { path: ^/, roles: ROLE_USER }
|
- { path: ^/, roles: ROLE_USER }
|
||||||
|
|
|
@ -2,9 +2,12 @@
|
||||||
|
|
||||||
namespace Wallabag\CoreBundle\Controller;
|
namespace Wallabag\CoreBundle\Controller;
|
||||||
|
|
||||||
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||||
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Security\Core\SecurityContext;
|
use Symfony\Component\Security\Core\SecurityContext;
|
||||||
|
use Wallabag\CoreBundle\Form\Type\ResetPasswordType;
|
||||||
|
|
||||||
class SecurityController extends Controller
|
class SecurityController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -25,4 +28,123 @@ class SecurityController extends Controller
|
||||||
'error' => $error,
|
'error' => $error,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request forgot password: show form
|
||||||
|
*
|
||||||
|
* @Route("/forgot-password", name="forgot_password")
|
||||||
|
* @Method({"GET", "POST"})
|
||||||
|
*/
|
||||||
|
public function forgotPasswordAction(Request $request)
|
||||||
|
{
|
||||||
|
$form = $this->createForm('forgot_password');
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isValid()) {
|
||||||
|
$user = $this->getDoctrine()->getRepository('WallabagCoreBundle:User')->findOneByEmail($form->get('email')->getData());
|
||||||
|
|
||||||
|
// generate "hard" token
|
||||||
|
$user->setConfirmationToken(rtrim(strtr(base64_encode(hash('sha256', uniqid(mt_rand(), true), true)), '+/', '-_'), '='));
|
||||||
|
$user->setPasswordRequestedAt(new \DateTime());
|
||||||
|
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$em->persist($user);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
$message = \Swift_Message::newInstance()
|
||||||
|
->setSubject('Reset Password')
|
||||||
|
->setFrom($this->container->getParameter('from_email'))
|
||||||
|
->setTo($user->getEmail())
|
||||||
|
->setBody($this->renderView('WallabagCoreBundle:Mail:forgotPassword.txt.twig', array(
|
||||||
|
'username' => $user->getUsername(),
|
||||||
|
'confirmationUrl' => $this->generateUrl('forgot_password_reset', array('token' => $user->getConfirmationToken()), true),
|
||||||
|
)))
|
||||||
|
;
|
||||||
|
$this->get('mailer')->send($message);
|
||||||
|
|
||||||
|
return $this->redirect($this->generateUrl('forgot_password_check_email',
|
||||||
|
array('email' => $this->getObfuscatedEmail($user->getEmail()))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('WallabagCoreBundle:Security:forgotPassword.html.twig', array(
|
||||||
|
'form' => $form->createView(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the user to check his email provider
|
||||||
|
*
|
||||||
|
* @Route("/forgot-password/check-email", name="forgot_password_check_email")
|
||||||
|
* @Method({"GET"})
|
||||||
|
*/
|
||||||
|
public function checkEmailAction(Request $request)
|
||||||
|
{
|
||||||
|
$email = $request->query->get('email');
|
||||||
|
|
||||||
|
if (empty($email)) {
|
||||||
|
// the user does not come from the forgotPassword action
|
||||||
|
return $this->redirect($this->generateUrl('forgot_password'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('WallabagCoreBundle:Security:checkEmail.html.twig', array(
|
||||||
|
'email' => $email,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset user password
|
||||||
|
*
|
||||||
|
* @Route("/forgot-password/{token}", name="forgot_password_reset")
|
||||||
|
* @Method({"GET", "POST"})
|
||||||
|
*/
|
||||||
|
public function resetAction(Request $request, $token)
|
||||||
|
{
|
||||||
|
$user = $this->getDoctrine()->getRepository('WallabagCoreBundle:User')->findOneByConfirmationToken($token);
|
||||||
|
|
||||||
|
if (null === $user) {
|
||||||
|
$this->createNotFoundException(sprintf('No user found with token "%s"', $token));
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = $this->createForm(new ResetPasswordType());
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isValid()) {
|
||||||
|
$user->setPassword($form->get('new_password')->getData());
|
||||||
|
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$em->persist($user);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
$this->get('session')->getFlashBag()->add(
|
||||||
|
'notice',
|
||||||
|
'The password has been reset successfully'
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->redirect($this->generateUrl('login'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('WallabagCoreBundle:Security:reset.html.twig', array(
|
||||||
|
'token' => $token,
|
||||||
|
'form' => $form->createView(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the truncated email displayed when requesting the resetting.
|
||||||
|
*
|
||||||
|
* Keeping only the part following @ in the address.
|
||||||
|
*
|
||||||
|
* @param string $email
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getObfuscatedEmail($email)
|
||||||
|
{
|
||||||
|
if (false !== $pos = strpos($email, '@')) {
|
||||||
|
$email = '...'.substr($email, $pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $email;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,16 @@ class User implements AdvancedUserInterface, \Serializable
|
||||||
*/
|
*/
|
||||||
private $isActive = true;
|
private $isActive = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="confirmation_token", type="string", nullable=true)
|
||||||
|
*/
|
||||||
|
private $confirmationToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="password_requested_at", type="datetime", nullable=true)
|
||||||
|
*/
|
||||||
|
private $passwordRequestedAt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var date
|
* @var date
|
||||||
*
|
*
|
||||||
|
@ -377,4 +387,50 @@ class User implements AdvancedUserInterface, \Serializable
|
||||||
{
|
{
|
||||||
return $this->config;
|
return $this->config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set confirmationToken
|
||||||
|
*
|
||||||
|
* @param string $confirmationToken
|
||||||
|
* @return User
|
||||||
|
*/
|
||||||
|
public function setConfirmationToken($confirmationToken)
|
||||||
|
{
|
||||||
|
$this->confirmationToken = $confirmationToken;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get confirmationToken
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getConfirmationToken()
|
||||||
|
{
|
||||||
|
return $this->confirmationToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set passwordRequestedAt
|
||||||
|
*
|
||||||
|
* @param \DateTime $passwordRequestedAt
|
||||||
|
* @return User
|
||||||
|
*/
|
||||||
|
public function setPasswordRequestedAt($passwordRequestedAt)
|
||||||
|
{
|
||||||
|
$this->passwordRequestedAt = $passwordRequestedAt;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get passwordRequestedAt
|
||||||
|
*
|
||||||
|
* @return \DateTime
|
||||||
|
*/
|
||||||
|
public function getPasswordRequestedAt()
|
||||||
|
{
|
||||||
|
return $this->passwordRequestedAt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
52
src/Wallabag/CoreBundle/Form/Type/ForgotPasswordType.php
Normal file
52
src/Wallabag/CoreBundle/Form/Type/ForgotPasswordType.php
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
namespace Wallabag\CoreBundle\Form\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Validator\Constraints;
|
||||||
|
use Symfony\Component\Validator\ExecutionContextInterface;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Registry;
|
||||||
|
|
||||||
|
class ForgotPasswordType extends AbstractType
|
||||||
|
{
|
||||||
|
private $doctrine = null;
|
||||||
|
|
||||||
|
public function __construct(Registry $doctrine)
|
||||||
|
{
|
||||||
|
$this->doctrine = $doctrine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('email', 'email', array(
|
||||||
|
'constraints' => array(
|
||||||
|
new Constraints\Email(),
|
||||||
|
new Constraints\NotBlank(),
|
||||||
|
new Constraints\Callback(array(array($this, 'validateEmail'))),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'forgot_password';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateEmail($email, ExecutionContextInterface $context)
|
||||||
|
{
|
||||||
|
$user = $this->doctrine
|
||||||
|
->getRepository('WallabagCoreBundle:User')
|
||||||
|
->findOneByEmail($email);
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
$context->addViolationAt(
|
||||||
|
'email',
|
||||||
|
'No user found with this email',
|
||||||
|
array(),
|
||||||
|
$email
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
src/Wallabag/CoreBundle/Form/Type/ResetPasswordType.php
Normal file
34
src/Wallabag/CoreBundle/Form/Type/ResetPasswordType.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
namespace Wallabag\CoreBundle\Form\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Validator\Constraints;
|
||||||
|
|
||||||
|
class ResetPasswordType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('new_password', 'repeated', array(
|
||||||
|
'type' => 'password',
|
||||||
|
'invalid_message' => 'The password fields must match.',
|
||||||
|
'required' => true,
|
||||||
|
'first_options' => array('label' => 'New password'),
|
||||||
|
'second_options' => array('label' => 'Repeat new password'),
|
||||||
|
'constraints' => array(
|
||||||
|
new Constraints\Length(array(
|
||||||
|
'min' => 8,
|
||||||
|
'minMessage' => 'Password should by at least 8 chars long',
|
||||||
|
)),
|
||||||
|
new Constraints\NotBlank(),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'change_passwd';
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,9 +22,17 @@ services:
|
||||||
- @security.context
|
- @security.context
|
||||||
- %theme% # default theme from parameters.yml
|
- %theme% # default theme from parameters.yml
|
||||||
|
|
||||||
|
# custom form type
|
||||||
wallabag_core.form.type.config:
|
wallabag_core.form.type.config:
|
||||||
class: Wallabag\CoreBundle\Form\Type\ConfigType
|
class: Wallabag\CoreBundle\Form\Type\ConfigType
|
||||||
arguments:
|
arguments:
|
||||||
- %liip_theme.themes%
|
- %liip_theme.themes%
|
||||||
tags:
|
tags:
|
||||||
- { name: form.type, alias: config }
|
- { name: form.type, alias: config }
|
||||||
|
|
||||||
|
wallabag_core.form.type.forgot_password:
|
||||||
|
class: Wallabag\CoreBundle\Form\Type\ForgotPasswordType
|
||||||
|
arguments:
|
||||||
|
- @doctrine
|
||||||
|
tags:
|
||||||
|
- { name: form.type, alias: forgot_password }
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
Hello {{username}}!
|
||||||
|
|
||||||
|
To reset your password - please visit {{confirmationUrl}}
|
||||||
|
|
||||||
|
Regards,
|
||||||
|
Wallabag bot
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "WallabagCoreBundle::layout.html.twig" %}
|
||||||
|
|
||||||
|
{% block title %}{% trans %}Forgot password{% endtrans %}{% endblock %}
|
||||||
|
|
||||||
|
{% block body_class %}login{% endblock %}
|
||||||
|
|
||||||
|
{% block menu %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form>
|
||||||
|
<fieldset class="w500p center">
|
||||||
|
<h2 class="mbs txtcenter">{% trans %}Forgot password{% endtrans %}</h2>
|
||||||
|
|
||||||
|
<p>{{ 'An email has been sent to %email%. It contains a link you must click to reset your password.'|trans({'%email%': email}) }}</p>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,31 @@
|
||||||
|
{% extends "WallabagCoreBundle::layout.html.twig" %}
|
||||||
|
|
||||||
|
{% block title %}{% trans %}Forgot password{% endtrans %}{% endblock %}
|
||||||
|
|
||||||
|
{% block body_class %}login{% endblock %}
|
||||||
|
|
||||||
|
{% block menu %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="{{ path('forgot_password') }}" method="post" name="forgotPasswordform">
|
||||||
|
<fieldset class="w500p center">
|
||||||
|
<h2 class="mbs txtcenter">{% trans %}Forgot password{% endtrans %}</h2>
|
||||||
|
|
||||||
|
{{ form_errors(form) }}
|
||||||
|
|
||||||
|
<p>Enter your email address below and we'll send you password reset instructions.</p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
{{ form_label(form.email) }}
|
||||||
|
{{ form_errors(form.email) }}
|
||||||
|
{{ form_widget(form.email) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mts txtcenter">
|
||||||
|
<button type="submit">Send me reset instructions</button>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
{{ form_rest(form) }}
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -5,15 +5,19 @@
|
||||||
{% block body_class %}login{% endblock %}
|
{% block body_class %}login{% endblock %}
|
||||||
|
|
||||||
{% block menu %}{% endblock %}
|
{% block menu %}{% endblock %}
|
||||||
|
{% block messages %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if error %}
|
|
||||||
<div>{{ error.message }}</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<form action="{{ path('login_check') }}" method="post" name="loginform">
|
<form action="{{ path('login_check') }}" method="post" name="loginform">
|
||||||
<fieldset class="w500p center">
|
<fieldset class="w500p center">
|
||||||
<h2 class="mbs txtcenter">{% trans %}Login to wallabag{% endtrans %}</h2>
|
<h2 class="mbs txtcenter">{% trans %}Login to wallabag{% endtrans %}</h2>
|
||||||
|
{% if error %}
|
||||||
|
<div>{{ error.message }}</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for flashMessage in app.session.flashbag.get('notice') %}
|
||||||
|
<p>{{ flashMessage }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col w150p" for="username">{% trans %}Username{% endtrans %}</label>
|
<label class="col w150p" for="username">{% trans %}Username{% endtrans %}</label>
|
||||||
|
@ -26,7 +30,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mts txtcenter">
|
<div class="row mts txtcenter">
|
||||||
<button type="submit">login</button>
|
<button type="submit">Login</button>
|
||||||
|
<a href="{{ path('forgot_password') }}" class="small">Forgot your password?</a>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
{% extends "WallabagCoreBundle::layout.html.twig" %}
|
||||||
|
|
||||||
|
{% block title %}{% trans %}Change password{% endtrans %}{% endblock %}
|
||||||
|
|
||||||
|
{% block body_class %}login{% endblock %}
|
||||||
|
|
||||||
|
{% block menu %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="{{ path('forgot_password_reset', {'token': token}) }}" method="post" name="loginform">
|
||||||
|
<fieldset class="w500p center">
|
||||||
|
<h2 class="mbs txtcenter">{% trans %}Change password{% endtrans %}</h2>
|
||||||
|
|
||||||
|
{{ form_errors(form) }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
{{ form_label(form.new_password.first) }}
|
||||||
|
{{ form_errors(form.new_password.first) }}
|
||||||
|
{{ form_widget(form.new_password.first) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
{{ form_label(form.new_password.second) }}
|
||||||
|
{{ form_errors(form.new_password.second) }}
|
||||||
|
{{ form_widget(form.new_password.second) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mts txtcenter">
|
||||||
|
<button type="submit">Change password</button>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
{{ form_rest(form) }}
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -3,6 +3,8 @@
|
||||||
namespace Wallabag\CoreBundle\Tests\Controller;
|
namespace Wallabag\CoreBundle\Tests\Controller;
|
||||||
|
|
||||||
use Wallabag\CoreBundle\Tests\WallabagTestCase;
|
use Wallabag\CoreBundle\Tests\WallabagTestCase;
|
||||||
|
use Symfony\Component\Filesystem\Filesystem;
|
||||||
|
use Symfony\Component\Finder\Finder;
|
||||||
|
|
||||||
class SecurityControllerTest extends WallabagTestCase
|
class SecurityControllerTest extends WallabagTestCase
|
||||||
{
|
{
|
||||||
|
@ -37,4 +39,99 @@ class SecurityControllerTest extends WallabagTestCase
|
||||||
|
|
||||||
$this->assertContains('Bad credentials', $client->getResponse()->getContent());
|
$this->assertContains('Bad credentials', $client->getResponse()->getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testForgotPassword()
|
||||||
|
{
|
||||||
|
$client = $this->getClient();
|
||||||
|
|
||||||
|
$crawler = $client->request('GET', '/forgot-password');
|
||||||
|
|
||||||
|
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||||
|
|
||||||
|
$this->assertContains('Forgot password', $client->getResponse()->getContent());
|
||||||
|
|
||||||
|
$form = $crawler->filter('button[type=submit]');
|
||||||
|
|
||||||
|
$this->assertCount(1, $form);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'form' => $form->form(),
|
||||||
|
'client' => $client,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @depends testForgotPassword
|
||||||
|
*/
|
||||||
|
public function testSubmitForgotPasswordFail($parameters)
|
||||||
|
{
|
||||||
|
$form = $parameters['form'];
|
||||||
|
$client = $parameters['client'];
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'forgot_password[email]' => 'baggy',
|
||||||
|
);
|
||||||
|
|
||||||
|
$client->submit($form, $data);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||||
|
$this->assertContains('No user found with this email', $client->getResponse()->getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @depends testForgotPassword
|
||||||
|
*
|
||||||
|
* Instead of using collector which slow down the test suite
|
||||||
|
* http://symfony.com/doc/current/cookbook/email/testing.html
|
||||||
|
*
|
||||||
|
* Use a different way where Swift store email as file
|
||||||
|
*/
|
||||||
|
public function testSubmitForgotPassword($parameters)
|
||||||
|
{
|
||||||
|
$form = $parameters['form'];
|
||||||
|
$client = $parameters['client'];
|
||||||
|
|
||||||
|
$spoolDir = $client->getKernel()->getContainer()->getParameter('swiftmailer.spool.default.file.path');
|
||||||
|
|
||||||
|
// cleanup pool dir
|
||||||
|
$filesystem = new Filesystem();
|
||||||
|
$filesystem->remove($spoolDir);
|
||||||
|
|
||||||
|
// to use `getCollector` since `collect: false` in config_test.yml
|
||||||
|
$client->enableProfiler();
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'forgot_password[email]' => 'bobby@wallabag.org',
|
||||||
|
);
|
||||||
|
|
||||||
|
$client->submit($form, $data);
|
||||||
|
|
||||||
|
$this->assertEquals(302, $client->getResponse()->getStatusCode());
|
||||||
|
|
||||||
|
$crawler = $client->followRedirect();
|
||||||
|
|
||||||
|
$this->assertContains('An email has been sent to', $client->getResponse()->getContent());
|
||||||
|
|
||||||
|
// find every files (ie: emails) inside the spool dir except hidden files
|
||||||
|
$finder = new Finder();
|
||||||
|
$finder
|
||||||
|
->in($spoolDir)
|
||||||
|
->ignoreDotFiles(true)
|
||||||
|
->files();
|
||||||
|
|
||||||
|
$this->assertCount(1, $finder, 'Only one email has been sent');
|
||||||
|
|
||||||
|
foreach ($finder as $file) {
|
||||||
|
$message = unserialize(file_get_contents($file));
|
||||||
|
|
||||||
|
$this->assertInstanceOf('Swift_Message', $message);
|
||||||
|
$this->assertEquals('Reset Password', $message->getSubject());
|
||||||
|
$this->assertEquals('no-reply@wallabag.org', key($message->getFrom()));
|
||||||
|
$this->assertEquals('bobby@wallabag.org', key($message->getTo()));
|
||||||
|
$this->assertContains(
|
||||||
|
'To reset your password - please visit',
|
||||||
|
$message->getBody()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue