From 67c5270fdcad395851bab957651256e83c76dba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Tue, 29 Aug 2023 14:17:53 +0200 Subject: [PATCH] Add a validator on URL entity --- src/Controller/Api/EntryRestController.php | 22 ++++++++++- src/Controller/EntryController.php | 2 + src/Entity/Entry.php | 3 ++ .../Api/EntryRestControllerTest.php | 19 ++++++++++ tests/Controller/EntryControllerTest.php | 37 +++++++++++++++++-- 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/Controller/Api/EntryRestController.php b/src/Controller/Api/EntryRestController.php index ff1abed15..5c77abcd0 100644 --- a/src/Controller/Api/EntryRestController.php +++ b/src/Controller/Api/EntryRestController.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Validator\Validator\ValidatorInterface; use Wallabag\Entity\Entry; use Wallabag\Entity\Tag; use Wallabag\Event\EntryDeletedEvent; @@ -716,8 +717,15 @@ class EntryRestController extends WallabagRestController * * @return JsonResponse */ - public function postEntriesAction(Request $request, EntryRepository $entryRepository, ContentProxy $contentProxy, LoggerInterface $logger, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher) - { + public function postEntriesAction( + Request $request, + EntryRepository $entryRepository, + ContentProxy $contentProxy, + LoggerInterface $logger, + TagsAssigner $tagsAssigner, + EventDispatcherInterface $eventDispatcher, + ValidatorInterface $validator + ) { $this->validateAuthentication(); $url = $request->request->get('url'); @@ -788,6 +796,16 @@ class EntryRestController extends WallabagRestController $contentProxy->setDefaultEntryTitle($entry); } + $errors = $validator->validate($entry); + if (\count($errors) > 0) { + $errorsString = ''; + foreach ($errors as $error) { + $errorsString .= $error->getMessage() . "\n"; + } + + throw new BadRequestHttpException($errorsString); + } + $this->entityManager->persist($entry); $this->entityManager->flush(); diff --git a/src/Controller/EntryController.php b/src/Controller/EntryController.php index 934a77296..71a505ae6 100644 --- a/src/Controller/EntryController.php +++ b/src/Controller/EntryController.php @@ -204,6 +204,8 @@ class EntryController extends AbstractController // entry saved, dispatch event about it! $this->eventDispatcher->dispatch(new EntrySavedEvent($entry), EntrySavedEvent::NAME); + return $this->redirect($this->generateUrl('homepage')); + } elseif ($form->isSubmitted() && !$form->isValid()) { return $this->redirect($this->generateUrl('homepage')); } diff --git a/src/Entity/Entry.php b/src/Entity/Entry.php index 6f109bac2..c1a040ecf 100644 --- a/src/Entity/Entry.php +++ b/src/Entity/Entry.php @@ -75,6 +75,9 @@ class Entry * @var string|null * * @Assert\NotBlank() + * @Assert\Url( + * message = "The url '{{ value }}' is not a valid url", + * ) * @ORM\Column(name="url", type="text", nullable=true) * * @Groups({"entries_for_user", "export_all"}) diff --git a/tests/Controller/Api/EntryRestControllerTest.php b/tests/Controller/Api/EntryRestControllerTest.php index 2fa0c3399..e148d0c08 100644 --- a/tests/Controller/Api/EntryRestControllerTest.php +++ b/tests/Controller/Api/EntryRestControllerTest.php @@ -601,6 +601,25 @@ class EntryRestControllerTest extends WallabagApiTestCase $this->assertSame(400, $this->client->getResponse()->getStatusCode()); } + public function testBadFormatURL() + { + $this->client->request('POST', '/api/entries.json', [ + 'url' => 'wallabagIsAwesome', + 'tags' => 'google', + 'title' => 'New title for my article', + 'content' => 'my content', + 'language' => 'de', + 'published_at' => '2016-09-08T11:55:58+0200', + 'authors' => 'bob,helen', + 'public' => 1, + ]); + + $this->assertSame(400, $this->client->getResponse()->getStatusCode()); + + $content = json_decode($this->client->getResponse()->getContent(), true); + $this->assertStringContainsString('The url \'"wallabagIsAwesome"\' is not a valid url', $content['message']); + } + public function testPostEntry() { $this->client->request('POST', '/api/entries.json', [ diff --git a/tests/Controller/EntryControllerTest.php b/tests/Controller/EntryControllerTest.php index daa21e98a..d981dcd00 100644 --- a/tests/Controller/EntryControllerTest.php +++ b/tests/Controller/EntryControllerTest.php @@ -20,6 +20,7 @@ class EntryControllerTest extends WallabagTestCase public const AN_URL_CONTAINING_AN_ARTICLE_WITH_IMAGE = 'https://www.20minutes.fr/sport/jo_2024/4095122-20240712-jo-paris-2024-saut-ange-bombe-comment-anne-hidalgo-va-plonger-seine-si-fait-vraiment'; public $downloadImagesEnabled = false; public $url = 'https://www.20minutes.fr/sport/jo_2024/4095122-20240712-jo-paris-2024-saut-ange-bombe-comment-anne-hidalgo-va-plonger-seine-si-fait-vraiment'; + public $wrongUrl = 'wallabagIsAwesome'; private $entryDataTestAttribute = '[data-test="entry"]'; /** @@ -137,9 +138,7 @@ class EntryControllerTest extends WallabagTestCase $crawler = $client->submit($form); - $this->assertSame(200, $client->getResponse()->getStatusCode()); - $this->assertCount(1, $alert = $crawler->filter('form ul li')->extract(['_text'])); - $this->assertSame('This value should not be blank.', $alert[0]); + $this->assertSame(302, $client->getResponse()->getStatusCode()); } /** @@ -423,6 +422,38 @@ class EntryControllerTest extends WallabagTestCase $em->flush(); } + /** + * @group NetworkCalls + */ + public function testBadFormatURL() + { + $this->logInAs('admin'); + $client = $this->getTestClient(); + + $client->getContainer()->get(Config::class)->set('store_article_headers', 1); + + $crawler = $client->request('GET', '/new'); + + $this->assertSame(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('form[name=entry]')->form(); + + $data = [ + 'entry[url]' => $this->wrongUrl, + ]; + + $client->submit($form, $data); + + $this->assertSame(302, $client->getResponse()->getStatusCode()); + + $content = $client->getContainer() + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) + ->findByUrlAndUserId($this->wrongUrl, $this->getLoggedInUserId()); + + $this->assertFalse($content); + } + public function testArchive() { $this->logInAs('admin');