docusign_signature-1.0.x-dev/src/EventSubscriber/AccessDeniedSubscriber.php
src/EventSubscriber/AccessDeniedSubscriber.php
<?php
declare(strict_types=1);
namespace Drupal\docusign_signature\EventSubscriber;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Routing\RouteMatch;
use Drupal\docusign_signature\AuthInterface;
use Drupal\docusign_signature\AuthManagerInterface;
use Drupal\docusign_signature\Services\SignatureClient;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Route;
/**
* Redirects users when access is denied.
*
* Anonymous users are taken to the DocuSign login page when attempting to access a
* DocuSign signature pages.
*/
class AccessDeniedSubscriber implements EventSubscriberInterface {
/**
* The authentication service.
*
* @var \Drupal\docusign_signature\AuthInterface
*/
protected AuthInterface $authService;
/**
* DocuSign signature client.
*
* @var \Drupal\docusign_signature\Services\SignatureClient
*/
protected SignatureClient $client;
/**
* DocuSign module configuration.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected ImmutableConfig $config;
/**
* Constructs a new redirect subscriber.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\docusign_signature\AuthManagerInterface $auth_manager
* The DocuSign authentication manager service.
* @param \Drupal\docusign_signature\Services\SignatureClient $signature_client
* The DocuSign signature client.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
public function __construct(
ConfigFactoryInterface $config_factory,
AuthManagerInterface $auth_manager,
SignatureClient $signature_client
) {
$this->client = $signature_client;
$this->config = $config_factory->get('docusign_signature.settings');
// Initialize authentication service.
$this->authService = $auth_manager->createInstance(
$this->config->get('auth_service')
);
}
/**
* Redirects users when access is denied.
*
* @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
* The event to process.
*/
public function onException(ExceptionEvent $event): void {
$exception = $event->getThrowable();
if ($exception instanceof AccessDeniedHttpException) {
$route = RouteMatch::createFromRequest($event->getRequest())->getRouteObject();
// If route has DocuSign access token requirement.
if (
$route instanceof Route &&
$route->hasRequirement('_docusign_access_token_is_valid')
) {
$required_status = filter_var($route->getRequirement('_docusign_access_token_is_valid'), FILTER_VALIDATE_BOOLEAN);
if ($required_status) {
$event->setResponse($this->client->needToReAuth());
}
}
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
// Use a higher priority than
// \Drupal\Core\EventSubscriber\ExceptionLoggingSubscriber, because there's
// no need to log the exception if we can redirect.
$events[KernelEvents::EXCEPTION][] = ['onException', 75];
return $events;
}
}
