<?php
namespace PaperKite\Common\Controller;
use Lightbulb\Symfony\Exception\ServiceUnavailableException;
use LogicException;
use OneLogin\Saml2\Error;
use OneLogin\Saml2\ValidationError;
use PaperKite\EmployeeApi\Service\EmployeeAuthenticationService;
use PaperKite\EmployeeApi\Service\SamlService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
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\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken;
class SecurityController extends AbstractController
{
#[Route(path: '/login', name: 'security_login')]
public function login(AuthenticationUtils $authenticationUtils, SamlService $samlService): 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('@EasyAdmin/page/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
'csrf_token_intention' => 'authenticate',
'page_title' => 'Connexion',
'target_path' => $this->generateUrl('admin_dashboard'),
'username_label' => 'Username',
'password_label' => 'Password',
'username_parameter' => 'username',
'password_parameter' => 'password',
'forgot_password_enabled' => true,
'forgot_password_path' => $samlService->getSsoLoginUrl(),
'forgot_password_label' => 'SSO Login',
]);
}
/**
* @throws ValidationError
* @throws ServiceUnavailableException
* @throws Error
*/
#[Route(name: 'employee_sso_login_check', methods: ['POST'])]
public function postSsoLoginToken(Request $request, SamlService $samlService, EmployeeAuthenticationService $employeeAuthenticationService, TokenStorageInterface $tokenStorage): RedirectResponse
{
$employee = $samlService->handleSamlToken();
if (str_contains($request->get('RelayState'), 'employee-api')) {
$authCode = $employeeAuthenticationService->setAuthCode($employee);
return new RedirectResponse($this->getParameter('app_url') . $this->getParameter('app_sso_login_route') . '?authCode=' . $authCode);
} else {
// Manually authenticate the user for web interface
$token = new PostAuthenticationToken($employee, 'main', $employee->getRoles());
$tokenStorage->setToken($token);
return new RedirectResponse($this->generateUrl('admin_dashboard'));
}
}
#[Route(path: '/logout', name: 'security_logout')]
public function logout()
{
throw new LogicException('This should never be reached!');
}
}