<?php
namespace App\Controller;
use App\Dto\Request\DtoSaveInstructorRequest;
use App\Entity\Contact;
use App\Entity\Prestashop\Customers;
use App\Form\ContactAskPasswordResetType;
use App\Form\ContactResetType;
use App\Helper\StringHelper;
use App\Repository\ContactRepository;
use App\Security\ConnectAsAuthenticator;
use App\Security\ConnectAsAuthenticatorextends;
use App\Security\WebsiteFormAuthenticator;
use App\Service\ContactManager;
use App\Service\InstructorService;
use App\Service\LanguageManager;
use App\Service\NotificationManager;
use App\Service\NotificationService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class AuthController extends EntityController
{
use TargetPathTrait;
private ContactManager $contactManager;
/**
* ApiController constructor.
* @param EntityManagerInterface $em
* @param ContactManager $contactManager
* @param NotificationManager $notificationManager
* @param RequestStack $request
* @param LanguageManager $languageManager
*/
public function __construct(EntityManagerInterface $em,
ContactManager $contactManager,
NotificationManager $notificationManager,
RequestStack $request,
LanguageManager $languageManager,
NotificationService $notificationService)
//<<<<<<< HEAD
// LanguageManager $languageManager,
// SessionInterface $session,
// NotificationService $notificationService)
// {
// parent::__construct($em, $notificationManager, $request, $languageManager, $session, $notificationService);
//=======
// LanguageManager $languageManager)
{
parent::__construct($em, $notificationManager, $request, $languageManager, $notificationService);
//>>>>>>> 92-achat-unique
$this->contactManager = $contactManager;
}
/**
* This is a form for a customer to ask to change password for the email submitted.
* Route : /password-reset
* @param Request $request
* @return Response
*/
public function viewAskPasswordReset(Request $request, RouterInterface $router) : Response
{
$this->getNavigationContext($request, $router);
$emptyAccount = (new Contact())
->setPassword('12345')
->setRepeatedPassword('12345');
// generate the form with the email
// todo : add captcha ?
$form = $this->createForm(ContactAskPasswordResetType::class, $emptyAccount);
// Get the email from the form and process like apiAskPasswordReset
if ($request->isMethod('POST')) {
$form->submit($request->request->get($form->getName()));
// If form is correct
if ($form->isSubmitted()) {
$email = $emptyAccount->getEmail();
$contact = $this->contactManager->getContactByMail($email);
// get account by mail
if(!is_null($contact)){
// if the user has no validity date or a old validity date
$this->contactManager->sendResetPassword($contact, $this->language, $this->viewData["context"]);
}
else{
$this->notificationManager::addError('Le compte n\'existe pas');
}
}
}
$this->createFlashs();
$this->addViewDataObject('form', $form->createView())
->addViewDataArray('response', $this->getMessages());
return $this->render('contact/ask_account_password_reset.html.twig',
$this->viewData
);
}
/**
* The FORM to reset password with password and repeated password
* Route : ResetPassword
* @param Request $request
* @return Response
*/
public function viewResetPassword(Request $request, RouterInterface $router) : Response
{
$token = $request->query->get('token', ''); // the static + the temporary token
//test data = 86ae4cbe2a4650d7fa91655948c6e5de38ba907fdd0eff7ea4085efc7a780dd3
$this->getNavigationContext($request, $router);
if(empty($token) || strlen($token) !== 128){
$this->notificationManager::addError('Utilisateur non valable');
// $this->notificationManager::addError('86ae4cbe2a4650d7fa91655948c6e5de38ba907fdd0eff7ea4085efc7a780dd3' . $this->getTemporaryAccessToken('toto@toto.com'));
}
else{
$staticToken = substr($token, 0, 64); // The account static token
$currentAccount = $this->contactManager->getContactByStaticToken($staticToken);
// Check if the email exists and the token is correct
if($currentAccount !== null
&& $currentAccount->getResetPasswordValidity() !== null
&& $currentAccount->getResetPasswordValidity() <= new \DateTime('NOW')
){
$this->notificationManager::addError('Utilisateur non valable ou délai dépassé : réessayez');
$this->createFlashs();
return $this->redirectToRoute('Index',
$this->viewData
);
}
else{
// Now we add the form to change the password
$form = $this->createForm(ContactResetType::class, $currentAccount);
if ($request->isMethod('POST')) {
$form->submit($request->request->get($form->getName()));
// If form is correct
if ($form->isSubmitted() && $form->isValid()){
// save the account
$clearPassword = $currentAccount->getPassword();
if($this->contactManager->updatePasswordFromToken($currentAccount->getEmail(), $currentAccount->getPassword(), $staticToken)){
$this->notificationManager::addInfo("Mot de passe mis à jour");
$contact = $this->contactManager->getContactByMail($currentAccount->getEmail());
$contact->setLastConnexion();
$this->entityManager->flush();
}
else{
$this->notificationManager::addError("Utilisateur invalide");
}
// if the account exists on Prestashop
$psCustomer = Customers::getByEmail($currentAccount->getEmail(),true);
// Insert the user if he doesn't exist
if(!is_null($psCustomer)){
if($psCustomer->updatePassword($clearPassword) !==0){
$this->notificationManager::addInfo("Mot de passe modifié sur Prestashop");
}
}
$this->createFlashs();
return $this->redirectToRoute('PreLogin', [
"brandCode" => $_GET["brandCode"] ?? null,
"apiKey" => $_GET["apiKey"] ?? null,
]);
}
}
$this->createFlashs();
$this->addViewDataObject('form', $form->createView())
->addViewDataArray('response', $this->getMessages());
return $this->render('contact/account_password_reset.html.twig',
$this->viewData
);
}
}
return $this->render('home.html.twig', ['response' => $this->getMessages()]);
}
/**
* Login to the app
* Set a session with the contact and all related accounts
* Route : login
* @param Request $request
* @return Response
*/
public function viewPreLogin(Request $request, RouterInterface $router): Response
{
// dd($request->getSession()->get('_security.default.target_path'));
if (isset($_GET["lang"]) && StringHelper::isNullOrEmptyWithSpace($_GET["lang"]) == false)
{
return $this->redirectToRoute('PreLogin', [
"_locale" => $_GET["lang"],
"brandCode" => $_GET["brandCode"]?? null,
"apiKey" => $_GET["apiKey"]?? null
]);
}
if($_ENV["MAINTENANCE"] === "true") {
return $this->render('maintainance.html.twig', $this->viewData);
}
$responseAction = 'pre-login';
$response = null;
$data = [];
if(isset($_COOKIE["contactDeleted"])) {
$this->notificationManager::addError('Oops, il y a un souci ! Soit il y a eu une erreur avec votre adresse email, soit nos serveurs sont pris d\'assaut par trop de monde en même temps. Veuillez vérifier votre saisie ou réessayer plus tard :)');
}
// If user is connected
/*if (!is_null($this->getUser())) {
$responseAction = 'ContactAccounts';
}*/
if (!is_null($this->getUser())) {
if(!is_null($request->getSession()->get('_security.default.target_path'))) {
return $this->redirect($request->getSession()->get('_security.default.target_path'));
}
else {
$responseAction = 'ContactAccounts';
}
}
else{
$this->getNavigationContext($request, $router);
$submitted = $request->request->get('submitLogin');
// if the form is submitted
if(!is_null($submitted)){
$contactEmail = $request->request->get('email');
// If the email address exists and is a correct email address
if(!is_null($contactEmail) || !filter_var($contactEmail, FILTER_VALIDATE_EMAIL)){
$contact = $this->contactManager->getContactByMail($contactEmail);
// Si le contact n'est pas trouvé, on tente de le rechercher dans salesforce et de le synchroniser
if (is_null($contact))
{
$contact = $this->contactManager->syncContactFormSF($contactEmail);
}
// If the contact exists
if(!is_null($contact)){
// If its the first connexion
if(is_null($contact->getLastConnexion())){
$this->contactManager->getContactByMail($contactEmail);
if(strpos($request->getSession()->get('_security.default.target_path'), 'external_access/buy')) {
$currentContact = $this->entityManager->getRepository(Contact::class)->findOneBy(['email' => $contactEmail]);
$currentContact->setInternalReturnUrl($request->getSession()->get('_security.default.target_path'));
$this->entityManager->persist($currentContact);
$this->entityManager->flush();
}
$responseAction = 'FirstConnexionResetPassword';
}
// if its a normal connexion
else{
$responseAction = 'Login';
if($request->request->get('brandCode') != null && $request->request->get('brandCode') != "") {
$brandCode = $request->request->get('brandCode');
$data['brandCode'] = $brandCode;
}
if($request->request->get('apiKey') != null && $request->request->get('apiKey') != "") {
$apiKey = $request->request->get('apiKey');
$data['apiKey'] = $apiKey;
}
}
$data['email'] = $contact->getEmail();
}
// contact not existing
else{
if($request->request->get('brandCode') != null && $request->request->get('brandCode') != "") {
$brandCode = $request->request->get('brandCode');
$data['brandCode'] = $brandCode;
}
$responseAction = 'Register';
$data['email'] = $contactEmail;
// $this->notificationManager::addError('Le compte n\'existe pas.');
}
}
// Contact email not filled
else{
$this->notificationManager::addError('Adresse email incorrecte');
}
}
$this->createFlashs();
}
if ($responseAction === 'ContactAccounts'){
$response = $this->redirectToRoute('ContactAccounts');
}
elseif ($responseAction === 'FirstConnexionResetPassword'){
$data["brandCode"] = $_GET["brandCode"]?? null;
$data["apiKey"] = $_GET["apiKey"]?? null;
$response = $this->redirectToRoute('FirstConnexionResetPassword', $data);
}
elseif ($responseAction === 'Login'){
$response = $this->redirectToRoute('Login', $data);
}
elseif ($responseAction === 'Register'){
$response = $this->redirectToRoute('Register', $data);
}
else{
$response = $this->render('login/pre-login.html.twig', $this->viewData);
}
return $response;
}
/**
* Login to the app
* Set a session with the contact and all related accounts
* Route : login
* @param AuthenticationUtils $authenticationUtils
* @param Request $request
* @return Response
*/
public function viewLogin(AuthenticationUtils $authenticationUtils, Request $request, RouterInterface $router): Response
{
$responseRoute = 'Login';
$data = [];
if (!is_null($this->getUser())) {
$responseRoute = 'ContactAccounts';
}
else{
$this->getNavigationContext($request, $router);
$contactEmail = $request->query->get('email');
if(is_null($contactEmail)){
$responseRoute = 'PreLogin';
}
else{
// if(is_null($contactEmail)){
// $contactEmail = $authenticationUtils->getLastUsername();
// }
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$this->addViewDataString('last_username', $lastUsername)
->addViewDataObject('error', $error)
->addViewDataString('email', $contactEmail);
}
}
$this->createFlashs();
if($responseRoute === 'ContactAccounts'){
$response = $this->redirectToRoute('ContactAccounts');
}
elseif($responseRoute === 'PreLogin'){
$response = $this->redirectToRoute('PreLogin');
}
else{
$response = $this->render('login/login.html.twig', $this->viewData);
}
return $response;
}
public function logout()
{
}
/**
* First connexion email
* @param Request $request
* @return Response
*/
public function viewFirstConnexionResetPassword(Request $request, RouterInterface $router) : Response
{
$contactEmail = $request->query->get('email', '');
$contact = $this->contactManager->getContactByMail($contactEmail);
$this->getNavigationContext($request, $router);
if(!is_null($contact) && is_null($contact->getLastConnexion())){
// if the user has no validity date or a old validity date
$this->contactManager->sendResetPassword($contact, $this->language, $this->viewData['context']);
// $contact->setLastConnexion();
// $this->entityManager->flush();
}
else{
$this->notificationManager::addError('Le compte n\'existe pas ou l\'e-mail de première connexion a déjà été envoyé');
}
$this->createFlashs();
return $this->render('contact/first_connexion_ask_account_password_reset.html.twig', $this->viewData);
}
/**
* Register account
* @param Request $request
* @return Response
*/
public function viewRegisterAccount(Request $request, RouterInterface $router, InstructorService $instructorService, GuardAuthenticatorHandler $guard, WebsiteFormAuthenticator $autoLoginAuthenticator) : Response
{
if (!is_null($this->getUser()) || $this->language == 'it') {
$responseRoute = $this->redirectToRoute('ContactAccounts', $this->viewData);
}
else {
$this->getNavigationContext($request, $router);
$dtoRequest = new DtoSaveInstructorRequest();
$submitted = $request->request->get('submitRegister');
// if the form is submitted
if (!is_null($submitted)) {
$dtoRequest->email = $request->request->get('email') ?? '';
$dtoRequest->emailCompta = $request->request->get('email') ?? '';
$dtoRequest->lastName = $request->request->get('lastName') ?? '';
$dtoRequest->firstName = $request->request->get('firstName') ?? '';
$dtoRequest->phone = $request->request->get('phone') ?? '';
$dtoRequest->address = $request->request->get('address') ?? '';
$dtoRequest->zipCode = $request->request->get('zipCode') ?? '';
$dtoRequest->city = $request->request->get('city') ?? '';
$dtoRequest->siret = $request->request->get('siret') ?? '';
$dtoRequest->tva = $request->request->get('tva') ?? '';
$dtoRequest->password = $request->request->get('password') ?? '';
$dtoRequest->checkPassword = $request->request->get('checkPassword') ?? '';
$dtoRequest->billingCountryCode = $request->request->get('country') ?? '';
$dtoRequest->isPro = $request->request->get('isPro');
$dtoResponse = $instructorService->createInstructor($dtoRequest);
$this->createFlashsFromDtoResponse($dtoResponse);
if($dtoResponse->isSuccess()) {
$referent = $this->contactManager->fillSessionContactFromContactEmail($dtoRequest->email);
$request->getSession()->set(Security::LAST_USERNAME, $request->get('email'));
$request->getSession()->set('contact', $referent);
$request->getSession()->set('contactCsrfToken', $this->contactManager->getContactApiTokenByEmail($dtoRequest->email));
// Handle user as if he just logged-in
// after validating the user and saving it to the database
// authenticate the user and use onAuthenticationSuccess on the authenticator
$user = $this->contactManager->getContactByMail($dtoRequest->email);
$guard->authenticateUserAndHandleSuccess(
$user,
$request,
$autoLoginAuthenticator,
'main'
);
$responseRoute = $this->redirectToRoute('PreLogin', $this->viewData);
} else {
$this->addViewDataObject('newInstructorAccount', $dtoRequest);
$responseRoute = $this->render('contact/register.html.twig', $this->viewData);
}
} else {
$responseRoute = $this->render('contact/register.html.twig', $this->viewData);
}
}
return $responseRoute;
}
/**
* Autologin from Salesforce
* path: /{_locale}/switch
* name: SwitchUser
* @return \Symfony\Component\HttpFoundation\Response
*/
public function switchUser(GuardAuthenticatorHandler $guard, Security $security, ConnectAsAuthenticator $customAuthenticator, Request $request)
{
if ($this->getUser() == null)
{
$this->saveTargetPath($request->getSession(), "default", $request->getUri());
return $this->redirectToRoute('PreLogin');
}
$user = $this->entityManager->getRepository(Contact::class)->findOneBy(["email" => $request->get("email")]);
if ($user == null || $security->isGranted('ROLE_ADMIN') == false)
{
throw $this->createNotFoundException("L'action demandée ne peut pas être exécutée.");
}
else
{
$currentUser = $security->getUser();
$customAuthenticator->setCurrentUser($currentUser);
// Handle user as if he just logged-in
// after validating the user and saving it to the database
// authenticate the user and use onAuthenticationSuccess on the authenticator
$guard->authenticateUserAndHandleSuccess(
$user,
$request,
$customAuthenticator,
'main'
);
// Redirection vers la page Home
return $this->redirectToRoute('ContactAccounts');
}
}
/**
* disconnect to previous account from Salesforce
* path: /{_locale}/exit
* name: ExitUser
* @return Response
*/
public function exitUser(GuardAuthenticatorHandler $guard, Security $security, ConnectAsAuthenticator $customAuthenticator, Request $request) : Response
{
// Récupération des données de l'administrateur dans la session
$previousAdminUsername = $request->getSession()->get('previousAdminUsername');
if (StringHelper::isNullOrEmptyWithSpace($previousAdminUsername) == false)
{
$user = $this->entityManager->getRepository(Contact::class)->findOneBy(["email" => $previousAdminUsername]);
if ($user == null)
{
throw $this->createNotFoundException("L'action demandée ne peut pas être exécutée.");
}
else
{
$customAuthenticator->setCurrentUser(null);
$guard->authenticateUserAndHandleSuccess(
$user,
$request,
$customAuthenticator,
'main'
);
// Redirection vers la page Home
return $this->redirectToRoute('ContactAccounts');
}
}
else
{
throw $this->createNotFoundException("L'action demandée ne peut pas être exécutée.");
}
}
}