Skip to content

Commit

Permalink
CommandActions: Respond with JSON if requested
Browse files Browse the repository at this point in the history
  • Loading branch information
nilmerg committed Sep 5, 2023
1 parent 4ea941e commit 0d0c930
Showing 1 changed file with 58 additions and 4 deletions.
62 changes: 58 additions & 4 deletions library/Icingadb/Common/CommandActions.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Icinga\Module\Icingadb\Common;

use GuzzleHttp\Psr7\ServerRequest;
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
use Icinga\Module\Icingadb\Forms\Command\Object\AcknowledgeProblemForm;
use Icinga\Module\Icingadb\Forms\Command\Object\AddCommentForm;
Expand All @@ -17,6 +16,7 @@
use Icinga\Module\Icingadb\Forms\Command\Object\SendCustomNotificationForm;
use Icinga\Module\Icingadb\Forms\Command\Object\ToggleObjectFeaturesForm;
use Icinga\Security\SecurityException;
use Icinga\Web\Notification;
use ipl\Orm\Model;
use ipl\Orm\Query;
use ipl\Web\Url;
Expand Down Expand Up @@ -138,11 +138,35 @@ protected function assertIsGrantedOnCommandTargets(string $permission)
*/
protected function handleCommandForm($form)
{
$isXhr = $this->getRequest()->isXmlHttpRequest();
if ($isXhr && $this->getRequest()->isApiRequest()) {
// Prevents the framework already, this is just a fail-safe
$this->httpBadRequest('Responding with JSON during a Web request is not supported');
}

if (is_string($form)) {
/** @var \Icinga\Module\Icingadb\Forms\Command\CommandForm $form */
/** @var CommandForm $form */
$form = new $form();
}

$form->setObjects($this->getCommandTargets());

if ($isXhr) {
$this->handleWebRequest($form);
} else {
$this->handleApiRequest($form);
}
}

/**
* Handle a Web request for the given form
*
* @param CommandForm $form
*
* @return void
*/
protected function handleWebRequest(CommandForm $form): void
{
$actionUrl = $this->getRequest()->getUrl();
if ($this->view->compact) {
$actionUrl = clone $actionUrl;
Expand All @@ -153,7 +177,6 @@ protected function handleCommandForm($form)
}

$form->setAction($actionUrl->getAbsoluteUrl());
$form->setObjects($this->getCommandTargets());
$form->on($form::ON_SUCCESS, function () {
// This forces the column to reload nearly instantly after the redirect
// and ensures the effect of the command is visible to the user asap
Expand All @@ -162,11 +185,42 @@ protected function handleCommandForm($form)
$this->redirectNow($this->getCommandTargetsUrl());
});

$form->handleRequest(ServerRequest::fromGlobals());
$form->handleRequest($this->getServerRequest());

$this->addContent($form);
}

/**
* Handle an API request for the given form
*
* @param CommandForm $form
*
* @return never
*/
protected function handleApiRequest(CommandForm $form)
{
$form->setIsApiTarget();
$form->on($form::ON_SUCCESS, function () {
$this->getResponse()
->json()
->setSuccessData(Notification::getInstance()->popMessages())
->sendResponse();
});

$form->handleRequest($this->getServerRequest());

$errors = [];
foreach ($form->getElements() as $element) {
$errors[$element->getName()] = $element->getMessages();
}

$this->getResponse()
->json()
->setFailData($errors)
->setHttpResponseCode(422)
->sendResponse();
}

public function acknowledgeAction()
{
$this->assertIsGrantedOnCommandTargets('icingadb/command/acknowledge-problem');
Expand Down

0 comments on commit 0d0c930

Please sign in to comment.