Loading src/Controller/SamlController.php +11 −4 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Path\PathValidatorInterface; use Drupal\Core\Render\RendererInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\Core\Utility\Error; use Drupal\Core\Utility\Token; Loading @@ -28,6 +29,7 @@ use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; class SamlController extends ControllerBase { use ExecuteInRenderContextTrait; use StringTranslationTrait; /** * Name of the configuration object containing the setting used by this class. Loading Loading @@ -334,7 +336,7 @@ class SamlController extends ControllerBase { if ($destination) { if (UrlHelper::isExternal($destination)) { // Disallow redirecting to an external URL after we log in. throw new UserVisibleException("Destination URL query parameter must not be external: $destination"); throw new UserVisibleException('Destination URL query parameter must not be external: @destination', ['@destination' => $destination]); } $destination_url = $GLOBALS['base_url'] . '/' . $destination; Loading Loading @@ -491,10 +493,15 @@ class SamlController extends ControllerBase { if ($exception instanceof UserVisibleException || $config->get('debug_display_error_details')) { // Show the full error on screen; also log, but with lowered severity. // Assume we don't need the "while" part for a user visible error because // it's likely not fully correct. // it's likely to not fully match the detailed message. $this->messenger->addError($exception->getMessage()); if ($exception instanceof UserVisibleException) { $this->logger->warning($exception->getOriginalMessage(), $exception->getReplacements()); } else { $this->logger->warning($exception->getMessage()); } } else { // Use the same format for logging as Drupal's ExceptionLoggingSubscriber // except also specify where the error was encountered. (The options for Loading @@ -508,7 +515,7 @@ class SamlController extends ControllerBase { $this->logger->critical("%type encountered$while: @message in %function (line %line of %file).", $error); // Don't expose the error to prevent information leakage; the user likely // can't do much with it anyway. But hint that more details are available. $this->messenger->addError("Error encountered{$while}; details have been logged."); $this->messenger->addError($this->t("Error encountered{$while}; details have been logged.")); } // Get error URL. Loading src/UserVisibleException.php +80 −1 Original line number Diff line number Diff line Loading @@ -2,7 +2,86 @@ namespace Drupal\samlauth; use Drupal\Core\StringTranslation\TranslatableMarkup; /** * A RuntimeException that contains messages that are safe to expose to users. * * The message is translated into Drupal's current active language so that * getMessage() returns the translation. */ class UserVisibleException extends \RuntimeException { /** * The original (untranslated template) message passed in to the constructor. * * @var string */ protected $originalMessage; /** * The replacement patterns passed into the constructor. * * @var array */ protected $replacements; /** * UserVisibleException constructor. * * @param string $message * Untranslated message which may contain placeholders. * @param array $args * (optional) An associative array of replacements to make after * translation. Using '@' for the first character of the keys is encouraged; * '%' may come out strange when being rendered outside of HTML output. See * \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for * details. * @param int $code * (optional) The exception code. * @param \Throwable|null $previous * (optional) The previous throwable used for the exception chaining. * * @see \Drupal\Component\Render\FormattableMarkup::placeholderFormat() */ class UserVisibleException extends \RuntimeException {} public function __construct($message = '', array $args = [], $code = 0, \Throwable $previous = NULL) { $this->originalMessage = $message; $this->replacements = $args; // The getMessage() method must return the translation and is 'final', so // we must set the already-translated message. $markup = new TranslatableMarkup($message, $args); parent::__construct($markup->render(), $code, $previous); } /** * Gets the untranslated message with any placeholders intact. * * @return string * The untranslated message. */ public function getOriginalMessage() { return $this->originalMessage; } /** * Gets the replacements array. * * @return array * The replacements array. */ public function getReplacements() { return $this->replacements; } /** * Updates the translation returned by getMessage(). * * @param string $langcode * The language code to translate the message into. */ public function retranslate($langcode) { $markup = new TranslatableMarkup($this->originalMessage, $this->replacements, ['langcode' => $langcode]); $this->message = $markup->render(); } } Loading
src/Controller/SamlController.php +11 −4 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Path\PathValidatorInterface; use Drupal\Core\Render\RendererInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\Core\Utility\Error; use Drupal\Core\Utility\Token; Loading @@ -28,6 +29,7 @@ use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; class SamlController extends ControllerBase { use ExecuteInRenderContextTrait; use StringTranslationTrait; /** * Name of the configuration object containing the setting used by this class. Loading Loading @@ -334,7 +336,7 @@ class SamlController extends ControllerBase { if ($destination) { if (UrlHelper::isExternal($destination)) { // Disallow redirecting to an external URL after we log in. throw new UserVisibleException("Destination URL query parameter must not be external: $destination"); throw new UserVisibleException('Destination URL query parameter must not be external: @destination', ['@destination' => $destination]); } $destination_url = $GLOBALS['base_url'] . '/' . $destination; Loading Loading @@ -491,10 +493,15 @@ class SamlController extends ControllerBase { if ($exception instanceof UserVisibleException || $config->get('debug_display_error_details')) { // Show the full error on screen; also log, but with lowered severity. // Assume we don't need the "while" part for a user visible error because // it's likely not fully correct. // it's likely to not fully match the detailed message. $this->messenger->addError($exception->getMessage()); if ($exception instanceof UserVisibleException) { $this->logger->warning($exception->getOriginalMessage(), $exception->getReplacements()); } else { $this->logger->warning($exception->getMessage()); } } else { // Use the same format for logging as Drupal's ExceptionLoggingSubscriber // except also specify where the error was encountered. (The options for Loading @@ -508,7 +515,7 @@ class SamlController extends ControllerBase { $this->logger->critical("%type encountered$while: @message in %function (line %line of %file).", $error); // Don't expose the error to prevent information leakage; the user likely // can't do much with it anyway. But hint that more details are available. $this->messenger->addError("Error encountered{$while}; details have been logged."); $this->messenger->addError($this->t("Error encountered{$while}; details have been logged.")); } // Get error URL. Loading
src/UserVisibleException.php +80 −1 Original line number Diff line number Diff line Loading @@ -2,7 +2,86 @@ namespace Drupal\samlauth; use Drupal\Core\StringTranslation\TranslatableMarkup; /** * A RuntimeException that contains messages that are safe to expose to users. * * The message is translated into Drupal's current active language so that * getMessage() returns the translation. */ class UserVisibleException extends \RuntimeException { /** * The original (untranslated template) message passed in to the constructor. * * @var string */ protected $originalMessage; /** * The replacement patterns passed into the constructor. * * @var array */ protected $replacements; /** * UserVisibleException constructor. * * @param string $message * Untranslated message which may contain placeholders. * @param array $args * (optional) An associative array of replacements to make after * translation. Using '@' for the first character of the keys is encouraged; * '%' may come out strange when being rendered outside of HTML output. See * \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for * details. * @param int $code * (optional) The exception code. * @param \Throwable|null $previous * (optional) The previous throwable used for the exception chaining. * * @see \Drupal\Component\Render\FormattableMarkup::placeholderFormat() */ class UserVisibleException extends \RuntimeException {} public function __construct($message = '', array $args = [], $code = 0, \Throwable $previous = NULL) { $this->originalMessage = $message; $this->replacements = $args; // The getMessage() method must return the translation and is 'final', so // we must set the already-translated message. $markup = new TranslatableMarkup($message, $args); parent::__construct($markup->render(), $code, $previous); } /** * Gets the untranslated message with any placeholders intact. * * @return string * The untranslated message. */ public function getOriginalMessage() { return $this->originalMessage; } /** * Gets the replacements array. * * @return array * The replacements array. */ public function getReplacements() { return $this->replacements; } /** * Updates the translation returned by getMessage(). * * @param string $langcode * The language code to translate the message into. */ public function retranslate($langcode) { $markup = new TranslatableMarkup($this->originalMessage, $this->replacements, ['langcode' => $langcode]); $this->message = $markup->render(); } }