<?php
namespace App\Controller\Security;
use App\Common\Controller\BaseController;
use App\Entity\Security\User;
use App\Form\Security\ChangePasswordType;
use App\Form\Security\ResetPasswordType;
use App\Form\Security\User2Type;
use App\Repository\Security\ProfileRepository;
use App\Repository\Security\UserRepository;
use App\Service\Logger;
use App\Service\Mailer\Emailer;
use App\Service\Slugger;
use DateTime;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use LogicException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\LoginLink\LoginLinkDetails;
use Symfony\Component\Security\Http\LoginLink\LoginLinkHandlerInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;
class LoginController extends BaseController {
use TargetPathTrait;
/**
* @Route("/login", name="mapp_security_login", host="192.168.43.120")
*/
public function mlogin(AuthenticationUtils $helper, Logger $logger): Response {
$logger->logging(new User(), new User(), Logger::ACTION_CONNECT_FORM);
return $this->render('security/mlogin.html.twig', [
'last_username' => $helper->getLastUsername(),
// last authentication error (if any)
'error' => $helper->getLastAuthenticationError(),
]);
}
/**
* @Route("/login", name="app_security_login")
*/
public function login(AuthenticationUtils $helper, Logger $logger): Response {
$user = $this->getUser();
if ($user) {
$logger->logging($user, $user, Logger::ACTION_CONNECT_ALREADY);
return $this->redirectToRoute($this->getParameter('default_homepage'));
} else {
$logger->logging(new User(), new User(), Logger::ACTION_CONNECT_FORM);
return $this->render('security/login.html.twig', [
'controller_name' => 'LoginController',
// last username entered by the user (if any)
'last_username' => $helper->getLastUsername(),
// last authentication error (if any)
'error' => $helper->getLastAuthenticationError(),
]);
}
}
/**
* @Route("/signup", name="app_security_signup")
*/
public function signup(Request $request, UserRepository $repository, ProfileRepository $pRepository, TranslatorInterface $translator, Logger $logger, LoginLinkHandlerInterface $loginLinkHandler, Emailer $emailer, Environment $twig): Response {
$logger->logging(new User(), new User(), Logger::ACTION_CONNECT_FORM);
$user = new User();
$form = $this->createForm(User2Type::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
//TODO set username
$username = $user->getUsername();
if ($username === null or trim($username) == false) {
$usernamed = $user->generateUsername();
$username = $usernamed;
$i = 0;
$sameUsername = $repository->count(['username' => $username]);
while ($sameUsername != 0) {
$i++;
$username = $usernamed . $i;
$sameUsername = $repository->count(['username' => $username]);
}
$user->setUsername($username);
}
$user->setProfile($pRepository->findDefaultProfile());
$user->setPrivatePassword(false);
$slugger = new Slugger();
$user->setCode($slugger->createCode());
$repository->add($user, true);
$loginLinkDetails = $loginLinkHandler->createLoginLink($user);
$loginLink = $loginLinkDetails->getUrl();
$delai = $this->getDefaultContent2($loginLinkDetails);
$dest_name = $user->getFullname();
$subject = 'PROIMMO - Validate Email';
$description = 'Bonjour ' . $dest_name . ',' . PHP_EOL . PHP_EOL . ' Veuillez cliquer sur le bouton suivant pour la réinitialisation du mot de passe de votre compte PROIMMO.' . PHP_EOL . $loginLink . PHP_EOL . $delai . PHP_EOL . PHP_EOL . 'Merci de faire confiance à Tank\'immo, Madame / Monsieur ' . $dest_name . ' . Nous restons disponibles.';
$htmlContents = $twig->render('emails/_login_link_email.html.twig', [
'dest_name' => $dest_name,
'url' => $loginLink,
'delay' => $delai,
'username' => $user->getUsername(),
]);
$emailer->sendMail(Emailer::$defaultFrom, $user->getEmail(), $subject, $description, $htmlContents);
// $emailer->sendMail(Emailer::$defaultFrom, Emailer::$defaultTo, $subject, $description, $htmlContents);
$this->addFlash('success', $translator->trans('tt_message.add_successfully'));
$logger->logging($user, $user, Logger::ACTION_ADD);
return $this->render('security/confirm_email2.html.twig', [
'email' => $user->getEmail(),
'url' => $loginLink,
'message' => $this->getDefaultContent($loginLinkDetails),
]);
} catch (UniqueConstraintViolationException $ex) {
$form->addError(new FormError($translator->trans('tt_message.username_not_unique')));
}
} else {
$logger->logging(new User(), $user, Logger::ACTION_ADD_FORM);
}
return $this->render('security/signup.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/reset_password", name="app_security_reset_password")
* @IsGranted("IS_AUTHENTICATED")
* @IsGranted("ROLE_SECURITY_USER_RESET_PASSWORD")
*/
public function resetPassword(Request $request, TranslatorInterface $translator, Logger $logger, UserPasswordHasherInterface $passwordHasher): Response {
$user = $this->getUser();
$form = $this->createForm(ResetPasswordType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$newPassword = $form->get('newPassword')->getData();
$user->setPassword($passwordHasher->hashPassword($user, $newPassword));
$user->setPrivatePassword(true);
$user->setLmp(new DateTime());
$user->removeUserrole('ROLE_SECURITY_USER_RESET_PASSWORD');
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', $translator->trans('tt_message.change_password_successfully'));
$logger->logging($this->getUser(), $user, Logger::ACTION_PASSWORD_CHANGE);
return $this->redirectToRoute('jit_index');
} else {
$logger->logging(new User(), $user, Logger::ACTION_RESET_PASSWORD);
}
return $this->render('security/reset_password2.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @IsGranted("IS_AUTHENTICATED_FULLY")
* @Route("/change_password", name="app_security_change_password")
*/
public function changePassword(Request $request, TranslatorInterface $translator, Logger $logger, UserPasswordHasherInterface $passwordHasher): Response {
$user = $this->getUser();
$form = $this->createForm(ChangePasswordType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$oldPassword = $form->get('oldPassword')->getData();
$newPassword = $form->get('newPassword')->getData();
if ($passwordHasher->isPasswordValid($user, $oldPassword)) {
$user->setPassword($passwordHasher->hashPassword($user, $newPassword));
$user->setPrivatePassword(true);
$user->setLmp(new DateTime());
$user->removeUserrole('ROLE_SECURITY_USER_RESET_PASSWORD');
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', $translator->trans('tt_message.change_password_successfully'));
$logger->logging($this->getUser(), $user, Logger::ACTION_PASSWORD_CHANGE);
return $this->redirectToRoute('jit_index');
} else {
$form->addError(new FormError($translator->trans('tt_message.old_password_dont_match')));
}
} else {
$logger->logging(new User(), $user, Logger::ACTION_PASSWORD_CHANGE);
}
return $this->render('security/change_password2.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/confirm_email", name="app_security_confirm_email")
*/
public function confirmEmail(AuthenticationUtils $helper, Logger $logger): Response {
$logger->logging(new User(), new User(), Logger::ACTION_CONFIRM_EMAIL);
$slugger = new Slugger();
$code = $slugger->createCode();
return $this->render('security/confirm_email2.html.twig', [
'email' => $code,
]);
}
/**
* @Route("/forget_password", name="app_security_forget_password")
*/
public function forgetPassword(LoginLinkHandlerInterface $loginLinkHandler, UserRepository $userRepository, Request $request, Logger $logger,
UrlGeneratorInterface $urlGenerator, Emailer $emailer, Environment $twig): Response {
$logger->logging(new User(), new User(), Logger::ACTION_FORGET_PASSWORD);
// check if form is submitted
if ($request->isMethod('POST')) {
// load the user in some way (e.g. using the form input)
$email = $request->request->get('email');
$user = $userRepository->findOneBy(['email' => $email]);
$htmlContents = '';
$description = '';
$subject = 'PROIMMO - Reset Password';
if ($user === null) {
// Le compte n'existe pas faire toujour le mail
$dest_name = '';
$signuplink = $urlGenerator->generate('app_security_signup', [], UrlGeneratorInterface::ABSOLUTE_URL);
$description = 'Bonjour ' . $dest_name . ',' . PHP_EOL . PHP_EOL . ' Veuillez noter que vous n\'avez pas de compte sur la plateforme PROIMMO..' . PHP_EOL . 'Vous pouvez toujours créer un compte gratuitement en cliquant sur le lien ci-dessous' . PHP_EOL . $signuplink . PHP_EOL . PHP_EOL . 'Merci de faire confiance à Tank\'immo, Madame / Monsieur ' . $dest_name . ' . Nous restons disponibles.';
$htmlContents = $twig->render('emails/_login_unknow_email.html.twig', [
'dest_name' => $dest_name,
'url' => $signuplink,
]);
} else if (!$user->isEnabled()) {
// Compte innactif faire le mail
$dest_name = $user->getFullname();
$description = 'Bonjour ' . $dest_name . ',' . PHP_EOL . PHP_EOL . ' Veuillez noter que votre compte est vérouillé actuellement.' . PHP_EOL . 'Merci de contacter votre agent pour plus d\'informations' . PHP_EOL . PHP_EOL . 'Merci de faire confiance à Tank\'immo, Madame / Monsieur ' . $dest_name . ' . Nous restons disponibles.';
$htmlContents = $twig->render('emails/_login_lock_email.html.twig', [
'dest_name' => $dest_name,
]);
} else {
// create a login link for $user this returns an instance
// of LoginLinkDetails
$loginLinkDetails = $loginLinkHandler->createLoginLink($user);
$loginLink = $loginLinkDetails->getUrl();
$delai = $this->getDefaultContent2($loginLinkDetails);
$dest_name = $user->getFullname();
$description = 'Bonjour ' . $dest_name . ',' . PHP_EOL . PHP_EOL . ' Veuillez cliquer sur le bouton suivant pour la réinitialisation du mot de passe de votre compte PROIMMO.' . PHP_EOL . $loginLink . PHP_EOL . $delai . PHP_EOL . PHP_EOL . 'Merci de faire confiance à Tank\'immo, Madame / Monsieur ' . $dest_name . ' . Nous restons disponibles.';
$htmlContents = $twig->render('emails/_login_link_email.html.twig', [
'dest_name' => $dest_name,
'url' => $loginLink,
'delay' => $delai,
'username' => $user->getUsername(),
]);
}
$emailer->sendMail(Emailer::$defaultFrom, $email, $subject, $description, $htmlContents);
// $emailer->sendMail(Emailer::$defaultFrom, Emailer::$defaultTo, $subject, $description, $htmlContents);
return $this->render('security/confirm_email2.html.twig', [
'email' => $email,
// 'url' => $loginLink,
// 'message' => $this->getDefaultContent($loginLinkDetails),
]);
}
// if it's not submitted, render the form to request the "login link"
return $this->render('security/forget_password2.html.twig');
}
/**
* @Route("/logout", name="app_security_logout")
*/
public function logout() {
throw new LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
/**
* @Route("/login_check", name="app_security_login_check")
*/
public function loginCheck() {
throw new LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
private function getDefaultContent(LoginLinkDetails $loginLinkDetails): string {
$duration = $loginLinkDetails->getExpiresAt()->getTimestamp() - time();
$durationString = '';
if ($duration > 60) {
$durationString = floor($duration / 60) . ' minute' . ($duration > 60 ? 's' : '');
if (($hours = $duration / 3600) >= 1) {
$durationString = floor($hours) . ' hour' . ($hours >= 2 ? 's' : '');
}
} else {
$durationString = $duration . ' secondes';
}
return sprintf('Click on the %s to confirm you want to sign in. This link will expire in %s.', 'link', $durationString);
}
private function getDefaultContent2(LoginLinkDetails $loginLinkDetails): string {
$duration = $loginLinkDetails->getExpiresAt()->getTimestamp() - time();
$durationString = '';
if ($duration > 60) {
$durationString = floor($duration / 60) . ' minute' . ($duration > 60 ? 's' : '');
if (($hours = $duration / 3600) >= 1) {
$durationString = floor($hours) . ' hour' . ($hours >= 2 ? 's' : '');
}
} else {
$durationString = $duration . ' secondes';
}
return sprintf('This link will expire in %s.', $durationString);
}
}