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