mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-23 08:03:49 +00:00
fix folder name
This commit is contained in:
336
src/Bundle/ChillMainBundle/Controller/PasswordController.php
Normal file
336
src/Bundle/ChillMainBundle/Controller/PasswordController.php
Normal file
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Chill\MainBundle\Form\UserPasswordType;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Validator\Constraints\Callback;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Chill\MainBundle\Security\PasswordRecover\RecoverPasswordHelper;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Chill\MainBundle\Security\PasswordRecover\TokenManager;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverEvent;
|
||||
use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverVoter;
|
||||
|
||||
/**
|
||||
* Class PasswordController
|
||||
*
|
||||
* @package Chill\MainBundle\Controller
|
||||
*/
|
||||
class PasswordController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @var UserPasswordEncoderInterface
|
||||
*/
|
||||
protected $passwordEncoder;
|
||||
|
||||
/**
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $chillLogger;
|
||||
|
||||
/**
|
||||
* @var RecoverPasswordHelper
|
||||
*/
|
||||
protected $recoverPasswordHelper;
|
||||
|
||||
/**
|
||||
* @var TokenManager
|
||||
*/
|
||||
protected $tokenManager;
|
||||
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
protected $eventDispatcher;
|
||||
|
||||
/**
|
||||
* PasswordController constructor.
|
||||
*
|
||||
* @param LoggerInterface $chillLogger
|
||||
* @param UserPasswordEncoderInterface $passwordEncoder
|
||||
* @param RecoverPasswordHelper $recoverPasswordHelper
|
||||
* @param TokenManager $tokenManager
|
||||
* @param TranslatorInterface $translator
|
||||
* @param EventDispatcherInterface $eventDispatcher
|
||||
*/
|
||||
public function __construct(
|
||||
LoggerInterface $chillLogger,
|
||||
UserPasswordEncoderInterface $passwordEncoder,
|
||||
RecoverPasswordHelper $recoverPasswordHelper,
|
||||
TokenManager $tokenManager,
|
||||
TranslatorInterface $translator,
|
||||
EventDispatcherInterface $eventDispatcher
|
||||
) {
|
||||
$this->chillLogger = $chillLogger;
|
||||
$this->passwordEncoder = $passwordEncoder;
|
||||
$this->translator = $translator;
|
||||
$this->tokenManager = $tokenManager;
|
||||
$this->recoverPasswordHelper = $recoverPasswordHelper;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function UserPasswordAction(Request $request)
|
||||
{
|
||||
// get authentified user
|
||||
$user = $this->getUser();
|
||||
|
||||
// create a form for password_encoder
|
||||
$form = $this->passwordForm($user);
|
||||
|
||||
// process the form
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$password = $form->get('new_password')->getData();
|
||||
|
||||
// logging for prod
|
||||
$this
|
||||
->chillLogger
|
||||
->notice(
|
||||
'update password for an user',
|
||||
array(
|
||||
'method' => $request->getMethod(),
|
||||
'user' => $user->getUsername()
|
||||
)
|
||||
);
|
||||
|
||||
$user->setPassword($this->passwordEncoder->encodePassword($user, $password));
|
||||
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$em->flush();
|
||||
|
||||
$this->addFlash('success', $this->translator->trans('Password successfully updated!'));
|
||||
|
||||
return $this->redirectToRoute('change_my_password');
|
||||
|
||||
}
|
||||
|
||||
// render into a template
|
||||
return $this->render('@ChillMain/Password/password.html.twig', array(
|
||||
'form' => $form->createView()
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return \Symfony\Component\Form\Form
|
||||
*/
|
||||
private function passwordForm(User $user)
|
||||
{
|
||||
return $this
|
||||
->createForm(
|
||||
UserPasswordType::class,
|
||||
[],
|
||||
[ 'user' => $user ]
|
||||
)
|
||||
->add('submit', SubmitType::class, array('label' => 'Change password'))
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
||||
*/
|
||||
public function recoverAction(Request $request)
|
||||
{
|
||||
if (FALSE === $this->isGranted(PasswordRecoverVoter::ASK_TOKEN)) {
|
||||
return (new Response($this->translator->trans("You are not allowed "
|
||||
. "to try to recover password, due to mitigating possible "
|
||||
. "attack. Try to contact your system administrator"), Response::HTTP_FORBIDDEN));
|
||||
}
|
||||
|
||||
$query = $request->query;
|
||||
$username = $query->get(TokenManager::USERNAME_CANONICAL);
|
||||
$hash = $query->getAlnum(TokenManager::HASH);
|
||||
$token = $query->getAlnum(TokenManager::TOKEN);
|
||||
$timestamp = $query->getInt(TokenManager::TIMESTAMP);
|
||||
$user = $this->getDoctrine()->getRepository(User::class)
|
||||
->findOneByUsernameCanonical($username);
|
||||
|
||||
if (NULL === $user) {
|
||||
$this->eventDispatcher->dispatch(PasswordRecoverEvent::INVALID_TOKEN,
|
||||
new PasswordRecoverEvent($token, null, $request->getClientIp()));
|
||||
|
||||
throw $this->createNotFoundException(sprintf('User %s not found', $username));
|
||||
}
|
||||
|
||||
if (TRUE !== $this->tokenManager->verify($hash, $token, $user, $timestamp)) {
|
||||
$this->eventDispatcher->dispatch(PasswordRecoverEvent::INVALID_TOKEN,
|
||||
new PasswordRecoverEvent($token, $user, $request->getClientIp()));
|
||||
|
||||
return new Response("Invalid token", Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
$form = $this->passwordForm($user);
|
||||
$form->remove('actual_password');
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$password = $form->get('new_password')->getData();
|
||||
$user->setPassword($this->passwordEncoder->encodePassword($user, $password));
|
||||
// logging for prod
|
||||
$this
|
||||
->chillLogger
|
||||
->notice(
|
||||
'setting new password for user',
|
||||
array(
|
||||
'user' => $user->getUsername()
|
||||
)
|
||||
);
|
||||
|
||||
$this->getDoctrine()->getManager()->flush();
|
||||
|
||||
return $this->redirectToRoute('password_request_recover_changed');
|
||||
}
|
||||
|
||||
return $this->render('@ChillMain/Password/recover_password_form.html.twig', [
|
||||
'form' => $form->createView()
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Response
|
||||
*/
|
||||
public function changeConfirmedAction()
|
||||
{
|
||||
return $this->render('@ChillMain/Password/recover_password_changed.html.twig');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
||||
* @throws \Doctrine\ORM\NoResultException
|
||||
* @throws \Doctrine\ORM\NonUniqueResultException
|
||||
*/
|
||||
public function requestRecoverAction(Request $request)
|
||||
{
|
||||
if (FALSE === $this->isGranted(PasswordRecoverVoter::ASK_TOKEN)) {
|
||||
return (new Response($this->translator->trans("You are not allowed "
|
||||
. "to try to recover password, due to mitigating possible "
|
||||
. "attack. Try to contact your system administrator"), Response::HTTP_FORBIDDEN));
|
||||
}
|
||||
|
||||
$form = $this->requestRecoverForm();
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
/* @var $qb \Doctrine\ORM\QueryBuilder */
|
||||
$qb = $this->getDoctrine()->getManager()
|
||||
->createQueryBuilder();
|
||||
$qb->select('u')
|
||||
->from(User::class, 'u')
|
||||
->where($qb->expr()->eq('u.usernameCanonical', 'UNACCENT(LOWER(:pattern))'))
|
||||
->orWhere($qb->expr()->eq('u.emailCanonical', 'UNACCENT(LOWER(:pattern))' ))
|
||||
->setParameter('pattern', $form->get('username_or_email')->getData())
|
||||
;
|
||||
|
||||
$user = $qb->getQuery()->getSingleResult();
|
||||
|
||||
if (empty($user->getEmail())) {
|
||||
$this->addFlash('error', $this->translator->trans('This account does not have an email address. '
|
||||
. 'Please ask your administrator to renew your password.'));
|
||||
} else {
|
||||
if (FALSE === $this->isGranted(PasswordRecoverVoter::ASK_TOKEN, $user)) {
|
||||
return (new Response($this->translator->trans("You are not allowed "
|
||||
. "to try to recover password, due to mitigating possible "
|
||||
. "attack. Try to contact your system administrator"), Response::HTTP_FORBIDDEN));
|
||||
}
|
||||
|
||||
$this->recoverPasswordHelper->sendRecoverEmail($user,
|
||||
(new \DateTimeImmutable('now'))->add(new \DateInterval('PT30M')));
|
||||
|
||||
// logging for prod
|
||||
$this
|
||||
->chillLogger
|
||||
->notice(
|
||||
'Sending an email for password recovering',
|
||||
array(
|
||||
'user' => $user->getUsername()
|
||||
)
|
||||
);
|
||||
|
||||
$this->eventDispatcher->dispatch(
|
||||
PasswordRecoverEvent::ASK_TOKEN_SUCCESS,
|
||||
new PasswordRecoverEvent(null, $user, $request->getClientIp())
|
||||
);
|
||||
|
||||
return $this->redirectToRoute('password_request_recover_confirm');
|
||||
}
|
||||
} elseif ($form->isSubmitted() && FALSE === $form->isValid()) {
|
||||
$this->eventDispatcher->dispatch(
|
||||
PasswordRecoverEvent::ASK_TOKEN_INVALID_FORM,
|
||||
new PasswordRecoverEvent(null, null, $request->getClientIp())
|
||||
);
|
||||
}
|
||||
|
||||
return $this->render('@ChillMain/Password/request_recover_password.html.twig', [
|
||||
'form' => $form->createView()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Response
|
||||
*/
|
||||
public function requestRecoverConfirmAction()
|
||||
{
|
||||
return $this->render('@ChillMain/Password/request_recover_password_confirm.html.twig');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
protected function requestRecoverForm()
|
||||
{
|
||||
$builder = $this->createFormBuilder();
|
||||
$builder
|
||||
->add('username_or_email', TextType::class, [
|
||||
'label' => 'Username or email',
|
||||
'constraints' => [
|
||||
new Callback([
|
||||
'callback' => function($pattern, ExecutionContextInterface $context, $payload) {
|
||||
$qb = $this->getDoctrine()->getManager()
|
||||
->createQueryBuilder();
|
||||
$qb->select('COUNT(u)')
|
||||
->from(User::class, 'u')
|
||||
->where($qb->expr()->eq('u.usernameCanonical', 'UNACCENT(LOWER(:pattern))'))
|
||||
->orWhere($qb->expr()->eq('u.emailCanonical', 'UNACCENT(LOWER(:pattern))' ))
|
||||
->setParameter('pattern', $pattern)
|
||||
;
|
||||
|
||||
if ((int) $qb->getQuery()->getSingleScalarResult() !== 1) {
|
||||
$context->addViolation('This username or email does not exists');
|
||||
}
|
||||
}
|
||||
])
|
||||
]
|
||||
])
|
||||
->add('submit', SubmitType::class, [
|
||||
'label' => 'Request recover'
|
||||
]);
|
||||
|
||||
return $builder->getForm();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user