<?php
namespace App\Controller;
use App\Form\LoginConstituentInfoForm;
use App\Form\LoginForm;
use App\Form\LoginTokenForm;
use App\Form\ResetpassForm;
use App\Service\TessituraBundle\CartService;
use App\Service\TessituraBundle\ConstituentService;
use App\Service\TessituraBundle\TessituraUserProvider;
use App\Service\TessituraSDK\Entity\User;
use App\Service\TessituraSDK\Resource\Web\Session;
use App\Service\TessituraSDK\TessituraClient;
use App\Service\TessituraSDK\TessituraClientException;
use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
class SecurityController extends AbstractController
{
/**
* @var TessituraClient
*/
protected $client;
/**
* @var User
*/
protected $user;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var ParameterBagInterface
*/
private $params;
/**
* SecurityController constructor.
*
* @param TessituraClient $client
* @param TranslatorInterface $translator
* @param ParameterBagInterface $params
*/
public function __construct(TessituraClient $client, TranslatorInterface $translator, ParameterBagInterface $params)
{
$this->client = $client;
$this->translator = $translator;
$this->params = $params;
}
/**
* @Route(
* "/{_locale}/login/",
* name="login",
* defaults={
* "_locale": "fi"
* },
* requirements={
* "_locale": "fi|sv|en"
* }
* )
* @param Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function loginAction(Request $request, CartService $cartService, AuthenticationUtils $authenticationUtils)
{
/**
* Get previous authentication data
*/
/** @var AuthenticationUtils $authenticationUtils */
//$authenticationUtils = $this->get('security.authentication_utils');
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
/**
* Get LoginForm, the form is handled by TessituraGuardAuthenticator
*/
$form = $this->createForm(LoginForm::class, [
'_email' => $lastUsername
]);
if ($error) {
$form->addError(new FormError($error->getMessage()));
}
$fromStage24 = !!preg_match('/stage24/', $request->getUri());
/**
* Render
*/
return $this->render('page/login.html.twig', [
'form' => $form->createView(),
'source' => $fromStage24 ? 'stage24' : null,
]);
}
/**
* @Route(
* "/{_locale}/login/constituent/",
* name="login-constituent",
* defaults={
* "_locale": "fi"
* },
* requirements={
* "_locale": "fi|sv|en"
* }
* )
* @param Request $request
* @param KernelInterface $kernel
* @param AuthenticationUtils $authenticationUtils
* @return \Symfony\Component\HttpFoundation\Response
*/
public function loginConstituentInfoAction(Request $request, KernelInterface $kernel, AuthenticationUtils $authenticationUtils)
{
// if ($kernel->getEnvironment() !== 'dev') {
// NOT SUPPOSED TO BE USED ANYWHERE
throw $this->createNotFoundException();
// }
/**
* Get previous authentication data
*/
//$authenticationUtils = $this->get('security.authentication_utils');
$error = $authenticationUtils->getLastAuthenticationError();
/**
* Get LoginForm, the form is handled by TessituraGuardAuthenticator
*/
$form = $this->createForm(LoginConstituentInfoForm::class, []);
if ($error) {
$form->addError(new FormError($this->translator->trans("user_invalid")));
}
/**
* Render
*/
return $this->render('page/login.html.twig', [
'form' => $form->createView()
]);
}
/**
* @Route(
* "/{_locale}/login/external/",
* name="login-external",
* defaults={
* "_locale": "fi"
* },
* requirements={
* "_locale": "fi|sv|en"
* }
* )
* @param Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
* @throws TessituraClientException
*/
public function loginExternalAction(Request $request)
{
$redirect = $request->get('redirect');
$validRedirectDomains = [
$request->getSchemeAndHttpHost(),
$this->params->get('wp.domain'),
$this->params->get('osajaot.domain'),
];
$valid = false;
foreach ($validRedirectDomains as $domain) {
if (strpos($redirect, $domain) === 0) {
$valid = true;
}
}
if (strpos($redirect, 'login/external')) {
$valid = false;
}
if ($valid) {
return new RedirectResponse($redirect);
} else {
return $this->redirectToRoute('login');
}
}
/**
* @Route(
* "/{_locale}/login/token/",
* name="login-token",
* defaults={
* "_locale": "fi"
* },
* requirements={
* "_locale": "fi|sv|en"
* }
* )
* @param Request $request
* @param TessituraUserProvider $userProvider
* @param AuthenticationUtils $authenticationUtils
* @return \Symfony\Component\HttpFoundation\Response
*/
public function tokenLoginAction(Request $request, TessituraUserProvider $userProvider, AuthenticationUtils $authenticationUtils)
{
//return $this->redirectToRoute('login');
/**
* Get previous authentication data
*/
//$authenticationUtils = $this->get('security.authentication_utils');
$error = $authenticationUtils->getLastAuthenticationError();
/**
* Get LoginForm, the form is handled by TessituraGuardAuthenticator
*/
$form = $this->createForm(LoginTokenForm::class, [
]);
if ($error) {
$form->addError(new FormError($this->translator->trans("user_invalid")));
}
/**
* Render
*/
return $this->render('page/login-token.html.twig', [
'form' => $form->createView()
]);
}
/**
* @Route(
* "/{_locale}/account/logout/",
* name="account-logout",
* defaults={
* "_locale": "fi"
* },
* requirements={
* "_locale": "fi|sv|en"
* }
* )
* @param Request $request
* @param ConstituentService $constituentService
* @param CartService $cartService
*
* @param ContainerInterface $container
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws TessituraClientException
*/
public function logoutAction(
Request $request,
ConstituentService $constituentService,
CartService $cartService,
ContainerInterface $container,
Security $security,
TokenStorageInterface $tokenStorage,
) {
/** @var User $user */
$user = $security->getUser();
$cache = $container->get('cache.app');
$cache->invalidateTags([$constituentService->getCacheKey(), $cartService->getCacheKey()]);
/**
* Logout in Tessitura
*/
$session = $request->getSession();
if (!$session->has('tessitura_session')) {
$this->client->request(Session::logout($session->get('tessitura_session')));
}
/**
* Invalidate token and session storage
*/
$tokenStorage->setToken(null);
// $this->get('security.token_storage')->setToken(null);
$request->getSession()->invalidate();
/**
* Redirect to login
*/
return $this->redirectToRoute('login');
}
/**
* @Route(
* "/{_locale}/resetpass/",
* name="resetpass",
* defaults={
* "_locale": "fi"
* },
* requirements={
* "_locale": "fi|sv|en"
* }
* )
* @param Request $request
* @param AuthenticationUtils $authenticationUtils
* @return \Symfony\Component\HttpFoundation\Response
* @throws TessituraClientException
*/
public function resetPassAction(Request $request, AuthenticationUtils $authenticationUtils)
{
// TODO: Handler Resetpass
/** @var User $user */
$user = $this->get('security.token_storage')->getToken()->getUser();
/**
* Get previous authentication data
*/
//$authenticationUtils = $this->get('security.authentication_utils');
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
/**
* Get LoginForm, the form is handled by TessituraGuardAuthenticator
*/
$form = $this->createForm(ResetpassForm::class, [
'email' => $lastUsername
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$data = $form->getData();
$response = $this->client->request(Session::sendLoginCredentials($user->getSessionKey(), [
'EmailAddress' => $data['email'],
'LoginTypeId' => $this->params->get('tessitura.logintype'),
]));
$form->addError(new FormError($this->translator->trans("resetpass_sent")));
} catch (TessituraClientException $exception) {
switch ($exception->getCode()) {
case TessituraClientException::TESSITURA_LOGIN_NOT_FOUND:
$form->addError(new FormError($this->translator->trans("resetpass_invalid")));
break;
default:
throw $exception;
}
}
}
return $this->render('page/resetpass.html.twig', [
'form' => $form->createView()
]);
}
}