<?php
namespace Whater\UI\WebBundle\Controller\Security;
use Whater\UI\WebBundle\Controller\AbstractBusController;
use Whater\Infrastructure\SecurityBundle\Form\Type\LoginType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Whater\Application\UseCase\Security\CommandRequest\LoginCommand;
use Whater\Application\UseCase\Security\CommandRequest\ForgotPasswordCommand;
use Whater\Infrastructure\SecurityBundle\Form\Type\ForgotPaswordType;
use Whater\Infrastructure\SecurityBundle\Form\Type\ResetPaswordType;
use Whater\Application\UseCase\Security\CommandRequest\ResetPasswordCommand;
use Whater\Application\UseCase\Security\CommandRequest\SignupCommand;
use Whater\Domain\User\Exception\UserNotFoundException;
use Whater\Domain\User\Exception\ResetTokenExpiredException;
use Whater\Application\UseCase\User\CommandRequest\GetUserByUsernameCommand;
use Whater\Domain\Security\Exception\InvalidUsernameException;
use Whater\Infrastructure\SecurityBundle\Form\Type\SignupType;
use Whater\Infrastructure\SecurityBundle\Security\Model\Auth;
/**
* @Route("")
*/
class SecurityController extends AbstractBusController
{
/**
* @Route("/login", name="web_login", defaults={"_format" = "html"})
*/
public function loginAction(Request $request)
{
// If user is authenticated redirect to user dashboard
if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return new RedirectResponse($this->router()->generate('web_app_user_dashboard'));
}
$targetPath = $request->get('_target_path');
$form = $this->getFormFactory()->create(LoginType::class, LoginCommand::convertToDTO(), array(
'action' => $this->router()->generate('web_login_check', array('_target_path' => $targetPath), true),
'method' => 'POST',
'csrf_protection' => true
));
$session = $request->getSession();
if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(Security::AUTHENTICATION_ERROR);
} elseif (null !== $session && $session->has(Security::AUTHENTICATION_ERROR)) {
$error = $session->get(Security::AUTHENTICATION_ERROR);
$session->remove(Security::AUTHENTICATION_ERROR);
} else {
$error = null;
}
if (!$error instanceof AuthenticationException) {
$error = null;
}
if (!empty($error)) {
$this->setFlash('error', $this->translator()->trans($error->getMessageKey(), $error->getMessageData(), 'security'));
}
return $this->render('Security/login.html.twig', array('form' => $form->createView()));
}
/**
* @Route("/login_check", name="web_login_check", defaults={"_format" = "html"})
*/
public function loginCheckAction(Request $request)
{
throw new \RuntimeException('You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.');
}
/**
* @Route("/logout", name="web_logout", defaults={"_format" = "html"})
*/
public function logoutAction()
{
throw new \RuntimeException('You must activate the logout in your security firewall configuration.');
}
/**
* @Route("/forgot_password", name="web_forgot_password", defaults={"_format" = "html"})
*/
public function forgotPasswordAction(Request $request)
{
// If user is authenticated redirect to user dashboard
if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return new RedirectResponse($this->router()->generate('web_init'));
}
$form = $this->getFormFactory()->create(ForgotPaswordType::class, ForgotPasswordCommand::convertToDTO(), array(
'action' => $this->router()->generate('web_forgot_password', array(), true),
'method' => 'POST',
'csrf_protection' => true
));
if ('POST' === $request->getMethod()) {
$form->handleRequest($request);
$error = '';
if ($form->isSubmitted() && $form->isValid()) {
try {
$this->handle(ForgotPasswordCommand::fromDTO($form->getData()));
$this->setFlash('success', $this->translator()->trans('web.security.forgot_password.success'));
} catch (UserNotFoundException $e) {
$this->setFlash('error', $this->translator()->trans('web.security.forgot_password.user_not_found'));
}
} else {
$this->setFlash('error', $this->translator()->trans('web.security.forgot_password.error'));
}
}
return $this->render(
'Security/forgot_password.html.twig',
array('form' => $form->createView())
);
}
/**
* @Route("/reset_password/{resetToken}", name="web_reset_password", defaults={"_format" = "html"})
*/
public function forgotPasswordLandingAction(Request $request, string $resetToken)
{
// If user is authenticated redirect to user dashboard
if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return new RedirectResponse($this->router()->generate('web_init'));
}
$form = $this->getFormFactory()->create(ResetPaswordType::class, ResetPasswordCommand::convertToDTO(), array(
'action' => $this->router()->generate(
'web_reset_password',
array(
'resetToken' => $resetToken
),
true
),
'method' => 'POST',
'csrf_protection' => true,
'resetToken' => $resetToken
));
if ('POST' === $request->getMethod()) {
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$username = $this->handle(ResetPasswordCommand::fromDTO($form->getData()));
$user = $this->handle(new GetUserByUsernameCommand($username));
//Autenticate and go to dashboard
$token = new UsernamePasswordToken(new Auth($user), null, "main", $user->rolesAsArray());
$this->tokenStorage()->setToken($token); //now the user is logged in
$this->session()->set('_security_main', serialize($token));
return new RedirectResponse($this->router()->generate('web_init'));
} catch (ResetTokenExpiredException $e) {
$this->setFlash('error', $this->translator()->trans('web.security.reset_password.invalid_token'));
} catch (UserNotFoundException $e) {
$this->setFlash('error', $this->translator()->trans('web.security.reset_password.user_not_found'));
}
} else {
$this->setFlash('error', $this->translator()->trans('web.security.reset_password.error'));
}
}
return $this->render(
'Security/reset_password.html.twig',
array('form' => $form->createView())
);
}
/**
* @Route("/signup", name="web_signup", defaults={"_format" = "html"})
*/
public function signupUserAction(Request $request)
{
if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return new RedirectResponse($this->router()->generate('web_init'));
}
$form = $this->getFormFactory()->create(SignupType::class, SignupCommand::convertToDTO(), array(
'method' => 'POST',
'csrf_protection' => true
));
if ('POST' === $request->getMethod()) {
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$user = $this->handle(SignupCommand::fromDTO($form->getData()));
//Autenticate and go to dashboard
$roles = ['ROLE_USER'];
foreach ($user->roles() as $role) {
$roles[] = $role->roleType();
}
$token = new UsernamePasswordToken(new Auth($user), null, "main", $roles);
$this->tokenStorage()->setToken($token); //now the user is logged in
$this->session()->set('_security_main', serialize($token));
$loginEvent = new InteractiveLoginEvent($request, $token);
$this->eventDispatcher()->dispatch($loginEvent, SecurityEvents::INTERACTIVE_LOGIN);
$this->setFlash('info', $this->translator()->trans('web.security.signup.success'));
return new RedirectResponse($this->router()->generate('web_app_whater_map'));
} catch (InvalidUsernameException $e) {
$this->setFlash('error', $this->translator()->trans('web.security.signup.invalid_username'));
} catch (\Exception $e) {
$this->logger()->error($e->getMessage());
$this->setFlash('error', $this->translator()->trans('web.security.signup.exception'));
}
} else {
$this->setFlash('error', $this->translator()->trans('web.security.signup.error'));
}
}
$referralCode = $request->get('referral_code');
$response = $this->render(
'Security/signup.html.twig',
array(
'form' => $form->createView(),
'referralCode' => $referralCode
)
);
return $response;
}
}