<?php
namespace App\Controller;
use App\Entity\Client;
use App\Entity\Company;
use App\Entity\MarketplaceReservation;
use App\Entity\Specialist;
use App\Entity\User;
use App\Form\Client\CompanyCodeType;
use App\Form\Company\ClientType;
use App\Form\Marketplace\CompanyMarketplaceType;
use App\Form\SpecialistLightType;
use App\Form\SpecialistType;
use App\Repository\CompanyRepository;
use App\Repository\SpecialistRepository;
use App\Repository\UserRepository;
use App\Security\ClientAuthenticator;
use App\Security\ExternalClientProvider;
use App\Security\SpecialistAuthenticator;
use App\Service\ApiService;
use App\Service\EmailService;
use App\Service\OktaApiService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Uid\Uuid;
class SecurityController extends AbstractController
{
/**
* @var emailService
*/
private $emailService;
public function __construct(EmailService $emailService)
{
$this->emailService = $emailService;
}
/**
* @Route("/admin/login", name="app_login_admin")
*/
public function loginAdmin(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('admin_dashboard');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login_admin.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/admin/logout", name="app_admin_logout")
*/
public function logoutAdmin(): void
{
}
/**
* @Route("/entreprise/logout", name="app_company_logout")
*/
public function logoutCompany(): void
{
}
/**
* @Route("/entreprise/login", name="app_login_company")
*/
public function loginCompany(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('company_dashboard');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login_company.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/equipe/logout", name="app_client_logout")
*/
public function logoutClient(): void
{
}
/**
* @Route("/equipe/login-api", name="client_login", methods={"GET"})
* @return JsonResponse|RedirectResponse
*/
public function clientLogin(Request $request, ExternalClientProvider $clientProvider, ApiService $apiService,
EventDispatcherInterface $dispatcher, TokenStorageInterface $tokenStorage)
{
if (!$apiService->checkAuthorisation($request)) {
return new JsonResponse("Unauthorised", 403);
}
$urlToken = $request->get('token');
try {
$user = $clientProvider->loadUserByToken($urlToken);
$token = new UsernamePasswordToken($user, 'client', $user->getRoles());
$tokenStorage->setToken($token);
$event = new InteractiveLoginEvent($request, $token);
$dispatcher->dispatch($event, "security.interactive_login");
}catch (\Exception $e){
return $this->redirectToRoute(ClientAuthenticator::LOGIN_ROUTE);
}
return $this->redirectToRoute('client_dashboard');
}
/**
* @Route("/equipe/login", name="app_login_client")
*/
public function loginClient(Request $request, AuthenticationUtils $authenticationUtils): Response
{
$byPassSaml = $request->get('bypass', false);
if ($this->getUser()) {
return $this->redirectToRoute('client_dashboard');
}
if ($request->server->get('HTTP_HOST') == $this->getParameter('saml_redirect_domain') && !$byPassSaml){
return $this->redirectToRoute('saml_login');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login_client.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/equipe/login/premiere-connexion", name="app_login_company_code")
*/
public function loginByCompanyCode(Request $request, CompanyRepository $companyRepo): Response
{
$form = $this->createForm(CompanyCodeType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$company = $companyRepo->findOneBy(
[
'companyCode' => $form->getData()['companyCode']
]
);
if ($company instanceof Company && $company->getCompanyCode() == $form->getData()['companyCode']) {
return $this->redirectToRoute('app_create_user_company_code', ['companyCode' => $company->getCompanyCode()]);
}else{
$error = true;
$this->addFlash('errorGlobal', "Aucune entreprise trouvée");
return $this->redirectToRoute('app_login_company_code', ['error' => $error]);
}
}
return $this->render('security/login_company_code.html.twig', [
'codeForm' => $form->createView(),
]);
}
/**
* @Route("/equipe/login/code/{companyCode}", name="app_create_user_company_code")
*/
public function createUserByCompanyCode(Request $request, string $companyCode, EntityManagerInterface $entityManager,
EventDispatcherInterface $dispatcher, TokenStorageInterface $tokenStorage, CompanyRepository $companyRepo): Response
{
$company = $companyRepo->findOneBy(
[
'companyCode' => $companyCode
]
);
if ($company == null || $companyCode !== $company->getCompanyCode()) {
$error = true;
$this->addFlash('errorGlobal', "Aucune entreprise trouvée");
return $this->redirectToRoute('app_login_company_code', ['error' => $error]);
}
$client = new Client();
$client->setCompany($company);
$form = $this->createForm(ClientType::class, $client);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$plainPassword = "empty";
$client->getUser()->setName((string) $client);
$client->getUser()->setActive(true);
$client->setIsCgu(true);
$entityManager->persist($client);
$entityManager->flush();
$entityManager->refresh($client);
try {
$user = $client->getUser();
$token = new UsernamePasswordToken($user, 'client', $user->getRoles());
$tokenStorage->setToken($token);
$event = new InteractiveLoginEvent($request, $token);
$dispatcher->dispatch($event, "security.interactive_login");
$this->emailService->sendNewClientCreatedEmail($client, $plainPassword);
}catch (\Exception $e){
$this->addFlash('errorGlobal', 'Une erreur est survenue');
return $this->redirectToRoute(ClientAuthenticator::LOGIN_ROUTE);
}
return $this->redirectToRoute('client_dashboard');
}
return $this->render('security/create_user_company_code.html.twig', [
'regForm' => $form->createView(),
]);
}
/**
* @Route("/expert/login", name="app_login_specialist")
*/
public function loginSpecialist(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('specialist_dashboard');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login_specialist.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/login", name="app_login_marketplace", host="%MARKETPLACE_HOST%")
*/
public function loginMarketplace(AuthenticationUtils $authenticationUtils, EntityManagerInterface $em): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('marketplace_app_user');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login_marketplace.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/inscription", name="app_create_user_marketplace", host="%MARKETPLACE_HOST%")
*/
public function createMarketplaceUser(Request $request, EntityManagerInterface $em, EventDispatcherInterface $dispatcher, TokenStorageInterface $tokenStorage, CompanyRepository $companyRepo): Response
{
$company = new Company;
$company->setForceSegmentation(false);
$form = $this->createForm(CompanyMarketplaceType::class, $company, ['newCompany' => true]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$user = $company->getUser();
$user->setCompany($company);
$em->persist($user);
$em->persist($company);
$em->flush();
$this->addFlash('success', "Compte crée avec succès");
$token = new UsernamePasswordToken($user, 'marketplace', $user->getRoles());
$tokenStorage->setToken($token);
$event = new InteractiveLoginEvent($request, $token);
$dispatcher->dispatch($event, "security.interactive_login");
$this->emailService->sendNewMarketplaceCompanyCreatedEmail($company);
if (!empty($request->getSession()->get('RESERVATION_ID'))) {
$marketplaceReservation = $em->getRepository(MarketplaceReservation::class)->find($request->getSession()->get('RESERVATION_ID'));
return $this->redirectToRoute('marketplace_app_reservation_recap', ['marketplaceReservationId' => $marketplaceReservation->getId()]);
}
return $this->redirectToRoute('marketplace_app_user');
} catch (\Throwable $th) {
//throw $th;
$this->addFlash('accountError', 'Une erreur est survenue');
}
}
return $this->render('security/create_user_marketplace.html.twig', [
'form' => $form->createView()
]);
}
/**
* @Route("/logout", name="app_logout_marketplace", host="%MARKETPLACE_HOST%")
*/
public function logoutMarketplace(): void
{
}
/**
* @Route("/expert/login/creation-de-compte", name="app_create_specialist")
*/
public function specialistUserCreation(Request $request, EntityManagerInterface $entityManager, SpecialistRepository $specialistRepo ): Response
{
$specialist = new Specialist();
$options = [
'pwd_required' => true,
'specialist_reg' => true,
];
$form = $this->createForm(SpecialistLightType::class, $specialist, $options);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$existingSpecialist = $specialistRepo->findOneBy(
[
'tel' => $specialist->getTel(),
]
);
if ($existingSpecialist == null) {
$validUuid = Uuid::v1();
$specialist->setIsVirtualEvent(true);
$specialist->getUser()->setActive(true);
$specialist->setSpecialistTags([]);
$specialist->setUuid($validUuid);
$specialist->setStatus(Specialist::STATUS_WAITING_MAIL_CONFIRMATION);
try {
$entityManager->persist($specialist);
$entityManager->flush();
$entityManager->refresh($specialist);
$this->emailService->sendSpecialistAccountConfirmation($specialist);
$this->addFlash('success', 'Un mail de confirmation vient de vous être envoyé. Afin de finaliser votre inscription veuillez cliquer sur le lien présent dans ce mail. A très vite sur ULTEAM pour découvrir nos opportunités');
return $this->redirectToRoute(SpecialistAuthenticator::LOGIN_ROUTE);
}catch (\Exception $e){
$this->addFlash('errorGlobal', 'Une erreur est survenue');
return $this->redirectToRoute(SpecialistAuthenticator::LOGIN_ROUTE);
}
}elseif ($existingSpecialist != null && $existingSpecialist->getStatus() == Specialist::STATUS_REFUSED) {
$this->addFlash('errorGlobal', 'Désolé mais la connexion à ton compte n\'est pas possible actuellement');
return $this->redirectToRoute(SpecialistAuthenticator::LOGIN_ROUTE);
}else {
$this->addFlash('errorGlobal', 'Un expert avec ce numero de téléphone existe déjà');
return $this->redirectToRoute(SpecialistAuthenticator::LOGIN_ROUTE);
}
}
return $this->render('security/create_specialist.html.twig', [
'regForm' => $form->createView(),
]);
}
/**
* @Route("/expert/login/validation-compte/{specialistUuid}", name="app_validate_specialist")
*/
public function expertUserValidate(Request $request, EntityManagerInterface $entityManager, SpecialistRepository $specialistRepo, string $specialistUuid ): Response
{
$specialist = $specialistRepo->findOneBy([
'uuid' => $specialistUuid
]);
if ($specialist instanceof Specialist ) {
$specialist->setStatus(Specialist::STATUS_WAITING_ULTEAM_CONFIRMATION);
$entityManager->persist($specialist);
$entityManager->flush();
$this->emailService->sendNewSpecialistNotificationToUlteam($specialist);
$this->addFlash('success', 'Félicitations, ton compte est à présent validé, tu peux te connecter et profiter des opportunités ULTEAM');
return $this->redirectToRoute(SpecialistAuthenticator::LOGIN_ROUTE);
}else {
$this->addFlash('errorGlobal', 'Une erreur est survenue');
return $this->redirectToRoute(SpecialistAuthenticator::LOGIN_ROUTE);
}
return $this->render('security/create_specialist.html.twig', [
]);
}
/**
* @Route("/expert/logout", name="app_specialist_logout")
*/
public function logoutSpecialist(): void
{
}
}