<?php
namespace App\Controller;
use App\Entity\Association\Adherent;
use App\Entity\Parametre\Utilisateur;
use App\Form\Authenticator\AdherentActivateAccountType;
use App\Form\Authenticator\ForgotPasswordType;
use App\Form\Authenticator\LoginAuthenticatorType;
use App\Form\Authenticator\RenewPasswordType;
use App\Helper\MailerHelper;
use App\Helper\UserHelper;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
class AuthenticationController extends AbstractAppController {
/**
* Reset the password.
* @Route("/adherent/active-account/{token}", name="adherent_active_account", defaults={"token": null})
*/
public function activeAccountAdherent(Request $request, TranslatorInterface $translator, UserPasswordEncoderInterface $passwordEncoder, $token = null) {
// If user was already connected, redirect to home page.
if ($this->getUser() !== null || $this->getAppParameter("ASSOCIATION_EXTRANET_ENABLED") !== "1") {
return $this->redirectToRoute("app");
}
// If a token was defined.
if ($token !== null) {
// Create form.
$form = $this->createForm(RenewPasswordType::class);
$form->handleRequest($request);
$output = [
"localeLangage" => $translator->getLocale(),
"token" => $token,
"form" => $form->createView(),
];
// Check if token length is valid.
if (strlen($token) !== 36) {
$output["errorMessage"] = $translator->trans("app_adherent_active_account.error_invalid_link", [], "authenticator");
return $this->render('Authentication/create-password.html.twig', $output);
}
// Find user by her reset token.
$user = $this->em()->getRepository(Utilisateur::class)->findOneBy([
"activeAccountToken" => $token,
]);
// If not found.
if (null === $user) {
$output["errorMessage"] = $translator->trans("app_adherent_active_account.error_invalid_link", [], "authenticator");
return $this->render('Authentication/create-password.html.twig', $output);
}
// Check the platform.
if (false === in_array($user->getPlatformId(), [getenv("PLATFORM_ID")])) {
$output["errorMessage"] = $translator->trans("app_adherent_active_account.error_invalid_link", [], "authenticator");
return $this->render('Authentication/create-password.html.twig', $output);
}
// Check date expiration.
if ($user->getDateActiveAccountExpire()->getTimestamp() < time()) {
$output["errorMessage"] = $translator->trans("app_adherent_active_account.error_time_expire", [], "authenticator");
return $this->render('Authentication/create-password.html.twig', $output);
}
// If new password was submitted.
if ($form->isSubmitted() && $form->isValid()) {
$password = $form->get("_password")->getData();
$passwordAgain = $form->get("_passwordAgain")->getData();
if ($password !== $passwordAgain) {
$output["errorMessageForm"] = $translator->trans("app_reset_password.not_similar_password", [], "authenticator");
return $this->render('Authentication/create-password.html.twig', $output);
}
if (false === Utilisateur::isValidPassword($password)) {
$output["errorMessageForm"] = $translator->trans("app_reset_password.critere_password", [], "authenticator");
return $this->render('Authentication/create-password.html.twig', $output);
}
// Set the new password.
$password = $passwordEncoder->encodePassword($user, $password);
$user->setPassword($password);
$user->setActiveAccountToken(null);
$user->setDateActiveAccountExpire(null);
$this->em()->flush();
$output["successMessage"] = $translator->trans("app_adherent_active_account.success", [], "authenticator");
return $this->render('Authentication/create-password.html.twig', $output);
}
$output["infoMessage"] = $translator->trans("app_adherent_active_account.finalize_when_password_defined", [], "authenticator");
return $this->render('Authentication/create-password.html.twig', $output);
}
// Create form.
$form = $this->createForm(AdherentActivateAccountType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$locale = $translator->getLocale();
$currentPlatformId = getenv("PLATFORM_ID");
$email = $form->get("_username")->getData();
// Find user.
$findUser = $this->em()->getRepository(Utilisateur::class)->findOneBy([
"email" => $email,
"platformId" => $currentPlatformId,
]);
// Si aucun compte n'existe avec l'adresse email de l'adhérent, on lui créer un compte.
if ($findUser === null) {
$findAdherent = $this->em()->getRepository(Adherent::class)->findBy([
"email" => $email,
"platformId" => $currentPlatformId,
"accesExtranet" => true,
]);
if (count($findAdherent) > 0) {
$utilisateur = new Utilisateur();
$utilisateur->setCivilite($findAdherent[0]->getCivilite());
$utilisateur->setPrenom($findAdherent[0]->getPrenom());
$utilisateur->setNom($findAdherent[0]->getNom());
$utilisateur->setEmail($findAdherent[0]->getEmail());
$utilisateur->setLang($this->getAppParameter("LANGUAGE"));
$utilisateur->setRoles([Utilisateur::ROLE_ADHERENT]);
$utilisateur->setPassword(-1);
$utilisateur->setSocieteSelected($findAdherent[0]->getSociete());
// Generate new token forgot password.
$token = $utilisateur->generateActiveAccountToken();
$this->em()->persist($utilisateur);
// If token was returned, new token was generated.
if (false !== $token) {
$this->em()->flush();
// Set locale lang.
if (null !== $utilisateur->getLang()) {
$locale = $utilisateur->getLang();
}
// Submit mail to user.
$mailer = new MailerHelper($this->getParameter("smtp"), $this->container->get("twig"), $locale);
$mailer->sendMail(
"Authentication/email/adherent/active-account.html.twig",
[
"token" => $utilisateur->getActiveAccountToken(),
],
$utilisateur->getEmail()
);
}
}
} else {
// Si un compte existe avec l'adresse email et qu'il s'agit d'un compte adhérent non activé, on renvoi le mail d'activation.
if (UserHelper::hasRole(Utilisateur::ROLE_ADHERENT, $findUser) && $findUser->getActiveAccountToken() !== null) {
// Generate new token forgot password.
$token = $findUser->generateActiveAccountToken();
// If token was returned, new token was generated.
if (false !== $token) {
$this->em()->flush();
// Set locale lang.
if (null !== $findUser->getLang()) {
$locale = $findUser->getLang();
}
// Submit mail to user.
$mailer = new MailerHelper($this->getParameter("smtp"), $this->container->get("twig"), $locale);
$mailer->sendMail(
"Authentication/email/adherent/active-account.html.twig",
[
"token" => $findUser->getActiveAccountToken(),
],
$findUser->getEmail()
);
}
}
// Si un compte existe avec l'adresse email et qu'il s'agit d'un compte adhérent déjà activé, on envoi un mail d'information.
if (UserHelper::hasRole(Utilisateur::ROLE_ADHERENT, $findUser) && $findUser->getActiveAccountToken() === null) {
// Submit mail to user.
$mailer = new MailerHelper($this->getParameter("smtp"), $this->container->get("twig"), $locale);
$mailer->sendMail("Authentication/email/adherent/already-activated.html.twig.html.twig", [], $findUser->getEmail());
}
}
return $this->render('Authentication/adherent/active-account.html.twig', [
"localeLangage" => $translator->getLocale(),
"submitted" => true,
]);
}
return $this->render('Authentication/adherent/active-account.html.twig', [
"localeLangage" => $translator->getLocale(),
"form" => $form->createView(),
]);
}
/**
* Forgot password.
* @Route("/forgot-password", name="forgot_password")
*/
public function forgotPassword(Request $request, TranslatorInterface $translator): Response {
// If user was already connected, redirect to home page.
if ($this->getUser() !== null) {
return $this->redirectToRoute("app");
}
// Create form.
$form = $this->createForm(ForgotPasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$locale = $translator->getLocale();
$currentPlatformId = getenv("PLATFORM_ID");
$email = $form->get("_username")->getData();
// Find user.
$findUser = $this->em()->getRepository(Utilisateur::class)->findOneBy([
"email" => $email,
]);
// If user was found and platform match.
if ($findUser !== null && true === in_array($currentPlatformId, [false, $findUser->getPlatformId()])) {
putenv("PLATFORM_ID={$findUser->getPlatformId()}");
// Generate new token forgot password.
$token = $findUser->generateForgotPasswordToken();
// If token was returned, new token was generated.
if (false !== $token) {
$this->em()->flush();
// Set locale lang.
if (null !== $findUser->getLang()) {
$locale = $findUser->getLang();
}
// Submit mail to user.
$mailer = new MailerHelper($this->getParameter("smtp"), $this->container->get("twig"), $locale);
$mailer->sendMail(
"Authentication/email/forgot-password.html.twig",
[
"token" => $findUser->getResetPasswordToken(),
],
$findUser->getEmail()
);
}
}
return $this->render('Authentication/forgot-password.html.twig', [
"localeLangage" => $translator->getLocale(),
"submitted" => true,
]);
}
return $this->render('Authentication/forgot-password.html.twig', [
"localeLangage" => $translator->getLocale(),
"form" => $form->createView(),
]);
}
/**
* Login.
* @Route("/login", name="login")
*/
public function index(AuthenticationUtils $authenticationUtils, TranslatorInterface $translator): Response {
// If user was already connected, redirect to home page.
if ($this->getUser() !== null) {
return $this->redirectToRoute("app");
}
// Create form.
$form = $this->createForm(LoginAuthenticatorType::class);
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('Authentication/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
"localeLangage" => $translator->getLocale(),
"form" => $form->createView(),
]);
}
/**
* Logout user.
* @Route("/logout", name="app_logout")
*/
public function logout() {
/** @var Utilisateur $user */
$user = $this->getUser();
if (null !== $user) {
$user->setDateSessionExpiration(null);
$user->setSessionToken(null);
}
$this->em()->persist($user);
$this->em()->flush();
if (isset($_COOKIE['REMEMBERME'])) {
unset($_COOKIE['REMEMBERME']);
setcookie('REMEMBERME', null, -1, '/');
}
session_destroy();
return $this->redirectToRoute("login");
}
/**
* Logout user.
* @Route("/process-logout", name="app_process_logout")
*/
public function processLogout() {
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
/**
* Reset the password.
* @Route("/reset/{token}", name="reset_password")
*/
public function resetPassword(Request $request, TranslatorInterface $translator, UserPasswordEncoderInterface $passwordEncoder, $token) {
// If user was already connected, redirect to home page.
if ($this->getUser() !== null) {
return $this->redirectToRoute("app");
}
$isCreationPassword = $request->query->has("configure");
$twigView = ($isCreationPassword ? "create-password" : "reset");
// Create form.
$form = $this->createForm(RenewPasswordType::class);
$form->handleRequest($request);
$output = [
"localeLangage" => $translator->getLocale(),
"token" => $token,
"form" => $form->createView(),
];
// Check if token length is valid.
if (strlen($token) !== 36) {
$output["errorMessage"] = $translator->trans("app_reset_password.error_invalid_link", [], "authenticator");
return $this->render('Authentication/' . $twigView . '.html.twig', $output);
}
// Find user by her reset token.
$user = $this->em()->getRepository(Utilisateur::class)->findOneBy([
"resetPasswordToken" => $token,
]);
// If not found.
if (null === $user) {
$output["errorMessage"] = $translator->trans("app_reset_password.error_invalid_link", [], "authenticator");
return $this->render('Authentication/' . $twigView . '.html.twig', $output);
}
// Check the platform.
if (false === in_array($user->getPlatformId(), [false, getenv("PLATFORM_ID")])) {
$output["errorMessage"] = $translator->trans("app_reset_password.error_invalid_link", [], "authenticator");
return $this->render('Authentication/' . $twigView . '.html.twig', $output);
}
// Check date expiration.
if ($user->getDateResetPasswordExpire()->getTimestamp() < time()) {
$output["errorMessage"] = $translator->trans("app_reset_password.error_time_expire", [], "authenticator");
return $this->render('Authentication/' . $twigView . '.html.twig', $output);
}
// If new password was submitted.
if ($form->isSubmitted() && $form->isValid()) {
$password = $form->get("_password")->getData();
$passwordAgain = $form->get("_passwordAgain")->getData();
if ($password !== $passwordAgain) {
$output["errorMessageForm"] = $translator->trans("app_reset_password.not_similar_password", [], "authenticator");
return $this->render('Authentication/' . $twigView . '.html.twig', $output);
}
if (false === Utilisateur::isValidPassword($password)) {
$output["errorMessageForm"] = $translator->trans("app_reset_password.critere_password", [], "authenticator");
return $this->render('Authentication/' . $twigView . '.html.twig', $output);
}
// Set the new password.
$password = $passwordEncoder->encodePassword($user, $password);
$user->setPassword($password);
$user->setDateResetPasswordExpire(null);
$user->setResetPasswordToken(null);
$this->em()->flush();
$output["successMessage"] = $translator->trans("app_reset_password.success_change", [], "authenticator");
return $this->render('Authentication/' . $twigView . '.html.twig', $output);
}
return $this->render('Authentication/' . $twigView . '.html.twig', $output);
}
}