<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use App\Entity\Slave\User;
use App\Service\CompanyService;
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_CHECK_ROUTE = 'login_check';
public const LOGIN_ROUTE = 'login';
public const LOGIN_REDIRECT_ROUTE = 'login_redirect';
public const ADMIN_ROUTE = 'admin_index';
public const USER_ROUTE = 'user_index';
private UrlGeneratorInterface $urlGenerator;
private ManagerRegistry $mr;
private ParameterBagInterface $params;
public function __construct(UrlGeneratorInterface $urlGenerator, ManagerRegistry $managerRegistry, ParameterBagInterface $params)
{
$this->urlGenerator = $urlGenerator;
$this->mr = $managerRegistry;
$this->params = $params;
}
public function supports(Request $request): bool
{
return self::LOGIN_CHECK_ROUTE === $request->attributes->get('_route') && $request->isMethod('POST');
}
public function authenticate(Request $request): Passport
{
$email = $request->request->get('email', '');
$code = $request->request->get('code', '');
if($code == null && isset($_COOKIE["eposm_company_code"]))
$code = $_COOKIE["eposm_company_code"];
$request->getSession()->set('companyCode', $code);
$request->getSession()->set(Security::LAST_USERNAME, $email);
if($email != "admin"){
if($code != null){
$emMaster = $this->mr->getManager('master');
$company = $emMaster->getRepository('App\Entity\Master\Company')->findOneByCode($code);
setcookie("eposm_company_code", $code, time() + 1209600, "/");
$request->getSession()->set('companyId', $company->getId());
$em = CompanyService::getSlaveManagerByCompany($this->mr, $this->params, $company);
$userBadge = new UserBadge($email);
}
else{
$userBadge = new UserBadge($email, function() { return false; });
forceLogout();
return $this->urlGenerator->generate(self::LOGIN_REDIRECT_ROUTE);
}
}
else {
$userBadge = new UserBadge($email);
}
return new Passport(
$userBadge,
new PasswordCredentials($request->request->get('password', '')),
[
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
new RememberMeBadge(),
]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
if($token->getUser() instanceof User){
if($token->getUser()->getRole() == "ROLE_USER")
return new RedirectResponse($this->urlGenerator->generate(self::USER_ROUTE));
else
return new RedirectResponse($this->urlGenerator->generate(self::LOGIN_ROUTE, array('companyCode' => $request->getSession()->get('companyCode'))));
}
else{
if(in_array("ROLE_ADMIN", $token->getUser()->getRoles()))
return new RedirectResponse($this->urlGenerator->generate(self::ADMIN_ROUTE));
}
return $this->urlGenerator->generate(self::LOGIN_ROUTE, array('companyCode' => $request->getSession()->get('companyCode')));
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE, array('companyCode' => $request->getSession()->get('companyCode')));
}
protected function forceLogout(): void
{
$logoutEvent = new LogoutEvent($this->requestStack->getCurrentRequest(), $this->tokenStorage->getToken());
$this->eventDispatcher->dispatch($logoutEvent);
$this->tokenStorage->setToken(null);
$response = new Response();
$response->headers->clearCookie('REMEMBERME');
$response->send();
}
}