<?php
namespace App\Controller;
use App\Domain\Password\PasswordChange;
use App\Entity\AppUser;
use App\Enum\Errors;
use App\Enum\Events;
use App\Events\SendPasswordLinkEvent;
use App\Exception\PasswordException;
use App\Form\PasswordChangeEmailType;
use App\Form\PasswordChangeType;
use App\Services\PasswordService;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Swift_Mailer;
use Swift_Message;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
/**
* Class SecurityController
* @package App\Controller
*/
class SecurityController extends AbstractController
{
/** @var PasswordService */
private $passwordService;
/**
* SecurityController constructor.
* @param PasswordService $passwordService
*/
public function __construct(PasswordService $passwordService)
{
$this->passwordService = $passwordService;
}
/**
* @Route("/", name="app_root")
*
* @param AuthenticationUtils $authenticationUtils
* @return Response
*/
public function redirectToLogin(AuthenticationUtils $authenticationUtils): Response
{
return $this->redirectToRoute('app_login');
}
/**
* @Route("/login", name="app_login")
*
* @param AuthenticationUtils $authenticationUtils
* @return Response
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout()
{
}
/**
* @IsGranted("ROLE_EDITOR")
*
* @Route("/password/send/email/{id}", name="app_send_password_email", methods="POST|GET")
*
* @param Request $request
* @param AppUser $appUser
* @param EventDispatcherInterface $dispatcher
* @return RedirectResponse
*/
public function sendPasswordReset(Request $request, AppUser $appUser, EventDispatcherInterface $dispatcher)
{
try {
$passwordRequest = $this->passwordService->createPasswordRequest($appUser);
$dispatcher->dispatch(new SendPasswordLinkEvent($passwordRequest), Events::SEND_PASSWORD_LINK_EMAIL);
$this->addFlash(
'info',
sprintf('Es wird in Kürze ein Passwort-Link an %s verschickt',
$appUser->getFirstname() . ' ' . $appUser->getLastname())
);
} catch (PasswordException $ex) {
$this->addFlash('error', 'Email kann nicht verschickt werden');
}
return $this->redirect($request->headers->get('referer'));
}
/**
* @Route("/password/reset", name="app_reset_password", methods="POST|GET")
*
* @param Request $request
* @param EventDispatcherInterface $dispatcher
* @return Response
*/
public function resetPassword(Request $request, EventDispatcherInterface $dispatcher)
{
$form = $this->createForm(PasswordChangeEmailType::class, new PasswordChange());
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
/** @var PasswordChange $passwordChange */
$passwordChange = $form->getData();
$passwordRequest = $this->passwordService->createPasswordRequestByEmail($passwordChange->getEmail());
$dispatcher->dispatch(new SendPasswordLinkEvent($passwordRequest), Events::SEND_PASSWORD_LINK_EMAIL);
$this->addFlash('success', 'Sie erhalten in Kürze eine Email');
} catch (PasswordException $ex) {
if ($ex->getCode() === Errors::UNKONWN_USER) {
$this->addFlash('error', 'Email ist unbekannt');
} else {
$this->addFlash('error', $ex->getMessage());
}
}
}
return $this->render('security/reset.password.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/password/{token}", name="app_change_password", methods="POST|GET")
*
* @param Request $request
* @param $token
* @param PasswordService $passwordService
* @return Response
*/
public function changePassword(Request $request, $token, PasswordService $passwordService)
{
$form = null;
try {
$passwordChange = $passwordService->checkPasswordResetRequest($token);
$form = $this->createForm(PasswordChangeType::class, $passwordChange, [
'method' => 'POST',
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($this->passwordService->changePassword($form->getData())) {
$this->addFlash('success', 'Passwort wurde erfolgreich geändert');
}
} elseif ($form->isSubmitted() && !$form->isValid()) {
$this->passwordService->increaseTryCount($form->getData());
}
} catch (PasswordException $ex) {
if ($ex->getCode() === Errors::TO_MANY_TRYS_TO_CHANGE_PASSWORD) {
$this->addFlash('error', 'Zu viele Versuche. Token ist jetzt ungültig');
} else {
$this->addFlash('error', 'Token ist ungültig');
}
}
$view = $form ? $form->createView() : null;
return $this->render('security/change.password.html.twig', [
'form' => $view,
]);
}
/**
* @param Request $request
* @param string $email
* @param Swift_Mailer $mailer
* @return Response
*
* @Route("/send/test/mail/{email}", name="send_test_mail", methods="POST|GET")
*/
public function sendMail(Request $request, string $email, Swift_Mailer $mailer)
{
$message = (new Swift_Message('Hello Email'))
->setFrom('info@trainee.mdm.dom')
->setTo($email)
->setBody('test mail',
'text/plain'
);
$responseMessage = 'Email konnte nicht gesendt werden';
$state = Response::HTTP_INTERNAL_SERVER_ERROR;
if ($mailer->send($message)) {
$responseMessage = 'Email wurde an: ' . $email . ' gesendet';
$state = Response::HTTP_OK;
}
return new Response($responseMessage, $state);
}
}