From 53e384a5c312f900cdb4e79a4d9d30767b206035 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Wed, 18 Sep 2024 09:31:59 +0200 Subject: [PATCH 1/4] controllers: Remove incorrect usage of trait `CommandActions` --- application/controllers/CommentController.php | 15 --------------- application/controllers/DowntimeController.php | 15 --------------- 2 files changed, 30 deletions(-) diff --git a/application/controllers/CommentController.php b/application/controllers/CommentController.php index b184d6b9d..fc0800647 100644 --- a/application/controllers/CommentController.php +++ b/application/controllers/CommentController.php @@ -5,19 +5,14 @@ namespace Icinga\Module\Icingadb\Controllers; use Icinga\Exception\NotFoundError; -use Icinga\Module\Icingadb\Common\CommandActions; -use Icinga\Module\Icingadb\Common\Links; use Icinga\Module\Icingadb\Model\Comment; use Icinga\Module\Icingadb\Web\Controller; use Icinga\Module\Icingadb\Widget\Detail\CommentDetail; use Icinga\Module\Icingadb\Widget\ItemList\CommentList; use ipl\Stdlib\Filter; -use ipl\Web\Url; class CommentController extends Controller { - use CommandActions; - /** @var Comment The comment object */ protected $comment; @@ -59,14 +54,4 @@ public function indexAction() $this->setAutorefreshInterval(10); } - - protected function fetchCommandTargets(): array - { - return [$this->comment]; - } - - protected function getCommandTargetsUrl(): Url - { - return Links::comment($this->comment); - } } diff --git a/application/controllers/DowntimeController.php b/application/controllers/DowntimeController.php index a0a7fa070..500d0f7e3 100644 --- a/application/controllers/DowntimeController.php +++ b/application/controllers/DowntimeController.php @@ -5,19 +5,14 @@ namespace Icinga\Module\Icingadb\Controllers; use Icinga\Exception\NotFoundError; -use Icinga\Module\Icingadb\Common\CommandActions; -use Icinga\Module\Icingadb\Common\Links; use Icinga\Module\Icingadb\Model\Downtime; use Icinga\Module\Icingadb\Web\Controller; use Icinga\Module\Icingadb\Widget\Detail\DowntimeDetail; use Icinga\Module\Icingadb\Widget\ItemList\DowntimeList; use ipl\Stdlib\Filter; -use ipl\Web\Url; class DowntimeController extends Controller { - use CommandActions; - /** @var Downtime */ protected $downtime; @@ -71,14 +66,4 @@ public function indexAction() $this->setAutorefreshInterval(10); } - - protected function fetchCommandTargets(): array - { - return [$this->downtime]; - } - - protected function getCommandTargetsUrl(): Url - { - return Links::downtime($this->downtime); - } } From 8da8ce6b0e3175494d9f66c53cfede96db0cf642 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Wed, 18 Sep 2024 09:33:18 +0200 Subject: [PATCH 2/4] comments: Support automated removal --- .../controllers/CommentsController.php | 66 +++++++++++-------- .../Command/Object/DeleteCommentForm.php | 4 -- doc/09-Automation.md | 10 +++ .../Icingadb/Widget/Detail/CommentDetail.php | 1 - 4 files changed, 49 insertions(+), 32 deletions(-) diff --git a/application/controllers/CommentsController.php b/application/controllers/CommentsController.php index 2358423d5..540dd31e5 100644 --- a/application/controllers/CommentsController.php +++ b/application/controllers/CommentsController.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Icingadb\Controllers; use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Module\Icingadb\Common\CommandActions; use Icinga\Module\Icingadb\Common\Links; use Icinga\Module\Icingadb\Forms\Command\Object\DeleteCommentForm; use Icinga\Module\Icingadb\Model\Comment; @@ -13,12 +14,16 @@ use Icinga\Module\Icingadb\Widget\ItemList\CommentList; use Icinga\Module\Icingadb\Web\Control\ViewModeSwitcher; use Icinga\Module\Icingadb\Widget\ShowMore; +use ipl\Orm\Model; +use ipl\Stdlib\Filter; use ipl\Web\Control\LimitControl; use ipl\Web\Control\SortControl; use ipl\Web\Url; class CommentsController extends Controller { + use CommandActions; + public function indexAction() { $this->addTitleTab(t('Comments')); @@ -103,34 +108,9 @@ public function indexAction() public function deleteAction() { + $this->assertIsGrantedOnCommandTargets('icingadb/command/comment/delete'); $this->setTitle(t('Remove Comments')); - - $db = $this->getDb(); - - $comments = Comment::on($db)->with([ - 'host', - 'host.state', - 'service', - 'service.host', - 'service.host.state', - 'service.state' - ]); - - $this->filter($comments); - - $form = (new DeleteCommentForm()) - ->setObjects($comments) - ->setRedirectUrl(Links::comments()->getAbsoluteUrl()) - ->on(DeleteCommentForm::ON_SUCCESS, function ($form) { - // This forces the column to reload nearly instantly after the redirect - // and ensures the effect of the command is visible to the user asap - $this->getResponse()->setAutoRefreshInterval(1); - - $this->redirectNow($form->getRedirectUrl()); - }) - ->handleRequest(ServerRequest::fromGlobals()); - - $this->addContent($form); + $this->handleCommandForm(DeleteCommentForm::class); } public function detailsAction() @@ -194,4 +174,36 @@ public function searchEditorAction() $this->getDocument()->add($editor); $this->setTitle(t('Adjust Filter')); } + + protected function getCommandTargetsUrl(): Url + { + return Url::fromPath('__CLOSE__'); + } + + protected function fetchCommandTargets() + { + $comments = Comment::on($this->getDb())->with([ + 'host', + 'host.state', + 'service', + 'service.host', + 'service.host.state', + 'service.state' + ]); + + $this->filter($comments); + + return $comments; + } + + public function isGrantedOn(string $permission, Model $object): bool + { + return parent::isGrantedOn($permission, $object->{$object->object_type}); + } + + public function isGrantedOnType(string $permission, string $type, Filter\Rule $filter, bool $cache = true): bool + { + return parent::isGrantedOnType($permission, 'host', $filter, $cache) + || parent::isGrantedOnType($permission, 'service', $filter, $cache); + } } diff --git a/application/forms/Command/Object/DeleteCommentForm.php b/application/forms/Command/Object/DeleteCommentForm.php index a35fc2e5f..c6bc7d84f 100644 --- a/application/forms/Command/Object/DeleteCommentForm.php +++ b/application/forms/Command/Object/DeleteCommentForm.php @@ -9,15 +9,12 @@ use Icinga\Module\Icingadb\Forms\Command\CommandForm; use Icinga\Web\Notification; use ipl\Orm\Model; -use ipl\Web\Common\RedirectOption; use ipl\Web\Widget\Icon; use Iterator; use Traversable; class DeleteCommentForm extends CommandForm { - use RedirectOption; - protected $defaultAttributes = ['class' => 'inline']; public function __construct() @@ -38,7 +35,6 @@ public function __construct() protected function assembleElements() { - $this->addElement($this->createRedirectOption()); } protected function assembleSubmitButton() diff --git a/doc/09-Automation.md b/doc/09-Automation.md index f5141882b..1c5ac4ac3 100644 --- a/doc/09-Automation.md +++ b/doc/09-Automation.md @@ -131,6 +131,16 @@ Please have a look at the [Monitoring Plugins Development Guidelines](https://ww | expire | n | BoolEnum | - | | expire_time | y | DateTime | expire | +### Delete Comments + +#### Routes + +* icingadb/comments/delete + +#### Options + +None. + ### Check Now #### Routes diff --git a/library/Icingadb/Widget/Detail/CommentDetail.php b/library/Icingadb/Widget/Detail/CommentDetail.php index 5b0923e43..4255f61be 100644 --- a/library/Icingadb/Widget/Detail/CommentDetail.php +++ b/library/Icingadb/Widget/Detail/CommentDetail.php @@ -114,7 +114,6 @@ protected function createRemoveCommentForm() return (new DeleteCommentForm()) ->setObjects([$this->comment]) - ->populate(['redirect' => '__BACK__']) ->setAction($action->getAbsoluteUrl()); } From 5d769c130b57fcd35d9c3a43e5d480ff7431c22e Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Wed, 18 Sep 2024 09:34:02 +0200 Subject: [PATCH 3/4] downtimes: Support automated removal --- .../controllers/DowntimesController.php | 70 ++++++++++++------- .../Command/Object/DeleteDowntimeForm.php | 4 -- doc/09-Automation.md | 10 +++ .../Icingadb/Widget/Detail/DowntimeDetail.php | 1 - 4 files changed, 53 insertions(+), 32 deletions(-) diff --git a/application/controllers/DowntimesController.php b/application/controllers/DowntimesController.php index c045ffb45..448f1de5f 100644 --- a/application/controllers/DowntimesController.php +++ b/application/controllers/DowntimesController.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Icingadb\Controllers; use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Module\Icingadb\Common\CommandActions; use Icinga\Module\Icingadb\Common\Links; use Icinga\Module\Icingadb\Forms\Command\Object\DeleteDowntimeForm; use Icinga\Module\Icingadb\Model\Downtime; @@ -13,12 +14,16 @@ use Icinga\Module\Icingadb\Widget\ItemList\DowntimeList; use Icinga\Module\Icingadb\Web\Control\ViewModeSwitcher; use Icinga\Module\Icingadb\Widget\ShowMore; +use ipl\Orm\Model; +use ipl\Stdlib\Filter; use ipl\Web\Control\LimitControl; use ipl\Web\Control\SortControl; use ipl\Web\Url; class DowntimesController extends Controller { + use CommandActions; + public function indexAction() { $this->addTitleTab(t('Downtimes')); @@ -109,34 +114,9 @@ public function indexAction() public function deleteAction() { + $this->assertIsGrantedOnCommandTargets('icingadb/command/downtime/delete'); $this->setTitle(t('Cancel Downtimes')); - - $db = $this->getDb(); - - $downtimes = Downtime::on($db)->with([ - 'host', - 'host.state', - 'service', - 'service.host', - 'service.host.state', - 'service.state' - ]); - - $this->filter($downtimes); - - $form = (new DeleteDowntimeForm()) - ->setObjects($downtimes) - ->setRedirectUrl(Links::downtimes()->getAbsoluteUrl()) - ->on(DeleteDowntimeForm::ON_SUCCESS, function ($form) { - // This forces the column to reload nearly instantly after the redirect - // and ensures the effect of the command is visible to the user asap - $this->getResponse()->setAutoRefreshInterval(1); - - $this->redirectNow($form->getRedirectUrl()); - }) - ->handleRequest(ServerRequest::fromGlobals()); - - $this->addContent($form); + $this->handleCommandForm(DeleteDowntimeForm::class); } public function detailsAction() @@ -200,4 +180,40 @@ public function searchEditorAction() $this->getDocument()->add($editor); $this->setTitle(t('Adjust Filter')); } + + protected function getCommandTargetsUrl(): Url + { + return Url::fromPath('__CLOSE__'); + } + + protected function fetchCommandTargets() + { + $downtimes = Downtime::on($this->getDb())->with([ + 'host', + 'host.state', + 'service', + 'service.host', + 'service.host.state', + 'service.state' + ]); + + $this->filter($downtimes); + + return $downtimes; + } + + public function isGrantedOn(string $permission, Model $object): bool + { + if ($object->scheduled_by !== null) { + return false; + } + + return parent::isGrantedOn($permission, $object->{$object->object_type}); + } + + public function isGrantedOnType(string $permission, string $type, Filter\Rule $filter, bool $cache = true): bool + { + return parent::isGrantedOnType($permission, 'host', $filter, $cache) + || parent::isGrantedOnType($permission, 'service', $filter, $cache); + } } diff --git a/application/forms/Command/Object/DeleteDowntimeForm.php b/application/forms/Command/Object/DeleteDowntimeForm.php index b13bcc524..79165d2c8 100644 --- a/application/forms/Command/Object/DeleteDowntimeForm.php +++ b/application/forms/Command/Object/DeleteDowntimeForm.php @@ -9,15 +9,12 @@ use Icinga\Module\Icingadb\Forms\Command\CommandForm; use Icinga\Web\Notification; use ipl\Orm\Model; -use ipl\Web\Common\RedirectOption; use ipl\Web\Widget\Icon; use Iterator; use Traversable; class DeleteDowntimeForm extends CommandForm { - use RedirectOption; - protected $defaultAttributes = ['class' => 'inline']; public function __construct() @@ -38,7 +35,6 @@ public function __construct() protected function assembleElements() { - $this->addElement($this->createRedirectOption()); } protected function assembleSubmitButton() diff --git a/doc/09-Automation.md b/doc/09-Automation.md index 1c5ac4ac3..f993482ef 100644 --- a/doc/09-Automation.md +++ b/doc/09-Automation.md @@ -228,6 +228,16 @@ None. | hours | y | Number | flexible | | minutes | y | Number | flexible | +### Delete Downtimes + +#### Routes + +* icingadb/downtimes/delete + +#### Options + +None. + ### Send Custom Notification #### Routes diff --git a/library/Icingadb/Widget/Detail/DowntimeDetail.php b/library/Icingadb/Widget/Detail/DowntimeDetail.php index 9e50f7f26..6a3902dc4 100644 --- a/library/Icingadb/Widget/Detail/DowntimeDetail.php +++ b/library/Icingadb/Widget/Detail/DowntimeDetail.php @@ -58,7 +58,6 @@ protected function createCancelDowntimeForm() return (new DeleteDowntimeForm()) ->setObjects([$this->downtime]) - ->populate(['redirect' => '__BACK__']) ->setAction($action->getAbsoluteUrl()); } From 4e60c6fd602e4bb89e18afab52d26d2a19b17791 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Wed, 18 Sep 2024 09:34:20 +0200 Subject: [PATCH 4/4] CommandActions: Force a form's HTTP method for api requests --- library/Icingadb/Common/CommandActions.php | 1 + 1 file changed, 1 insertion(+) diff --git a/library/Icingadb/Common/CommandActions.php b/library/Icingadb/Common/CommandActions.php index af7d19428..eb161995f 100644 --- a/library/Icingadb/Common/CommandActions.php +++ b/library/Icingadb/Common/CommandActions.php @@ -215,6 +215,7 @@ protected function handleApiRequest(CommandForm $form) }); $form->handleRequest($this->getServerRequest()); + $this->assertHttpMethod($form->getMethod()); $errors = []; foreach ($form->getElements() as $element) {