<?php
namespace App\EventListener;
use App\Enum\User\UserRestrictionsEnum;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use App\Entity\User;
use App\Entity\Location;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Security;
use App\Service\DatabaseService;
use App\Service\UserAccessService;
class RequestListener
{
/**
* @var RouterInterface
*/
private $router;
/**
* @var Security
*/
private $security;
/**
* @var DatabaseService
*/
private $databaseService;
/**
* @var UserAccessService
*/
private $userAccessService;
public function __construct(RouterInterface $router, Security $security, DatabaseService $databaseService, UserAccessService $userAccessService) {
$this->router = $router;
$this->security = $security;
$this->databaseService = $databaseService;
$this->userAccessService = $userAccessService;
}
public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
$path = $request->getPathInfo();
$user = $this->security->getUser();
if (!$user instanceof User) {
return;
}
if ($path === "/login" && $request->getSession()->isStarted()) {
/** @var User $user */
$user = $this->databaseService->getManager()->getRepository(User::class)->findOneBy(["username" =>$user->getUsername()]);
$activeLocations = $user->getActiveLocations();
if($activeLocations->isEmpty()) {
if ($user->isHatchAdministrator()) {
$event->setResponse(new RedirectResponse($this->router->generate('admin_index')));
return;
} else {
$event->getRequest()->getSession()->getFlashBag()->add('error', "No active locations for login");
return;
}
}
$defaultLocation = $user->getDefaultLocation();
if ( $defaultLocation instanceof Location && $activeLocations->contains($defaultLocation) ) {
$event->setResponse(new RedirectResponse($this->router->generate('client_index', ['locationId' =>$defaultLocation->getId()])));
return;
}
if($user->isHatchAdministrator()) {
$event->setResponse(new RedirectResponse($this->router->generate('admin_index')));
return;
} elseif ($activeLocations->count() === 1) {
$event->setResponse(new RedirectResponse($this->router->generate('client_index', ['locationId' =>$activeLocations->first()->getId()])));
return;
} else {
$event->setResponse(new RedirectResponse($this->router->generate('location_login_select')));
return;
}
}
if (str_starts_with($path, '/admin')) {
if ($user->isHatchAdministrator() && $user->hasRestrictions()) {
$restrictionsMap = UserRestrictionsEnum::getRestrictionsMap();
$userRestrictions = $user->getRestrictions();
$allowedPaths = [];
$redirectRoute = 'app_login';
foreach ($userRestrictions as $restriction) {
if (isset($restrictionsMap[$restriction])) {
$allowedPaths = array_merge($allowedPaths, $restrictionsMap[$restriction]['paths']);
if ($redirectRoute === 'app_login') {
$redirectRoute = $restrictionsMap[$restriction]['redirect_route'];
}
}
}
$isAllowed = false;
foreach ($allowedPaths as $allowedPath) {
if (str_starts_with($path, $allowedPath)) {
$isAllowed = true;
break;
}
}
if (!$isAllowed) {
$event->setResponse(new RedirectResponse($this->router->generate($redirectRoute)));
return;
}
} elseif (!$user->isHatchAdministrator()) {
$event->setResponse(new RedirectResponse($this->router->generate('app_login')));
return;
}
}
if (str_starts_with($path, '/client')) {
$locationId = $request->attributes->get('locationId');
if ($locationId) {
$location = $this->databaseService->getManager()->getRepository(Location::class)->find($locationId);
if ($location instanceof Location && $location->getCompany() && $location->getCompany()->isBillingHold()) {
$firstValidLocation = $this->userAccessService->getFirstActiveLocationInFirstNonBillingHoldCompany($user);
$companyName = $location->getCompany()->getName();
$request->getSession()->getFlashBag()->add(
'error',
sprintf(
'Payment is Past Due for %s. Please submit payment to regain access. For any questions, please contact ComplianceBilling@KipuHealth.com.',
$companyName
)
);
if ($firstValidLocation) {
$event->setResponse(
new RedirectResponse(
$this->router->generate('client_index', ['locationId' => $firstValidLocation->getId()])
)
);
}
}
}
}
}
}