Browse Source
* More flexible headers for STOMP messages, theoretically. * Lower the priority of the base implementation. * More context. * Add in the "aud" claim. ... ensure we're dealing with our tokens. * Rectify the other base class. * Remove some chaff intro'd from merge conflicts. * Return after failing to find the "aud" claim. * Permissively allow without the "aud" claim... ... _could_ roll more conditionally, with some state set during an update hook; however, seems like unnecessary complexity. * Couple of coding standards things. * Add the use of the class back in.pull/851/head
Adam
3 years ago
committed by
GitHub
10 changed files with 299 additions and 167 deletions
@ -0,0 +1,97 @@
|
||||
<?php |
||||
|
||||
namespace Drupal\islandora\Event; |
||||
|
||||
use Drupal\Core\Entity\EntityInterface; |
||||
use Drupal\Core\Session\AccountInterface; |
||||
|
||||
use Symfony\Component\HttpFoundation\ParameterBag; |
||||
use Symfony\Component\EventDispatcher\Event; |
||||
|
||||
/** |
||||
* Event used to build headers for STOMP. |
||||
*/ |
||||
class StompHeaderEvent extends Event implements StompHeaderEventInterface { |
||||
|
||||
/** |
||||
* Stashed entity, for context. |
||||
* |
||||
* @var \Drupal\Core\Entity\EntityInterface |
||||
*/ |
||||
protected $entity; |
||||
|
||||
/** |
||||
* Stashed user info, for context. |
||||
* |
||||
* @var \Drupal\Core\Session\AccountInterface |
||||
*/ |
||||
protected $user; |
||||
|
||||
/** |
||||
* An array of data to be sent with the STOMP request, for context. |
||||
* |
||||
* @var array |
||||
*/ |
||||
protected $data; |
||||
|
||||
/** |
||||
* An array of configuration used to generate $data, for context. |
||||
* |
||||
* @var array |
||||
*/ |
||||
protected $configuration; |
||||
|
||||
/** |
||||
* The set of headers. |
||||
* |
||||
* @var \Symfony\Component\HttpFoundation\ParameterBag |
||||
*/ |
||||
protected $headers; |
||||
|
||||
/** |
||||
* Constructor. |
||||
*/ |
||||
public function __construct(EntityInterface $entity, AccountInterface $user, array $data, array $configuration) { |
||||
$this->entity = $entity; |
||||
$this->user = $user; |
||||
$this->data = $data; |
||||
$this->configuration = $configuration; |
||||
$this->headers = new ParameterBag(); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function getEntity() { |
||||
return $this->entity; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function getUser() { |
||||
return $this->user; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function getData() { |
||||
return $this->data; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function getHeaders() { |
||||
return $this->headers; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function getConfiguration() { |
||||
return $this->configuration; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,8 @@
|
||||
<?php |
||||
|
||||
namespace Drupal\islandora\Event; |
||||
|
||||
/** |
||||
* Typification for handling exceptions specific to STOMP header generation. |
||||
*/ |
||||
class StompHeaderEventException extends \Exception {} |
@ -0,0 +1,56 @@
|
||||
<?php |
||||
|
||||
namespace Drupal\islandora\Event; |
||||
|
||||
/** |
||||
* Contract for representing an event to build headers for STOMP messages. |
||||
*/ |
||||
interface StompHeaderEventInterface { |
||||
|
||||
const EVENT_NAME = 'islandora.stomp.header_event'; |
||||
|
||||
/** |
||||
* Get the headers being built for STOMP. |
||||
* |
||||
* XXX: Ironically, using ParameterBag instead of HeaderBag due to case- |
||||
* sensitivity: In the context of HTTP, headers are case insensitive (and is |
||||
* what HeaderBag is intended; however, STOMP headers are case sensitive. |
||||
* |
||||
* @return \Symfony\Component\HttpFoundation\ParameterBag |
||||
* The headers |
||||
*/ |
||||
public function getHeaders(); |
||||
|
||||
/** |
||||
* Fetch the entity provided as context. |
||||
* |
||||
* @return \Drupal\Core\Entity\EntityInterface |
||||
* The entity provided as context. |
||||
*/ |
||||
public function getEntity(); |
||||
|
||||
/** |
||||
* Fetch the user provided as context. |
||||
* |
||||
* @return \Drupal\Core\Session\AccountInterface |
||||
* The user provided as context. |
||||
*/ |
||||
public function getUser(); |
||||
|
||||
/** |
||||
* Fetch the data to be sent in the body of the request. |
||||
* |
||||
* @return array |
||||
* The array of data. |
||||
*/ |
||||
public function getData(); |
||||
|
||||
/** |
||||
* Fetch the configuration of the action, for context. |
||||
* |
||||
* @return array |
||||
* The array of configuration for the upstream action. |
||||
*/ |
||||
public function getConfiguration(); |
||||
|
||||
} |
@ -0,0 +1,63 @@
|
||||
<?php |
||||
|
||||
namespace Drupal\islandora\EventSubscriber; |
||||
|
||||
use Drupal\islandora\Event\StompHeaderEventInterface; |
||||
use Drupal\jwt\Authentication\Provider\JwtAuth; |
||||
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait; |
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
||||
|
||||
/** |
||||
* Base STOMP header listener. |
||||
*/ |
||||
class StompHeaderEventSubscriber implements EventSubscriberInterface { |
||||
|
||||
use StringTranslationTrait; |
||||
|
||||
/** |
||||
* The JWT auth service. |
||||
* |
||||
* @var \Drupal\jwt\Authentication\Provider\JwtAuth |
||||
*/ |
||||
protected $auth; |
||||
|
||||
/** |
||||
* Constructor. |
||||
*/ |
||||
public function __construct( |
||||
JwtAuth $auth |
||||
) { |
||||
$this->auth = $auth; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public static function getSubscribedEvents() { |
||||
return [ |
||||
StompHeaderEventInterface::EVENT_NAME => ['baseAuth', -100], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* 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"); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue