<?php
/**
* Created by PhpStorm.
* User: ricar
* Date: 06/08/2018
* Time: 09:43
*/
namespace App\Controller;
use App\Entity\Usuario;
use App\Form\ChangeEmailConfirmType;
use App\Form\ChangeEmailType;
use App\Form\ChangePasswordType;
use App\Form\ForgotChangeFormType;
use App\Form\ForgotEmailFormType;
use App\Form\ForgotFormType;
use App\Form\LoginFormType;
use App\Form\Model\ChangePassword;
use App\Form\PerfilType;
use App\Notification\UsuarioEmailAlterado;
use App\Notification\UsuarioEsqueciSenha;
use App\Notification\UsuarioSenhaAlterada;
use App\Notification\UsuarioTrocarEmail;
use App\Repository\ProficienciaRepository;
use App\Repository\UsuarioRepository;
use App\Service\Notifier;
use App\Validator\BrasilCpfValidator;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\Finder\Exception\AccessDeniedException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class MainController extends AppController
{
/**
* @Route("/", name="homepage")
* @IsGranted(Usuario::IS_AUTHENTICATED)
*/
public function homepageAction(): Response
{
return $this->render('main/homepage.html.twig');
}
/**
* @Route("/login", name="login")
* @IsGranted(Usuario::PUBLIC_ACCESS)
*/
public function loginAction(AuthenticationUtils $authenticationUtils): Response
{
if ($this->isGranted(Usuario::IS_AUTHENTICATED)) {
return $this->redirectToRoute('homepage');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$form = $this->createForm(LoginFormType::class, [
'_username' => $lastUsername,
]);
return $this->render(
'main/login.html.twig',
array(
'form' => $form->createView(),
'error' => $error,
)
);
}
/**
* @Route("/esqueci", name="forgot")
* @IsGranted(Usuario::PUBLIC_ACCESS)
*/
public function forgotAction(Request $request, Notifier $notifier, UsuarioRepository $repository, EntityManagerInterface $em): Response
{
if ($this->isGranted(Usuario::IS_AUTHENTICATED)) {
return $this->redirectToRoute('change_pass');
}
$form = $this->createForm(ForgotFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$formData = $form->getData();
$usuario = $repository->findOneBy(['email' => $formData['email']]);
if ($usuario instanceof Usuario) {
if (!$usuario->getAtivo()) {
$this->addFlash('warning', 'Este usuário encontra-se bloqueado no sistema!');
return $this->redirectToRoute('forgot');
}
$token = $usuario->generateResetToken(\DateInterval::createFromDateString('1 hour'));
$notifier->prepareAndSend(new UsuarioEsqueciSenha($usuario, $token));
$em->persist($usuario);
$em->flush();
}
$this->addFlash('success', 'Email para alteração de senha enviado!');
return $this->redirectToRoute('login');
}
return $this->render('main/forgot.html.twig', [
'form' => $form->createView()
]);
}
/**
* @Route("/esqueci/{resetToken}", name="forgot_change")
* @IsGranted(Usuario::PUBLIC_ACCESS)
*/
public function forgotChangeAction(Usuario $usuario, Request $request, Notifier $notifier, EntityManagerInterface $em): Response
{
if ($usuario->isResetTokenValid()) {
$form = $this->createForm(ForgotChangeFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$formData = $form->getData();
$usuario->setPlainPassword($formData['senha']);
$usuario->clearResetToken();
$notifier->prepareAndSend(new UsuarioSenhaAlterada($usuario));
$em->persist($usuario);
$em->flush();
$this->addFlash('success', 'Senha alterada!');
return $this->redirectToRoute('login');
}
return $this->render('main/forgot_change.html.twig', [
'form' => $form->createView()
]);
} else {
throw $this->createNotFoundException('Token não encontrado!');
}
}
/**
* @Route("/esqueci-email", name="forgot_email")
* @IsGranted(Usuario::PUBLIC_ACCESS)
*/
public function forgotEmailAction(Request $request, Notifier $notifier, UsuarioRepository $repository, EntityManagerInterface $em): Response
{
if ($this->isGranted(Usuario::IS_AUTHENTICATED)) {
return $this->redirectToRoute('change_email');
}
$form = $this->createForm(ForgotEmailFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$formData = $form->getData();
$cpf = BrasilCpfValidator::normalize($formData['cpf']);
$usuario = $repository->findOneBy(['cpf' => $cpf]);
if ($usuario instanceof Usuario) {
if (!$usuario->getAtivo()) {
$this->addFlash('warning', 'Este usuário encontra-se bloqueado no sistema!');
return $this->redirectToRoute('forgot');
}
$token = $usuario->generateResetToken(\DateInterval::createFromDateString('1 hour'));
$notifier->prepareAndSend(new UsuarioEsqueciSenha($usuario, $token));
$em->persist($usuario);
$em->flush();
$email = $usuario->getObfuscatedEmail();
$this->addFlash('success', "Email para alteração de senha enviado para $email!");
} elseif ($form->isSubmitted()) {
$this->addFlash('error', "Nenhum usuário localizado com o CPF informado!");
}
}
return $this->render('main/forgot_email.html.twig', [
'form' => $form->createView()
]);
}
/**
* @Route("/trocar-senha", name="change_pass")
* @IsGranted(Usuario::IS_AUTHENTICATED_FULLY)
*/
public function trocarSenhaAction(Request $request, EntityManagerInterface $em, Notifier $notifier): Response
{
/** @var Usuario $usuario */
$usuario = $this->getUsuario();
if (!is_object($usuario) || !$usuario instanceof UserInterface) {
throw new AccessDeniedException('Você não tem permissão para estar aqui...');
}
$form = $this->createForm(ChangePasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var ChangePassword $formData */
$formData = $form->getData();
$usuario->setPlainPassword($formData->getNewPassword());
$usuario->clearResetToken();
$notifier->prepareAndSend(new UsuarioSenhaAlterada($usuario));
$em->persist($usuario);
$em->flush();
$this->addFlash('success', 'Senha alterada com sucesso!');
return $this->redirectToRoute('change_pass');
}
return $this->render('main/change_pass.html.twig', [
'trocarSenhaForm' => $form->createView()
]);
}
/**
* @Route("/trocar-email", name="change_email")
* @IsGranted(Usuario::IS_AUTHENTICATED_FULLY)
*/
public function changeEmailAction(Request $request, Notifier $notifier, UsuarioRepository $repository, EntityManagerInterface $em): Response
{
/** @var Usuario $usuario */
$usuario = $this->getUsuario();
if (!is_object($usuario) || !$usuario instanceof UserInterface) {
throw new AccessDeniedException('Você não tem permissão para estar aqui...');
}
$form = $this->createForm(ChangeEmailType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$formData = $form->getData();
$token = $usuario->generateResetToken(\DateInterval::createFromDateString('1 hour'));
$notifier->prepareAndSend(new UsuarioTrocarEmail($usuario, $token, $formData->getEmail()));
$em->persist($usuario);
$em->flush();
$this->addFlash('success', 'Email para alteração de e-mail enviado!');
return $this->redirectToRoute('change_email');
}
return $this->render('main/change_email.html.twig', [
'form' => $form->createView(),
'confirmed' => false,
]);
}
/**
* @Route("/trocar-email/{newEmail}/{resetToken}", name="confirm_email_change")
* @IsGranted(Usuario::PUBLIC_ACCESS)
*/
public function confirmEmailChangeAction($newEmail, Usuario $usuario, Request $request, Notifier $notifier, EntityManagerInterface $em): Response
{
if ($usuario->isResetTokenValid() && $newEmail) {
if ($this->getUsuario()->getId() != $usuario->getId()) {
throw new AccessDeniedException('Você não tem permissão para estar aqui...');
}
$oldEmail = $usuario->getEmail();
$form = $this->createForm(ChangeEmailConfirmType::class, [
'old_email' => $oldEmail,
'new_email' => $newEmail,
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$usuario->setEmail($newEmail);
$usuario->clearResetToken();
$notifier->prepareAndSend(new UsuarioEmailAlterado($usuario, $oldEmail));
$em->persist($usuario);
$em->flush();
$this->addFlash('success', 'E-mail alterado!');
return $this->redirectToRoute('perfil');
}
return $this->render('main/change_email.html.twig', [
'form' => $form->createView(),
'confirmed' => true,
]);
} else {
throw $this->createNotFoundException('Token não encontrado!');
}
}
/**
* @Route("/perfil", name="perfil")
* @IsGranted(Usuario::IS_AUTHENTICATED_FULLY)
*/
public function perfilAction(Request $request, EntityManagerInterface $em, ProficienciaRepository $proficienciaRepository): Response
{
/** @var Usuario $usuario */
$usuario = $this->getUsuario();
if (!is_object($usuario) || !$usuario instanceof UserInterface) {
throw new AccessDeniedException('Você não tem permissão para estar aqui...');
}
$form = $this->createForm(PerfilType::class, $usuario, [
'usuario' => $usuario,
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var Usuario $usuario */
$usuario = $form->getData();
$em->persist($usuario);
$em->flush();
$this->addFlash('success', 'Perfil atualizado com sucesso!');
return $this->redirectToRoute('perfil');
}
$proficiencias = $proficienciaRepository->findBy([
'usuario' => $usuario
]);
return $this->render('main/perfil.html.twig', [
'form' => $form->createView(),
'proficiencias' => $proficiencias
]);
}
/**
* @Route("/logout", name="logout")
* @IsGranted(Usuario::PUBLIC_ACCESS)
*/
public function logoutAction(): Response
{
throw new \Exception('this should not be reached!');
}
}