<?php
namespace App\Controller\User;
use App\Entity\User\User;
use App\Form\User\InscriptionType;
use App\Repository\Fiche\FicheBatimentRepository;
use App\Repository\User\UserRepository;
use App\Security\User\FormLoginAuthenticator;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use App\Form\User\LoginType;
use App\Form\User\MotDePasseOublieType;
/**
* @Route("/", name="user_security_")
*/
class SecurityController extends AbstractController
{
const MSG_ERROR_MAIL_INEXISTANT = 'Cette adresse mail n\'est pas enregistrée dans la base de données.';
const MSG_PASSWORD_CHANGED = 'Votre mot de passe a été modifié et envoyé à votre adresse mail.';
const MSG_ACTIVATION_SUCCESS = 'Votre compte a bien été activé.';
const MSG_ACTIVATION_ERROR = 'L\'activation n\'a pas pû être effectuée.';
private $pathAuthenticationHome;
public function __construct(ParameterBagInterface $theParameterBag)
{
$this->pathAuthenticationHome = 'postConnexion';
}
/**
* @Route("/login", name="login")
*/
public function login(
AuthenticationUtils $authenticationUtils,
Request $theRequest,
FicheBatimentRepository $theFicheBatimentRepository
): Response
{
if ($this->getUser() != null) {
return $this->redirectToRoute($this->pathAuthenticationHome);
}
$theEM = $this->getDoctrine()->getManager();
// retrouver une erreur d'authentification s'il y en a une
$error = $authenticationUtils->getLastAuthenticationError();
// retrouver le dernier identifiant de connexion utilisé
$lastUsername = $authenticationUtils->getLastUsername();
$theForm = $this->createForm(LoginType::class, null, array('username' => $lastUsername));
$theForm->handleRequest($theRequest);
if ($theForm->isSubmitted()) {
}
if ($error != null) {
$theForm->addError(new FormError($error->getMessageKey()));
}
return $this->render('user/security/login.html.twig', [
'theForm' => $theForm->createView(),
'last_username' => $lastUsername,
]
);
}
/**
* @Route("/activation/{activationToken}", name="activation")
*/
public function activation(UserRepository $theUserRepository, ManagerRegistry $theManagerRegistry , $activationToken)
{
$theUser = $theUserRepository->findByActivationToken($activationToken);
if ($theUser != null) {
$theUser->setIsEnabled(true);
$theUser->setActivationToken(null);
$theManagerRegistry->getManager()->flush();
$this->addFlash('success', self::MSG_ACTIVATION_SUCCESS);
} else {
$this->addFlash('danger', self::MSG_ACTIVATION_ERROR);
}
return $this->redirectToRoute('user_security_login');
}
/**
* @Route("/inscription", name="inscription")
*/
public function inscription(
Request $theRequest,
ManagerRegistry $theManagerRegistry,
UserPasswordHasherInterface $theUserPasswordHasherInterface,
TokenStorageInterface $theTokenStorage,
FormLoginAuthenticator $theFormLoginAuthenticator,
MailerInterface $theMailer
): Response
{
if ($this->getUser() != null) {
return $this->redirectToRoute($this->pathAuthenticationHome);
}
$theUser = new User();
$theForm = $this->createForm(InscriptionType::class, $theUser);
$theForm->handleRequest($theRequest);
if ($theForm->isSubmitted() && $theForm->isValid()) {
$theUser->setPassword(
$theUserPasswordHasherInterface->hashPassword($theUser, $theUser->getPlainPassword())
);
$theUser->setActivationToken(bin2hex(random_bytes(16)));
$theUser->setRolePrincipal('ROLE_UTILISATEUR');
$theEM = $theManagerRegistry->getManager();
$theEM->persist($theUser);
$theEM->flush();
$theEmail = $this->getTheEmailInscription($theUser);
$theMailer->send($theEmail);
$theToken = new UsernamePasswordToken($theUser, null, 'main', $theUser->getRoles());
$theTokenStorage->setToken($theToken);
$theRequest->getSession()->set('_security_main', serialize($theToken));
return $theFormLoginAuthenticator->onAuthenticationSuccess($theRequest, $theToken, 'app_user_provider');
} else {
$theResponse = $this->render('user/security/inscription.html.twig', [
'theForm' => $theForm->createView(),
]
);
}
return $theResponse;
}
/**
* @param Request $theRequest
* @param UserRepository $theUserRepository
* @return Response
*
* @Route("/mot-de-passe-oublie", name="mot_de_passe_oublie")
*/
public function motDePasseOublie(
Request $theRequest,
UserRepository $theUserRepository,
UserPasswordHasherInterface $theUserPasswordHasherInterface,
MailerInterface $theMailer,
ManagerRegistry $theManagerRegistry
)
{
$theForm = $this->createForm(MotDePasseOublieType::class);
$theForm->handleRequest($theRequest);
if ($theForm->isSubmitted() && $theForm->isValid()) {
$email = $theForm->get('email')->getData();
$theUser = $theUserRepository->findOneByEmail($email);
if ($theUser == null) {
$theForm->addError(new FormError(self::MSG_ERROR_MAIL_INEXISTANT));
} else {
$theUser->setPlainPassword(bin2hex(random_bytes(8)));
$theEmail = $this->getTheEmailMotDePasseOublie($theUser);
$theMailer->send($theEmail);
$encodedPassword = $theUserPasswordHasherInterface->hashPassword($theUser, $theUser->getPlainPassword());
$theUser->setPassword($encodedPassword);
$theManagerRegistry->getManager()->flush();
$this->addFlash('success', self::MSG_PASSWORD_CHANGED);
}
}
return $this->render('user/security/mot-de-passe-oublie.html.twig', array(
'theForm' => $theForm->createView()
));
}
private function getTheEmailMotDePasseOublie(User $theUser)
{
$theEmail = new Email();
$theEmail
->subject('SOBRO - Nouveau mot de passe')
->text($this->renderView('user/security/mot-de-passe-oublie.txt.twig', array(
'theUser' => $theUser
)))
->addTo($theUser->getEmail())
->addFrom('admin@sobro.fr');
return $theEmail;
}
private function getTheEmailInscription(User $theUser)
{
$theEmail = new Email();
$theEmail
->subject('SOBRO - Inscription')
->text($this->renderView('user/security/inscription.txt.twig', array(
'theUser' => $theUser
)))
->addTo($theUser->getEmail())
->addCc('admin@sobro.fr')
->addFrom('admin@sobro.fr');
return $theEmail;
}
/**
* @Route("/logout", name="logout")
*/
public function logout(Request $theRequest): void
{
throw new \Exception('This should never be reached!');
}
}