From 1d32e4ecee44a11d7eb8c6ede6385cb79a449d87 Mon Sep 17 00:00:00 2001 From: Kevin Papst Date: Sat, 30 Oct 2021 15:17:06 +0200 Subject: [PATCH] use token in invoice delete route (#2889) --- src/Constants.php | 6 +++--- src/Controller/InvoiceController.php | 14 ++++++++++++-- src/EventSubscriber/Actions/InvoiceSubscriber.php | 2 +- templates/invoice/actions.html.twig | 2 +- tests/Controller/InvoiceControllerTest.php | 3 ++- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/Constants.php b/src/Constants.php index 18aee97f5b..d3034e05bc 100644 --- a/src/Constants.php +++ b/src/Constants.php @@ -17,15 +17,15 @@ class Constants /** * The current release version */ - public const VERSION = '1.15.6'; + public const VERSION = '1.16.0'; /** * The current release: major * 10000 + minor * 100 + patch */ - public const VERSION_ID = 11506; + public const VERSION_ID = 11600; /** * The current release status, either "stable" or "dev" */ - public const STATUS = 'stable'; + public const STATUS = 'dev'; /** * The software name */ diff --git a/src/Controller/InvoiceController.php b/src/Controller/InvoiceController.php index e235402ea6..1d160217b1 100644 --- a/src/Controller/InvoiceController.php +++ b/src/Controller/InvoiceController.php @@ -36,6 +36,8 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Csrf\CsrfToken; +use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** @@ -253,10 +255,18 @@ public function changeStatusAction(Invoice $invoice, string $status, Request $re } /** - * @Route(path="/delete/{id}", name="admin_invoice_delete", methods={"GET"}) + * @Route(path="/delete/{id}/{token}", name="admin_invoice_delete", methods={"GET"}) */ - public function deleteInvoiceAction(Invoice $invoice): Response + public function deleteInvoiceAction(Invoice $invoice, string $token, CsrfTokenManagerInterface $csrfTokenManager): Response { + if (!$csrfTokenManager->isTokenValid(new CsrfToken('invoice.delete', $token))) { + $this->flashError('action.delete.error'); + + return $this->redirectToRoute('admin_invoice_list'); + } + + $csrfTokenManager->refreshToken($token); + try { $this->service->deleteInvoice($invoice); $this->flashSuccess('action.delete.success'); diff --git a/src/EventSubscriber/Actions/InvoiceSubscriber.php b/src/EventSubscriber/Actions/InvoiceSubscriber.php index 8374b3b9c9..c574f9c9d7 100644 --- a/src/EventSubscriber/Actions/InvoiceSubscriber.php +++ b/src/EventSubscriber/Actions/InvoiceSubscriber.php @@ -37,6 +37,6 @@ public function onActions(PageActionsEvent $event): void } $event->addAction('download', ['url' => $this->path('admin_invoice_download', ['id' => $invoice->getId()]), 'target' => '_blank']); - $event->addDelete($this->path('admin_invoice_delete', ['id' => $invoice->getId()]), false); + $event->addDelete($this->path('admin_invoice_delete', ['id' => $invoice->getId(), 'token' => $payload['token']]), false); } } diff --git a/templates/invoice/actions.html.twig b/templates/invoice/actions.html.twig index 95f57623cb..d1fa98c4b4 100644 --- a/templates/invoice/actions.html.twig +++ b/templates/invoice/actions.html.twig @@ -6,7 +6,7 @@ {% macro invoice(invoice, view) %} {% import "macros/widgets.html.twig" as widgets %} - {% set event = actions(app.user, 'invoice', view, {'invoice': invoice}) %} + {% set event = actions(app.user, 'invoice', view, {'invoice': invoice, 'token': csrf_token('invoice.delete')}) %} {{ widgets.table_actions(event.actions) }} {% endmacro %} diff --git a/tests/Controller/InvoiceControllerTest.php b/tests/Controller/InvoiceControllerTest.php index 8c252e4d09..56cdafd9fa 100644 --- a/tests/Controller/InvoiceControllerTest.php +++ b/tests/Controller/InvoiceControllerTest.php @@ -353,7 +353,8 @@ public function testCreateActionAsAdminWithDownloadAndStatusChangeAndDelete() $client->followRedirect(); $this->assertTrue($client->getResponse()->isSuccessful()); - $this->request($client, '/invoice/delete/' . $id); + // this does not delete the invoice, because the token is wrong + $this->request($client, '/invoice/delete/' . $id . '/fghfkjhgkjhg'); $this->assertIsRedirect($client, '/invoice/show'); $client->followRedirect(); $this->assertTrue($client->getResponse()->isSuccessful());