Update CSRF Token IDs for Issue kevinpapst/kimai2#2947 (#2948)

* bump version
* removed not needed token, as it is already contained in the form
Co-authored-by: Kevin Papst <kpapst@gmx.net>
This commit is contained in:
tdozbun-reno
2021-11-18 11:32:00 -06:00
committed by GitHub
parent b28e9c120c
commit 56d02673ed
16 changed files with 35 additions and 113 deletions

View File

@@ -17,11 +17,11 @@ class Constants
/**
* The current release version
*/
public const VERSION = '1.16.2';
public const VERSION = '1.16.3';
/**
* The current release: major * 10000 + minor * 100 + patch
*/
public const VERSION_ID = 11602;
public const VERSION_ID = 11603;
/**
* The current release status, either "stable" or "dev"
*/

View File

@@ -172,7 +172,7 @@ final class CustomerController extends AbstractController
return $this->redirectToRoute('customer_details', ['id' => $customerId]);
}
$csrfTokenManager->refreshToken($token);
$csrfTokenManager->refreshToken('customer.delete_comment');
try {
$this->repository->deleteComment($comment);
@@ -219,7 +219,7 @@ final class CustomerController extends AbstractController
return $this->redirectToRoute('customer_details', ['id' => $customerId]);
}
$csrfTokenManager->refreshToken($token);
$csrfTokenManager->refreshToken('customer.pin_comment');
$comment->setPinned(!$comment->isPinned());
try {

View File

@@ -69,7 +69,7 @@ class DoctorController extends AbstractController
return $this->redirectToRoute('doctor');
}
$csrfTokenManager->refreshToken($token);
$csrfTokenManager->refreshToken('doctor.flush_log');
$logfile = $this->getLogFilename();

View File

@@ -265,7 +265,7 @@ final class InvoiceController extends AbstractController
return $this->redirectToRoute('admin_invoice_list');
}
$csrfTokenManager->refreshToken($token);
$csrfTokenManager->refreshToken('invoice.delete');
try {
$this->service->deleteInvoice($invoice);
@@ -462,7 +462,7 @@ final class InvoiceController extends AbstractController
return $this->redirectToRoute('admin_invoice_template');
}
$csrfTokenManager->refreshToken($token);
$csrfTokenManager->refreshToken('invoice.delete_template');
try {
$this->templateRepository->removeTemplate($template);

View File

@@ -194,7 +194,7 @@ final class ProjectController extends AbstractController
return $this->redirectToRoute('project_details', ['id' => $projectId]);
}
$csrfTokenManager->refreshToken($token);
$csrfTokenManager->refreshToken('project.delete_comment');
try {
$this->repository->deleteComment($comment);
@@ -241,7 +241,7 @@ final class ProjectController extends AbstractController
return $this->redirectToRoute('project_details', ['id' => $projectId]);
}
$csrfTokenManager->refreshToken($token);
$csrfTokenManager->refreshToken('project.pin_comment');
$comment->setPinned(!$comment->isPinned());
try {
@@ -432,7 +432,7 @@ final class ProjectController extends AbstractController
return $this->redirectToRoute('project_details', ['id' => $project->getId()]);
}
$csrfTokenManager->refreshToken($token);
$csrfTokenManager->refreshToken('project.duplicate');
$newProject = $projectDuplicationService->duplicate($project, $project->getName() . ' [COPY]');

View File

@@ -94,7 +94,7 @@ final class TeamController extends AbstractController
return $this->redirectToRoute('admin_team_edit', ['id' => $team->getId()]);
}
$csrfTokenManager->refreshToken($token);
$csrfTokenManager->refreshToken('team.duplicate');
$newTeam = clone $team;
$newTeam->setName($team->getName() . ' [COPY]');

View File

@@ -211,14 +211,14 @@ abstract class TimesheetAbstractController extends AbstractController
]);
}
protected function duplicate(Timesheet $timesheet, Request $request, string $renderTemplate, string $token): Response
protected function duplicate(Timesheet $timesheet, Request $request, string $renderTemplate): Response
{
$copyTimesheet = clone $timesheet;
$event = new TimesheetMetaDefinitionEvent($copyTimesheet);
$this->dispatcher->dispatch($event);
$form = $this->getDuplicateForm($copyTimesheet, $timesheet, $token);
$form = $this->getDuplicateForm($copyTimesheet, $timesheet);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -612,7 +612,7 @@ abstract class TimesheetAbstractController extends AbstractController
return $query;
}
abstract protected function getDuplicateForm(Timesheet $entry, Timesheet $original, string $token): FormInterface;
abstract protected function getDuplicateForm(Timesheet $entry, Timesheet $original): FormInterface;
abstract protected function getCreateForm(Timesheet $entry): FormInterface;
}

View File

@@ -21,8 +21,6 @@ use Symfony\Component\Form\FormInterface;
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;
/**
* @Route(path="/timesheet")
@@ -62,20 +60,12 @@ class TimesheetController extends TimesheetAbstractController
}
/**
* @Route(path="/{id}/duplicate/{token}", name="timesheet_duplicate", methods={"GET", "POST"})
* @Route(path="/{id}/duplicate", name="timesheet_duplicate", methods={"GET", "POST"})
* @Security("is_granted('duplicate', entry)")
*/
public function duplicateAction(Timesheet $entry, Request $request, string $token, CsrfTokenManagerInterface $csrfTokenManager): Response
public function duplicateAction(Timesheet $entry, Request $request): Response
{
if (!$csrfTokenManager->isTokenValid(new CsrfToken('timesheet.duplicate', $token))) {
$this->flashError('action.csrf.error');
return $this->redirectToRoute('timesheet');
}
$csrfTokenManager->refreshToken($token);
return $this->duplicate($entry, $request, 'timesheet/edit.html.twig', $token);
return $this->duplicate($entry, $request, 'timesheet/edit.html.twig');
}
/**
@@ -110,8 +100,8 @@ class TimesheetController extends TimesheetAbstractController
return $this->generateCreateForm($entry, TimesheetEditForm::class, $this->generateUrl('timesheet_create'));
}
protected function getDuplicateForm(Timesheet $entry, Timesheet $original, string $token): FormInterface
protected function getDuplicateForm(Timesheet $entry, Timesheet $original): FormInterface
{
return $this->generateCreateForm($entry, TimesheetEditForm::class, $this->generateUrl('timesheet_duplicate', ['id' => $original->getId(), 'token' => $token]));
return $this->generateCreateForm($entry, TimesheetEditForm::class, $this->generateUrl('timesheet_duplicate', ['id' => $original->getId()]));
}
}

View File

@@ -28,8 +28,6 @@ use Symfony\Component\Form\FormInterface;
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;
/**
* @Route(path="/team/timesheet")
@@ -73,20 +71,12 @@ class TimesheetTeamController extends TimesheetAbstractController
}
/**
* @Route(path="/{id}/duplicate/{token}", name="admin_timesheet_duplicate", methods={"GET", "POST"})
* @Route(path="/{id}/duplicate", name="admin_timesheet_duplicate", methods={"GET", "POST"})
* @Security("is_granted('duplicate', entry)")
*/
public function duplicateAction(Timesheet $entry, Request $request, string $token, CsrfTokenManagerInterface $csrfTokenManager): Response
public function duplicateAction(Timesheet $entry, Request $request): Response
{
if (!$csrfTokenManager->isTokenValid(new CsrfToken('admin_timesheet.duplicate', $token))) {
$this->flashError('action.csrf.error');
return $this->redirectToRoute('admin_timesheet');
}
$csrfTokenManager->refreshToken($token);
return $this->duplicate($entry, $request, 'timesheet-team/edit.html.twig', $token);
return $this->duplicate($entry, $request, 'timesheet-team/edit.html.twig');
}
/**
@@ -205,9 +195,9 @@ class TimesheetTeamController extends TimesheetAbstractController
return $this->generateCreateForm($entry, TimesheetAdminEditForm::class, $this->generateUrl('admin_timesheet_create'));
}
protected function getDuplicateForm(Timesheet $entry, Timesheet $original, string $token): FormInterface
protected function getDuplicateForm(Timesheet $entry, Timesheet $original): FormInterface
{
return $this->generateCreateForm($entry, TimesheetAdminEditForm::class, $this->generateUrl('admin_timesheet_duplicate', ['id' => $original->getId(), 'token' => $token]));
return $this->generateCreateForm($entry, TimesheetAdminEditForm::class, $this->generateUrl('admin_timesheet_duplicate', ['id' => $original->getId()]));
}
protected function getPermissionEditExport(): string

View File

@@ -39,7 +39,7 @@ abstract class AbstractTimesheetSubscriber extends AbstractActionsSubscriber
if ($this->isGranted('duplicate', $timesheet)) {
$class = $event->isView('edit') ? '' : 'modal-ajax-form';
$event->addAction('copy', ['url' => $this->path($routeDuplicate, ['id' => $timesheet->getId(), 'token' => $payload['token']]), 'class' => $class]);
$event->addAction('copy', ['url' => $this->path($routeDuplicate, ['id' => $timesheet->getId()]), 'class' => $class]);
}
if ($event->countActions() > 0) {

View File

@@ -6,7 +6,7 @@
{% macro timesheet_team(timesheet, view) %}
{% import "macros/widgets.html.twig" as widgets %}
{% set event = actions(app.user, 'timesheet_team', view, {'timesheet': timesheet, 'token': csrf_token('admin_timesheet.duplicate')}) %}
{% set event = actions(app.user, 'timesheet_team', view, {'timesheet': timesheet}) %}
{% if view == 'index' or view == 'custom' %}
{{ widgets.table_actions(event.actions) }}
{% else %}

View File

@@ -6,7 +6,7 @@
{% macro timesheet(timesheet, view, options) %}
{% import "macros/widgets.html.twig" as widgets %}
{% set event = actions(app.user, 'timesheet', view, {'timesheet': timesheet, 'token': csrf_token('timesheet.duplicate')}) %}
{% set event = actions(app.user, 'timesheet', view, {'timesheet': timesheet}) %}
{% if view == 'index' or view == 'custom' %}
{{ widgets.table_actions(event.actions) }}
{% else %}

View File

@@ -241,8 +241,10 @@ class CustomerControllerTest extends ControllerBaseTest
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
$client->followRedirect();
$node = $client->getCrawler()->filter('div.box#comments_box .box-body a.btn.active');
$token2 = self::$container->get('security.csrf.token_manager')->getToken('customer.pin_comment');
self::assertEquals(1, $node->count());
self::assertEquals($this->createUrl('/admin/customer/' . $id . '/comment_pin/' . $token), $node->attr('href'));
self::assertEquals($this->createUrl('/admin/customer/' . $id . '/comment_pin/' . $token2), $node->attr('href'));
self::assertNotEquals($token, $token2);
}
public function testCreateDefaultTeamAction()

View File

@@ -318,8 +318,10 @@ class ProjectControllerTest extends ControllerBaseTest
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
$client->followRedirect();
$node = $client->getCrawler()->filter('div.box#comments_box .box-body a.btn.active');
$token2 = self::$container->get('security.csrf.token_manager')->getToken('project.pin_comment');
self::assertEquals(1, $node->count());
self::assertEquals($this->createUrl('/admin/project/' . $id . '/comment_pin/' . $token), $node->attr('href'));
self::assertEquals($this->createUrl('/admin/project/' . $id . '/comment_pin/' . $token2), $node->attr('href'));
self::assertNotEquals($token, $token2);
}
public function testCreateDefaultTeamAction()

View File

@@ -708,9 +708,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$ids = $this->importFixture($fixture);
$newId = $ids[0]->getId();
$token = self::$container->get('security.csrf.token_manager')->getToken('timesheet.duplicate');
$this->request($client, '/timesheet/' . $newId . '/duplicate/' . $token);
$this->request($client, '/timesheet/' . $newId . '/duplicate');
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=timesheet_edit_form]')->form();
@@ -732,33 +730,4 @@ class TimesheetControllerTest extends ControllerBaseTest
$this->assertEquals(2016, $timesheet->getFixedRate());
$this->assertEquals(2016, $timesheet->getRate());
}
public function testDuplicateActionWithInvalidCsrf()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$dateTime = new DateTimeFactory(new \DateTimeZone('Europe/London'));
$fixture = new TimesheetFixtures();
$fixture->setAmount(1);
$fixture->setAmountRunning(0);
$fixture->setUser($this->getUserByRole(User::ROLE_USER));
$fixture->setStartDate($dateTime->createDateTime());
$fixture->setCallback(function (Timesheet $timesheet) {
$timesheet->setDescription('Testing is fun!');
$begin = clone $timesheet->getBegin();
$begin->setTime(0, 0, 0);
$timesheet->setBegin($begin);
$end = clone $timesheet->getBegin();
$end->modify('+ 8 hours');
$timesheet->setEnd($end);
$timesheet->setFixedRate(2016);
$timesheet->setHourlyRate(127);
});
/** @var Timesheet[] $ids */
$ids = $this->importFixture($fixture);
$newId = $ids[0]->getId();
$this->assertInvalidCsrfToken($client, '/timesheet/' . $newId . '/duplicate/dfghdfghdfghdfghdfgh', $this->createUrl('/timesheet/'));
}
}

View File

@@ -428,9 +428,7 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
$ids = $this->importFixture($fixture);
$newId = $ids[0]->getId();
$token = self::$container->get('security.csrf.token_manager')->getToken('admin_timesheet.duplicate');
$this->request($client, '/team/timesheet/' . $newId . '/duplicate/' . $token);
$this->request($client, '/team/timesheet/' . $newId . '/duplicate');
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=timesheet_admin_edit_form]')->form();
@@ -452,33 +450,4 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
$this->assertEquals(2016, $timesheet->getFixedRate());
$this->assertEquals(2016, $timesheet->getRate());
}
public function testDuplicateActionWithInvalidCsrf()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$dateTime = new DateTimeFactory(new \DateTimeZone('Europe/London'));
$fixture = new TimesheetFixtures();
$fixture->setAmount(1);
$fixture->setAmountRunning(0);
$fixture->setUser($this->getUserByRole(User::ROLE_USER));
$fixture->setStartDate($dateTime->createDateTime());
$fixture->setCallback(function (Timesheet $timesheet) {
$timesheet->setDescription('Testing is fun!');
$begin = clone $timesheet->getBegin();
$begin->setTime(0, 0, 0);
$timesheet->setBegin($begin);
$end = clone $timesheet->getBegin();
$end->modify('+ 8 hours');
$timesheet->setEnd($end);
$timesheet->setFixedRate(2016);
$timesheet->setHourlyRate(127);
});
/** @var Timesheet[] $ids */
$ids = $this->importFixture($fixture);
$newId = $ids[0]->getId();
$this->assertInvalidCsrfToken($client, '/team/timesheet/' . $newId . '/duplicate/dfghdfghdfghdfghdfgh', $this->createUrl('/team/timesheet/'));
}
}