diff --git a/islandora.services.yml b/islandora.services.yml index 39ebbab0..4b3a9d16 100644 --- a/islandora.services.yml +++ b/islandora.services.yml @@ -54,3 +54,8 @@ services: arguments: ['@entity_type.manager', '@entity_field.manager', '@context.manager', '@flysystem_factory', '@language_manager'] islandora.entity_mapper: class: Islandora\Crayfish\Commons\EntityMapper\EntityMapper + islandora.stomp.auth_header_listener: + class: Drupal\islandora\EventSubscriber\StompHeaderEventSubscriber + arguments: ['@jwt.authentication.jwt'] + tags: + - { name: event_subscriber } diff --git a/src/Event/StompHeaderEvent.php b/src/Event/StompHeaderEvent.php new file mode 100644 index 00000000..997b9b1c --- /dev/null +++ b/src/Event/StompHeaderEvent.php @@ -0,0 +1,67 @@ +entity = $entity; + $this->user = $user; + $this->headers = new ParameterBag(); + } + + /** + * {@inheritdoc} + */ + public function getEntity() { + return $this->entity; + } + + /** + * {@inheritdoc} + */ + public function getUser() { + return $this->user; + } + + /** + * {@inheritdoc} + */ + public function getHeaders() { + return $this->headers; + } + +} diff --git a/src/Event/StompHeaderEventException.php b/src/Event/StompHeaderEventException.php new file mode 100644 index 00000000..c9ee3878 --- /dev/null +++ b/src/Event/StompHeaderEventException.php @@ -0,0 +1,8 @@ +account = $account; $this->entityTypeManager = $entity_type_manager; $this->eventGenerator = $event_generator; $this->stomp = $stomp; - $this->auth = $auth; $this->messenger = $messenger; + $this->eventDispatcher = $event_dispatcher; } /** @@ -119,8 +119,8 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact $container->get('entity_type.manager'), $container->get('islandora.eventgenerator'), $container->get('islandora.stomp'), - $container->get('jwt.authentication.jwt'), - $container->get('messenger') + $container->get('messenger'), + $container->get('event_dispatcher') ); } @@ -128,29 +128,26 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact * {@inheritdoc} */ public function execute($entity = NULL) { - - // Include a token for later authentication in the message. - $token = $this->auth->generateToken(); - if (empty($token)) { - // JWT isn't properly configured. Log and notify user. - \Drupal::logger('islandora')->error( - $this->t('Error getting JWT token for message. Check JWT Configuration.') - ); - $this->messenger->addMessage( - $this->t('Error getting JWT token for message. Check JWT Configuration.'), 'error' - ); - return; - } - // Generate event as stomp message. try { $user = $this->entityTypeManager->getStorage('user')->load($this->account->id()); $data = $this->generateData($entity); + + $event = $this->eventDispatcher->dispatch( + StompHeaderEvent::EVENT_NAME, + new StompHeaderEvent($entity, $user) + ); + $message = new Message( $this->eventGenerator->generateEvent($entity, $user, $data), - ['Authorization' => "Bearer $token"] + $event->getHeaders()->all() ); } + catch (StompHeaderEventException $e) { + \Drupal::logger('islandora')->error($e->getMessage()); + $this->messenger->addMessage($e->getMessage(), 'error'); + return; + } catch (\RuntimeException $e) { // Notify the user the event couldn't be generated and abort. \Drupal::logger('islandora')->error( diff --git a/src/EventSubscriber/StompHeaderSubscriber.php b/src/EventSubscriber/StompHeaderSubscriber.php new file mode 100644 index 00000000..a93e48ae --- /dev/null +++ b/src/EventSubscriber/StompHeaderSubscriber.php @@ -0,0 +1,61 @@ +auth = $auth; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + return [ + StompHeaderEventInterface::EVENT_NAME => 'baseAuth', + ]; + } + + /** + * Event callback; generate and add base authorization header if none is set. + */ + public function baseAuth(StompHeaderEventInterface $stomp_event) { + $headers = $stomp_event->getHeaders(); + if (!$headers->has('Authorization')) { + $token = $this->auth->generateToken(); + if (empty($token)) { + // JWT does not seem to be properly configured. + // phpcs:ignore DrupalPractice.General.ExceptionT.ExceptionT + throw new StompHeaderEventException($this->t('Error getting JWT token for message. Check JWT Configuration.')); + } + else { + $headers->set('Authorization', "Bearer $token"); + } + } + + } +} diff --git a/src/Plugin/Action/AbstractGenerateDerivative.php b/src/Plugin/Action/AbstractGenerateDerivative.php index b22201e1..36801609 100644 --- a/src/Plugin/Action/AbstractGenerateDerivative.php +++ b/src/Plugin/Action/AbstractGenerateDerivative.php @@ -2,9 +2,15 @@ namespace Drupal\islandora\Plugin\Action; +use Drupal\islandora\EventGenerator\EmitEvent; +use Drupal\islandora\IslandoraUtils; +use Drupal\islandora\MediaSource\MediaSourceService; +use Drupal\token\TokenInterface; + use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Emits a Node event. diff --git a/src/Plugin/Action/EmitFileEvent.php b/src/Plugin/Action/EmitFileEvent.php index cd20b3d5..f6f598f4 100644 --- a/src/Plugin/Action/EmitFileEvent.php +++ b/src/Plugin/Action/EmitFileEvent.php @@ -2,17 +2,11 @@ namespace Drupal\islandora\Plugin\Action; +use Drupal\islandora\EventGenerator\EmitEvent; + use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\File\FileSystemInterface; -use Drupal\Core\Messenger\MessengerInterface; -use Drupal\Core\Session\AccountInterface; use Drupal\Core\Site\Settings; -use Drupal\Core\StreamWrapper\StreamWrapperManager; -use Drupal\jwt\Authentication\Provider\JwtAuth; -use Drupal\islandora\EventGenerator\EmitEvent; -use Drupal\islandora\EventGenerator\EventGeneratorInterface; -use Stomp\StatefulStomp; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -34,52 +28,9 @@ class EmitFileEvent extends EmitEvent { protected $fileSystem; /** - * Constructs a EmitEvent action. - * - * @param array $configuration - * A configuration array containing information about the plugin instance. - * @param string $plugin_id - * The plugin_id for the plugin instance. - * @param mixed $plugin_definition - * The plugin implementation definition. - * @param \Drupal\Core\Session\AccountInterface $account - * Current user. - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * Entity type manager. - * @param \Drupal\islandora\EventGenerator\EventGeneratorInterface $event_generator - * EventGenerator service to serialize AS2 events. - * @param \Stomp\StatefulStomp $stomp - * Stomp client. - * @param \Drupal\jwt\Authentication\Provider\JwtAuth $auth - * JWT Auth client. - * @param \Drupal\Core\File\FileSystemInterface $file_system - * File system service. - * @param \Drupal\Core\Messenger\MessengerInterface $messenger - * The messenger. + * Setter for the file system service. */ - public function __construct( - array $configuration, - $plugin_id, - $plugin_definition, - AccountInterface $account, - EntityTypeManagerInterface $entity_type_manager, - EventGeneratorInterface $event_generator, - StatefulStomp $stomp, - JwtAuth $auth, - FileSystemInterface $file_system, - MessengerInterface $messenger - ) { - parent::__construct( - $configuration, - $plugin_id, - $plugin_definition, - $account, - $entity_type_manager, - $event_generator, - $stomp, - $auth, - $messenger - ); + public function setFileSystemService(FileSystemInterface $file_system) { $this->fileSystem = $file_system; } @@ -87,18 +38,11 @@ class EmitFileEvent extends EmitEvent { * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('current_user'), - $container->get('entity_type.manager'), - $container->get('islandora.eventgenerator'), - $container->get('islandora.stomp'), - $container->get('jwt.authentication.jwt'), - $container->get('file_system'), - $container->get('messenger') - ); + $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); + + $instance->setFileSystemService($container->get('file_system')); + + return $instance; } /** diff --git a/src/Plugin/Action/EmitMediaEvent.php b/src/Plugin/Action/EmitMediaEvent.php index 275dd510..294f9aea 100644 --- a/src/Plugin/Action/EmitMediaEvent.php +++ b/src/Plugin/Action/EmitMediaEvent.php @@ -3,14 +3,8 @@ namespace Drupal\islandora\Plugin\Action; use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Messenger\MessengerInterface; -use Drupal\Core\Session\AccountInterface; -use Drupal\jwt\Authentication\Provider\JwtAuth; use Drupal\islandora\EventGenerator\EmitEvent; -use Drupal\islandora\EventGenerator\EventGeneratorInterface; use Drupal\islandora\MediaSource\MediaSourceService; -use Stomp\StatefulStomp; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -31,72 +25,15 @@ class EmitMediaEvent extends EmitEvent { */ protected $mediaSource; - /** - * Constructs a EmitEvent action. - * - * @param array $configuration - * A configuration array containing information about the plugin instance. - * @param string $plugin_id - * The plugin_id for the plugin instance. - * @param mixed $plugin_definition - * The plugin implementation definition. - * @param \Drupal\Core\Session\AccountInterface $account - * Current user. - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * Entity type manager. - * @param \Drupal\islandora\EventGenerator\EventGeneratorInterface $event_generator - * EventGenerator service to serialize AS2 events. - * @param \Stomp\StatefulStomp $stomp - * Stomp client. - * @param \Drupal\jwt\Authentication\Provider\JwtAuth $auth - * JWT Auth client. - * @param \Drupal\islandora\MediaSource\MediaSourceService $media_source - * Media source service. - * @param \Drupal\Core\Messenger\MessengerInterface $messenger - * The messenger. - */ - public function __construct( - array $configuration, - $plugin_id, - $plugin_definition, - AccountInterface $account, - EntityTypeManagerInterface $entity_type_manager, - EventGeneratorInterface $event_generator, - StatefulStomp $stomp, - JwtAuth $auth, - MediaSourceService $media_source, - MessengerInterface $messenger - ) { - parent::__construct( - $configuration, - $plugin_id, - $plugin_definition, - $account, - $entity_type_manager, - $event_generator, - $stomp, - $auth, - $messenger - ); - $this->mediaSource = $media_source; - } - /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('current_user'), - $container->get('entity_type.manager'), - $container->get('islandora.eventgenerator'), - $container->get('islandora.stomp'), - $container->get('jwt.authentication.jwt'), - $container->get('islandora.media_source_service'), - $container->get('messenger') - ); + $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); + + $instance->setMediaSourceService($container->get('islandora.media_source_service')); + + return $instance; } /** @@ -108,4 +45,11 @@ class EmitMediaEvent extends EmitEvent { return $data; } + /** + * Setter for the media source service. + */ + public function setMediaSourceService(MediaSourceService $media_source) { + $this->mediaSource = $media_source; + } + }