<?php
namespace App\Controller;
use App\Entity\Resource;
use App\Form\AskRecoveryType;
use App\Form\RecoverType;
use App\Form\ResourceRegisterType;
use App\Service\CaptchaService;
use App\Service\FormService;
use App\Service\ResourceService;
use App\Service\VoiceService;
use DateTime;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\String\ByteString;
use Symfony\Contracts\Translation\TranslatorInterface;
class SecurityController extends AbstractController
{
const DEFAULT_ROUTE = 'home';
private $translator;
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
public function nolocale(Request $request): RedirectResponse
{
$prefered = $request->getPreferredLanguage(explode('|', $this->getParameter('supported_locales')));
if ($prefered == null) {
$prefered = 'en';
}
return $this->redirectToRoute('login', ['_locale' => $prefered]);
}
public function registernolocale(Request $request): RedirectResponse
{
$prefered = $request->getPreferredLanguage(explode('|', $this->getParameter('supported_locales')));
if ($prefered == null) {
$prefered = 'en';
}
return $this->redirectToRoute('register', ['_locale' => $prefered]);
}
public function askRecoverynolocale(Request $request): RedirectResponse
{
$prefered = $request->getPreferredLanguage(explode('|', $this->getParameter('supported_locales')));
if ($prefered == null) {
$prefered = 'en';
}
return $this->redirectToRoute('ask_recovery', ['_locale' => $prefered]);
}
public function recovernolocale(Request $request, string $token): RedirectResponse
{
$prefered = $request->getPreferredLanguage(explode('|', $this->getParameter('supported_locales')));
if ($prefered == null) {
$prefered = 'en';
}
return $this->redirectToRoute('recover', [
'token' => $token,
'_locale' => $prefered,
]);
}
public function createPasswordnolocale(Request $request, string $token): RedirectResponse
{
$prefered = $request->getPreferredLanguage(explode('|', $this->getParameter('supported_locales')));
if ($prefered == null) {
$prefered = 'en';
}
return $this->redirectToRoute('create_password', [
'token' => $token,
'_locale' => $prefered,
]);
}
public function login(AuthenticationUtils $authUtils): Response
{
if ($this->getUser() instanceof Resource) {
return $this->redirectToRoute(self::DEFAULT_ROUTE);
}
$error = $authUtils->getLastAuthenticationError();
$lastUsername = $authUtils->getLastUsername();
return $this->render('security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
]);
}
public function register(CaptchaService $captchaService): Response
{
if ($this->getUser() instanceof Resource) {
return $this->redirectToRoute(self::DEFAULT_ROUTE);
}
$form = $this->createForm(ResourceRegisterType::class);
return $this->render('security/register.html.twig', [
'form' => $form->createView(),
'sitekey' => $captchaService->getSitekey(),
]);
}
/**
* @throws Exception
*/
public function registerSave(Request $request, ResourceService $util, FormService $fUtil, VoiceService $voiceService, CaptchaService $captchaService): Response
{
$resource = new Resource();
$form = $this->createForm(ResourceRegisterType::class, $resource);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/**
* @var UploadedFile $sample
*/
$sample = $form->get('sample_file')->getData();
$recaptchaToken = $request->request->get('g-recaptcha-response');
if (!$captchaService->verifyCaptcha($recaptchaToken)) {
try {
unlink($sample->getRealPath());
} catch (Exception $e) {
}
return new JsonResponse([
'errors' => [
'recaptcha' => $this->translator->trans('The form is invalid, please refresh the page and try again'),
],
]);
}
$sponsorCode = $form->get('sponsor_code')->getData();
$sponsor = $util->getResourceBySponsorCode($sponsorCode);
$resource->setRegisteredAt(new DateTime());
$resource->setPassword('');
$resource->setAccentHidden($resource->getAccent());
$resource->setRole('ROLE_RESOURCE');
$resource->setStatus(Resource::STATUS_VALIDABLE);
$resource->setComptaStatus(Resource::STATUS_COMPTA_NONE);
$resource->setSponsorCode(ByteString::fromRandom(10, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'));
$resource->setSponsor($sponsor);
$resource->setPhoneLookup(false);
$resource->setOptOut(false);
$resource->setIsAgent(false);
$em = $this->getDoctrine()->getManager();
$em->persist($resource);
$em->flush();
$resource->setTra(null);
$voiceFile = $voiceService->saveSample($sample, $resource->getId());
$resource->setSample($voiceFile);
$em->flush();
$util->sendPasswordCreation($resource);
return $this->redirectToRoute('register_success', [
'resource' => $resource->getId(),
]);
}
return new JsonResponse([
'errors' => $fUtil->getErrorMessages($form),
]);
}
public function registerSuccess(Resource $resource): Response
{
return $this->render('security/register_success.html.twig', [
'email' => $resource->getEmail(),
]);
}
public function askRecovery(Request $request, ResourceService $util): Response
{
if ($this->getUser()) {
return $this->redirectToRoute(self::DEFAULT_ROUTE);
}
$form = $this->createForm(AskRecoveryType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$user = $util->getResourceByEmail($data['email']);
if ($user !== null) {
$util->sendRecovery($user);
}
return $this->render('security/recover_sent.html.twig');
}
return $this->render('security/ask_recovery.html.twig', [
'form' => $form->createView(),
'error' => false,
]);
}
public function recover(Request $request, string $token, ResourceService $util): Response
{
if ($this->getUser()) {
return $this->redirectToRoute(self::DEFAULT_ROUTE);
}
if ($token === null) {
return $this->render('security/recover_invalid_token.html.twig');
}
$user = $util->getRecoverableResource($token);
if ($user === null) {
return $this->render('security/recover_invalid_token.html.twig');
}
$form = $this->createForm(RecoverType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$util->changePassword($user, $data['password']);
return $this->redirectToRoute(self::DEFAULT_ROUTE);
}
return $this->render('security/recover.html.twig', [
'form' => $form->createView(),
]);
}
public function createPassword(Request $request, string $token, ResourceService $util): Response
{
if ($this->getUser()) {
return $this->redirectToRoute(self::DEFAULT_ROUTE);
}
if ($token === null) {
return $this->render('security/create_password_invalid_token.html.twig');
}
$user = $util->getRecoverableResource($token);
if ($user === null) {
return $this->render('security/create_password_invalid_token.html.twig');
}
$form = $this->createForm(RecoverType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$util->changePassword($user, $data['password']);
return $this->redirectToRoute(self::DEFAULT_ROUTE);
}
return $this->render('security/create_password.html.twig', [
'form' => $form->createView(),
]);
}
public function tra(): Response
{
return $this->render('security/tra.html.twig');
}
}