src/Cms/TenantBundle/Listener/PolicyListener.php line 60

Open in your IDE?
  1. <?php
  2. namespace Cms\TenantBundle\Listener;
  3. use Cms\CoreBundle\Service\ContextManager;
  4. use Cms\TenantBundle\Controller\Dashboard\PolicyController;
  5. use Cms\TenantBundle\Entity\TenantTypeEmbeddable;
  6. use DateTimeImmutable;
  7. use Platform\SecurityBundle\Controller\LoginController;
  8. use Platform\SecurityBundle\Controller\SingleSignOnController;
  9. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  10. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  11. use Symfony\Component\HttpFoundation\RedirectResponse;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpKernel\Config\FileLocator;
  14. use Symfony\Component\HttpKernel\Event\RequestEvent;
  15. use Symfony\Component\HttpKernel\KernelEvents;
  16. use Symfony\Component\Routing\RouterInterface;
  17. final class PolicyListener implements EventSubscriberInterface
  18. {
  19.     // DI
  20.     protected ContextManager $contextManager;
  21.     protected RouterInterface $router;
  22.     protected FileLocator $locator;
  23.     protected ParameterBagInterface $params;
  24.     /**
  25.      * @param ContextManager $contextManager
  26.      * @param RouterInterface $router
  27.      * @param FileLocator $locator
  28.      * @param ParameterBagInterface $params
  29.      */
  30.     public function __construct(
  31.         ContextManager $contextManager,
  32.         RouterInterface $router,
  33.         FileLocator $locator,
  34.         ParameterBagInterface $params
  35.     )
  36.     {
  37.         $this->contextManager $contextManager;
  38.         $this->router $router;
  39.         $this->locator $locator;
  40.         $this->params $params;
  41.     }
  42.     /**
  43.      * {@inheritdoc}
  44.      */
  45.     public static function getSubscribedEvents(): array
  46.     {
  47.         return [
  48.             KernelEvents::REQUEST => ['onKernelRequest'],
  49.         ];
  50.     }
  51.     /**
  52.      * @param RequestEvent $event
  53.      */
  54.     public function onKernelRequest(RequestEvent $event): void
  55.     {
  56.         static $skipRoutes = [
  57.             PolicyController::ROUTES__VIEW,
  58.             PolicyController::ROUTES__ACCEPT,
  59.             PolicyController::ROUTES__TERMS,
  60.             PolicyController::ROUTES__TERMS_ACCEPT,
  61.             LoginController::ROUTES__SELECT,
  62.             SingleSignOnController::ROUTES__START,
  63.             SingleSignOnController::ROUTES__FINISH,
  64.             'app.platform.security.logout',
  65.         ];
  66.         // see if we are working with the main request
  67.         $request $event->getRequest();
  68.         if ( ! $event->isMainRequest()) {
  69.             return;
  70.         }
  71.         // there are certain urls we don't want covered by the policy
  72.         if (in_array($request->get('_route'), $skipRoutestrue)) {
  73.             return;
  74.         }
  75.         // obtain the tenant
  76.         $tenant $this->contextManager->getGlobalContext()->getTenant();
  77.         if ( ! $tenant) {
  78.             return;
  79.         }
  80.         // if we are currently impersonating a user, we don't want this person to accept the policy on their behalf.
  81.         // in this case we want to skip if impersonation is active, otherwise, pull the user
  82.         if ($this->contextManager->getGlobalContext()->isImpersonating()) {
  83.             return;
  84.         }
  85.         $currentUser $this->contextManager->getGlobalContext()->getAuthenticatedAccount();
  86.         if ( ! $currentUser) {
  87.             return;
  88.         }
  89.         if ( ! $request->isMethod(Request::METHOD_GET)) {
  90.             return;
  91.         }
  92.         if ($request->isXmlHttpRequest()) {
  93.             return;
  94.         }
  95.         // check our company policy first
  96.         $timestamp DateTimeImmutable::createFromFormat(
  97.             DATE_ISO8601,
  98.             $this->params->get('cms.core.policies.ferpa.timestamp')
  99.         );
  100.         // go ahead and check if the timestamps match or has not been accepted yet
  101.         // redirect if this person needs to accept our policy
  102.         if ($tenant->getType()->getPrimary() !== TenantTypeEmbeddable::PRIMARY__CDD) {
  103.             if ( ! $currentUser->getTermsAcceptedOn() || $currentUser->getTermsAcceptedOn() < $timestamp) {
  104.                 $event->setResponse(
  105.                     new RedirectResponse($this->router->generate(PolicyController::ROUTES__TERMS))
  106.                 );
  107.                 return;
  108.             }
  109.         }
  110.         // if the tenant doesn't have a policy, nothing to do
  111.         if ( ! $tenant->getPolicy()) {
  112.             return;
  113.         }
  114.         // if there is a policy, and it has not yet been accepted or is out-of-date, redirect to review it and accept
  115.         if ( ! $currentUser->getPolicyAcceptedOn() || $currentUser->getPolicyAcceptedOn() < $tenant->getPolicy()) {
  116.             $event->setResponse(
  117.                 new RedirectResponse($this->router->generate(PolicyController::ROUTES__VIEW))
  118.             );
  119.         }
  120.     }
  121. }