mirror of
https://github.com/wallabag/wallabag.git
synced 2025-06-27 16:36:00 +00:00
Protect remove_tag with a CSRF token
This commit is contained in:
parent
d1e128900a
commit
ddf2e80842
4 changed files with 19 additions and 14 deletions
|
@ -10,6 +10,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
|||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Wallabag\CoreBundle\Entity\Entry;
|
||||
|
@ -87,12 +88,16 @@ class TagController extends AbstractController
|
|||
/**
|
||||
* Removes tag from entry.
|
||||
*
|
||||
* @Route("/remove-tag/{entry}/{tag}", requirements={"entry" = "\d+", "tag" = "\d+"}, name="remove_tag")
|
||||
* @Route("/remove-tag/{entry}/{tag}", name="remove_tag", methods={"POST"}, requirements={"entry" = "\d+", "tag" = "\d+"})
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function removeTagFromEntry(Request $request, Entry $entry, Tag $tag)
|
||||
{
|
||||
if (!$this->isCsrfTokenValid('remove-tag', $request->request->get('token'))) {
|
||||
throw new BadRequestHttpException('Bad CSRF token.');
|
||||
}
|
||||
|
||||
$this->checkUserAction($entry);
|
||||
|
||||
$entry->removeTag($tag);
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
<a class="chip-label" href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{ tag.label }}</a>
|
||||
{% if withRemove is defined and withRemove == true %}
|
||||
{% set current_path = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %}
|
||||
<a class="chip-action" href="{{ path('remove_tag', {'entry': entryId, 'tag': tag.id, redirect: current_path}) }}" onclick="return confirm('{{ 'entry.confirm.delete_tag'|trans|escape('js') }}')">
|
||||
<i class="material-icons vertical-align-middle">delete</i>
|
||||
</a>
|
||||
<form action="{{ path('remove_tag', {'entry': entryId, 'tag': tag.id, redirect: current_path}) }}" method="post">
|
||||
<input type="hidden" name="token" value="{{ csrf_token('remove-tag') }}"/>
|
||||
|
||||
<button type="submit" class="btn-link chip-action" onclick="return confirm('{{ 'entry.confirm.delete_tag'|trans|escape('js') }}')">
|
||||
<i class="material-icons vertical-align-middle">delete</i>
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
|
|
@ -1694,7 +1694,7 @@ class EntryControllerTest extends WallabagCoreTestCase
|
|||
$this->assertSame('example.com', $content->getDomainName());
|
||||
}
|
||||
|
||||
public function testEntryDeleteTagLink()
|
||||
public function testEntryDeleteTagForm()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
@ -1705,10 +1705,7 @@ class EntryControllerTest extends WallabagCoreTestCase
|
|||
|
||||
$crawler = $client->request('GET', '/view/' . $entry->getId());
|
||||
|
||||
// As long as the deletion link of a tag is following
|
||||
// a link to the tag view, we take the second one to retrieve
|
||||
// the deletion link of the first tag
|
||||
$link = $crawler->filter('body div#article div.tools ul.tags li.chip a')->extract(['href'])[1];
|
||||
$link = $crawler->filter('body div#article div.tools ul.tags li.chip form')->extract(['action'])[0];
|
||||
|
||||
$this->assertStringStartsWith(sprintf('/remove-tag/%s/%s', $entry->getId(), $tag->getId()), $link);
|
||||
}
|
||||
|
|
|
@ -126,8 +126,8 @@ class TagControllerTest extends WallabagCoreTestCase
|
|||
$crawler = $client->request('GET', '/view/' . $entry->getId());
|
||||
$entryUri = $client->getRequest()->getRequestUri();
|
||||
|
||||
$link = $crawler->filter('a[href^="/remove-tag/' . $entry->getId() . '/' . $tag->getId() . '"]')->link();
|
||||
$client->click($link);
|
||||
$form = $crawler->filter('form[action^="/remove-tag/' . $entry->getId() . '/' . $tag->getId() . '"]')->form();
|
||||
$client->submit($form);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame($entryUri, $client->getResponse()->getTargetUrl());
|
||||
|
@ -136,9 +136,8 @@ class TagControllerTest extends WallabagCoreTestCase
|
|||
$entry = $this->getEntityManager()->getRepository(Entry::class)->find($entry->getId());
|
||||
$this->assertNotContains($this->tagName, $entry->getTagsLabel());
|
||||
|
||||
$client->request('GET', '/remove-tag/' . $entry->getId() . '/' . $tag->getId());
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
$client->request('GET', '/view/' . $entry->getId());
|
||||
$this->assertStringNotContainsString('/remove-tag/' . $entry->getId() . '/' . $tag->getId(), $client->getResponse()->getContent());
|
||||
|
||||
$tag = $client->getContainer()
|
||||
->get(EntityManagerInterface::class)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue