<?php
namespace App\Controller;
use App\Entity\Master\Company;
use App\Entity\Slave\User;
use App\Form\Security\LoginCompanyType;
use App\Form\Security\PasswordCreationType;
use App\Form\Security\PasswordRecoveryType;
use App\Service\CompanyService;
use App\Service\ValidationService;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
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\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class SecurityController extends AbstractController
{
protected $mr;
private $params;
public function __construct(ManagerRegistry $managerRegistry, ParameterBagInterface $params)
{
$this->mr = $managerRegistry;
$this->params = $params;
}
/**
* @Route("/accedi-reindirizza", name="login_redirect")
*/
public function loginRedirect(Request $request, ValidatorInterface $validator): Response
{
$emMaster = $this->mr->getManager('master');
$session = $request->getSession();
$company = new Company();
$form = $this->createForm(LoginCompanyType::class, $company);
$form->handleRequest($request);
if($form->isSubmitted()){
$valid = true;
if($valid) $valid = ValidationService::validateNotBlank($validator, $form->get('companyCode'));
$company = $emMaster->getRepository('App\Entity\Master\Company')->findOneBy(array('code' => $form->get('companyCode')->getData()));
if($company == null){
$valid = false;
$form->get('companyCode')->addError(new FormError("Nessuna azienda trovata con questo codice!"));
}
if($valid && $form->isValid()){
$session->set('companyId', $company->getId());
return $this->redirectToRoute('login', array('companyCode' => $company->getCode()));
}
}
return $this->render('security/login_redirect.html.twig', array(
'form' => $form->createView()
));
}
/**
* @Route("/accedi", name="login_old")
*/
public function loginOld(Request $request)
{
if(isset($_COOKIE["eposm_company_code"]))
return $this->redirectToRoute("user_index");
return $this->redirectToRoute("login_redirect");
}
/**
* @Route("/accedi/{companyCode}", name="login")
*/
public function login($companyCode, Request $request, ValidatorInterface $validator, MailerInterface $mailer, AuthenticationUtils $authenticationUtils): Response
{
$emMaster = $this->mr->getManager('master');
$session = $request->getSession();
$company = $emMaster->getRepository('App\Entity\Master\Company')->findOneBy(array('code' => $companyCode));
$em = CompanyService::getSlaveManagerByCompany($this->mr, $this->params, $company);
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
$pswUser = new User();
$form = $this->createForm(PasswordRecoveryType::class, $pswUser);
$form->handleRequest($request);
if($form->isSubmitted()){
$valid = true;
$path = 'https://www.google.com/recaptcha/api/siteverify?secret=6Lf8cfEpAAAAAIGg748C0wPad5YSPs68DyXEl8eM&response='.$request->request->get("g-recaptcha-response");
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json'));
curl_setopt($ch, CURLOPT_URL,$path);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$result = curl_exec($ch);
curl_close($ch);
$res = json_decode($result, true);
if(!$res["success"]){
$valid = false;
$form->get('recaptcha')->addError(new FormError("Convalidare prima di inviare la richiesta"));
$this->addFlash('notice_warning', "Prima di inviare la richiesta, provare di non essere un robot.");
}
if($valid) $valid = ValidationService::validateNotBlank($validator, $form->get('email'));
if($valid) $valid = ValidationService::validateEmail($validator, $form->get('email'));
if($valid && $form->isValid()){
$user = $em->getRepository("App\Entity\Slave\User")->findOneByEmail($pswUser->getEmail());
if($user){
$now = new \DateTime();
$user->setOneTimeCode(md5(uniqid()));
$user->setExpirationOneTimeCode(date_modify($now, "+3 hours"));
$em->flush();
$message = (new TemplatedEmail())
->subject($this->params->get('subject_recover_password'))
->from($this->params->get('email_noreply'))
->to($user->getEmail())
->htmlTemplate('email/password_recovery.html.twig')
->context(['user' => $user, 'company' => $company]);
$mailer->send($message);
}
$this->addFlash('notice_success', "La richiesta è stata ricevuta correttamente.<br>Se l'account esiste, verrà inviato un messaggio di posta elettronica all'indirizzo corrispondente.");
return $this->redirectToRoute('login', array('companyCode' => $companyCode));
}
else{
$session->set('openModalRecover', true);
$this->addFlash('notice_warning', "Controlla le informazioni inserite nel form di recupero password.");
}
}
return $this->render('security/login.html.twig', array(
'company' => $company,
'last_username' => $lastUsername,
'error' => $error,
'form' => $form->createView()
));
}
/**
* @Route("/accedi-controllo", name="login_check")
*/
public function loginCheck() {}
/**
* @Route("/disconnetti", name="logout")
*/
public function logout(Response $response)
{
$response->headers->clearCookie('eposm_company_code', '/', '.'.$this->params->get('cookies_domain'));
}
/**
* @Route("/crea-password/{oneTimeCode}/{companyCode}", name="password_creation", requirements={"oneTimeCode" = "[\w\d]{32}"})
*/
public function passwordCreation(Request $request, $oneTimeCode, $companyCode, ValidatorInterface $validator, UserPasswordHasherInterface $passwordHasher)
{
//DISCONNETTO L'UTENTE SE CONNESSO
$this->get('security.token_storage')->setToken(null);
$session = $request->getSession();
$emMaster = $this->mr->getManager('master');
$company = $emMaster->getRepository('App\Entity\Master\Company')->findOneByCode($companyCode);
$session->set("companyId", $company->getId());
$em = CompanyService::getSlaveManagerByCompany($this->mr, $this->params, $company);
$user = $em->getRepository('App\Entity\Slave\User')->findOneByOneTimeCode($oneTimeCode);
$now = new \DateTime('now');
if($user != null && $user->getExpirationOneTimeCode() != null){
date_modify($user->getExpirationOneTimeCode(), '+3 hours');
if($now->format("YmdHis") < $user->getExpirationOneTimeCode()->format("YmdHis")){
$form = $this->createForm(PasswordCreationType::class, $user);
$form->handleRequest($request);
if($form->isSubmitted()){
$valid = true;
$valid = ValidationService::validateNotBlank($validator, $form->get('password'));
if($valid){
$psw = $form->get('password')->getData();
$count = 0;
if(preg_match('/[0-9]/', $psw)) $count++;
if(preg_match('/[a-z]/', $psw)) $count++;
if(preg_match('/[A-Z]/', $psw)) $count++;
if(preg_match('/[\!\#\$\&\(\)\.\+\-_]/', $psw)) $count++;
if($count < 3)
{
$this->addFlash('notice_warning', "La password inserita non è sufficientemente forte.");
$valid = false;
}
}
if($valid && $form->isValid()){
$password = $passwordHasher->hashPassword($user, $form->get("password")->getData());
$user->setPassword($password);
$user->setActive(1);
$em->flush();
$this->addFlash('notice_success', "La nuova password è stata creata correttamente; prima di poter accedere controllare se l'account è attivato.");
return $this->redirectToRoute("login", array('companyCode' => $companyCode));
}
}
return $this->render('security/password_create.html.twig', array(
'oneTimeCode' => $oneTimeCode,
'company' => $company,
'form' => $form->createView()
));
}
else{
$this->addFlash('notice_warning', "Il codice per la generazione della password è scaduto.<br>La password deve essere creata entro 3 ore dalla richiesta di attivazione.<br>Per poter proseguire è necessario richiedere un nuovo codice.");
return $this->redirectToRoute("login", array('companyCode' => $companyCode));
}
}
else{
$this->addFlash('notice_warning', "Non è stato trovato nessun utente abbinato al codice inserito, nel caso sia stato fatto copia/incolla dall'e-mail ricevuta, verificare che non siano stati riportati degli spazi o caratteri aggiuntivi.");
return $this->redirectToRoute("login", array('companyCode' => $companyCode));
}
}
}