<?php
namespace App\Security;
use App\Entity\User;
use App\Exception\SiteClosedException;
use App\Services\ScheduleService;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
use Symfony\Contracts\Translation\TranslatorInterface;
class ScheduleAuthenticator extends AbstractAuthenticator
{
use TargetPathTrait;
public const CLOSED_ROUTE = 'site_closed';
private TranslatorInterface $translator;
private Security $security;
private ScheduleService $scheduleService;
private RouterInterface $router;
public function __construct(
TranslatorInterface $translator,
Security $security,
ScheduleService $scheduleService,
RouterInterface $router
) {
$this->security = $security;
$this->translator = $translator;
$this->scheduleService = $scheduleService;
$this->router = $router;
}
public function supports(Request $request): ?bool
{
//dd('supports');
$authorizedRoutes = ['app_login', 'app_logout', 'site_closed'];
if (in_array($request->attributes->get('_route'), $authorizedRoutes)) {
return false;
}
return !$this->security->isGranted('ROLE_SAAS') && !$this->security->isGranted('ROLE_OWNER');
}
public function authenticate(Request $request): PassportInterface
{
return new Passport(
new UserBadge('', function () {
return $this->security->getUser();
}),
new CustomCredentials(function ($credentials, User $user) {
if ($this->scheduleService->isSiteClosed($user)) {
throw new SiteClosedException($this->translator->trans('site_closed'));
}
return true;
}, null)
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
if ($exception instanceof SiteClosedException) {
return new RedirectResponse($this->router->generate(self::CLOSED_ROUTE));
}
return null;
}
}