1
0
Fork 0
mirror of https://github.com/wallabag/wallabag.git synced 2025-08-26 18:21:02 +00:00

Merge branch '2.6'

This commit is contained in:
Yassine Guedidi 2025-04-10 01:29:49 +02:00
commit e6ce9c524c
28 changed files with 611 additions and 280 deletions

View file

@ -6,6 +6,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
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\Controller\AbstractController;
@ -73,7 +74,7 @@ class DeveloperController extends AbstractController
public function deleteClientAction(Request $request, Client $client, EntityManagerInterface $entityManager, TranslatorInterface $translator)
{
if (!$this->isCsrfTokenValid('delete-client', $request->request->get('token'))) {
throw $this->createAccessDeniedException('Bad CSRF token.');
throw new BadRequestHttpException('Bad CSRF token.');
}
if (null === $this->getUser() || $client->getUser()->getId() !== $this->getUser()->getId()) {

View file

@ -17,6 +17,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Validator\Constraints\Locale as LocaleConstraint;
@ -253,7 +254,7 @@ class ConfigController extends AbstractController
public function disableOtpEmailAction(Request $request)
{
if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) {
throw $this->createAccessDeniedException('Bad CSRF token.');
throw new BadRequestHttpException('Bad CSRF token.');
}
$user = $this->getUser();
@ -278,7 +279,7 @@ class ConfigController extends AbstractController
public function otpEmailAction(Request $request)
{
if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) {
throw $this->createAccessDeniedException('Bad CSRF token.');
throw new BadRequestHttpException('Bad CSRF token.');
}
$user = $this->getUser();
@ -306,7 +307,7 @@ class ConfigController extends AbstractController
public function disableOtpAppAction(Request $request)
{
if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) {
throw $this->createAccessDeniedException('Bad CSRF token.');
throw new BadRequestHttpException('Bad CSRF token.');
}
$user = $this->getUser();
@ -333,7 +334,7 @@ class ConfigController extends AbstractController
public function otpAppAction(Request $request, GoogleAuthenticatorInterface $googleAuthenticator)
{
if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) {
throw $this->createAccessDeniedException('Bad CSRF token.');
throw new BadRequestHttpException('Bad CSRF token.');
}
$user = $this->getUser();
@ -392,7 +393,7 @@ class ConfigController extends AbstractController
public function otpAppCheckAction(Request $request, GoogleAuthenticatorInterface $googleAuthenticator)
{
if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) {
throw $this->createAccessDeniedException('Bad CSRF token.');
throw new BadRequestHttpException('Bad CSRF token.');
}
$isValid = $googleAuthenticator->checkCode(
@ -425,20 +426,20 @@ class ConfigController extends AbstractController
/**
* @return RedirectResponse|JsonResponse
*/
#[Route(path: '/generate-token', name: 'generate_token', methods: ['GET'])]
#[Route(path: '/generate-token', name: 'generate_token', methods: ['POST'])]
#[IsGranted('EDIT_CONFIG')]
public function generateTokenAction(Request $request)
{
if (!$this->isCsrfTokenValid('generate-token', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$config = $this->getConfig();
$config->setFeedToken(Utils::generateToken());
$this->entityManager->persist($config);
$this->entityManager->flush();
if ($request->isXmlHttpRequest()) {
return new JsonResponse(['token' => $config->getFeedToken()]);
}
$this->addFlash(
'notice',
'flashes.config.notice.feed_token_updated'
@ -450,20 +451,20 @@ class ConfigController extends AbstractController
/**
* @return RedirectResponse|JsonResponse
*/
#[Route(path: '/revoke-token', name: 'revoke_token', methods: ['GET'])]
#[Route(path: '/revoke-token', name: 'revoke_token', methods: ['POST'])]
#[IsGranted('EDIT_CONFIG')]
public function revokeTokenAction(Request $request)
{
if (!$this->isCsrfTokenValid('revoke-token', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$config = $this->getConfig();
$config->setFeedToken(null);
$this->entityManager->persist($config);
$this->entityManager->flush();
if ($request->isXmlHttpRequest()) {
return new JsonResponse();
}
$this->addFlash(
'notice',
'flashes.config.notice.feed_token_revoked'
@ -477,10 +478,14 @@ class ConfigController extends AbstractController
*
* @return RedirectResponse
*/
#[Route(path: '/tagging-rule/delete/{taggingRule}', name: 'delete_tagging_rule', methods: ['GET'], requirements: ['taggingRule' => '\d+'])]
#[Route(path: '/tagging-rule/delete/{taggingRule}', name: 'delete_tagging_rule', methods: ['POST'], requirements: ['taggingRule' => '\d+'])]
#[IsGranted('DELETE', subject: 'taggingRule')]
public function deleteTaggingRuleAction(TaggingRule $taggingRule)
public function deleteTaggingRuleAction(Request $request, TaggingRule $taggingRule)
{
if (!$this->isCsrfTokenValid('delete-tagging-rule', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$this->entityManager->remove($taggingRule);
$this->entityManager->flush();
@ -509,10 +514,14 @@ class ConfigController extends AbstractController
*
* @return RedirectResponse
*/
#[Route(path: '/ignore-origin-user-rule/delete/{ignoreOriginUserRule}', name: 'delete_ignore_origin_rule', methods: ['GET'], requirements: ['ignoreOriginUserRule' => '\d+'])]
#[Route(path: '/ignore-origin-user-rule/delete/{ignoreOriginUserRule}', name: 'delete_ignore_origin_rule', methods: ['POST'], requirements: ['ignoreOriginUserRule' => '\d+'])]
#[IsGranted('DELETE', subject: 'ignoreOriginUserRule')]
public function deleteIgnoreOriginRuleAction(IgnoreOriginUserRule $ignoreOriginUserRule)
public function deleteIgnoreOriginRuleAction(Request $request, IgnoreOriginUserRule $ignoreOriginUserRule)
{
if (!$this->isCsrfTokenValid('delete-ignore-origin-rule', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$this->entityManager->remove($ignoreOriginUserRule);
$this->entityManager->flush();
@ -546,7 +555,7 @@ class ConfigController extends AbstractController
public function resetAction(Request $request, string $type, AnnotationRepository $annotationRepository, EntryRepository $entryRepository, TaggingRuleRepository $taggingRuleRepository)
{
if (!$this->isCsrfTokenValid('reset-area', $request->request->get('token'))) {
throw $this->createAccessDeniedException('Bad CSRF token.');
throw new BadRequestHttpException('Bad CSRF token.');
}
switch ($type) {
@ -602,7 +611,7 @@ class ConfigController extends AbstractController
public function deleteAccountAction(Request $request, UserRepository $userRepository, TokenStorageInterface $tokenStorage)
{
if (!$this->isCsrfTokenValid('delete-account', $request->request->get('token'))) {
throw $this->createAccessDeniedException('Bad CSRF token.');
throw new BadRequestHttpException('Bad CSRF token.');
}
$enabledUsers = $userRepository->getSumEnabledUsers();
@ -627,10 +636,14 @@ class ConfigController extends AbstractController
*
* @return RedirectResponse
*/
#[Route(path: '/config/view-mode', name: 'switch_view_mode', methods: ['GET'])]
#[Route(path: '/config/view-mode', name: 'switch_view_mode', methods: ['POST'])]
#[IsGranted('EDIT_CONFIG')]
public function changeViewModeAction(Request $request)
{
if (!$this->isCsrfTokenValid('switch-view-mode', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$user = $this->getUser();
$user->getConfig()->setListMode(!$user->getConfig()->getListMode());
@ -649,10 +662,14 @@ class ConfigController extends AbstractController
*
* @return RedirectResponse
*/
#[Route(path: '/locale/{language}', name: 'changeLocale', methods: ['GET'])]
#[Route(path: '/locale/{language}', name: 'changeLocale', methods: ['POST'])]
#[IsGranted('PUBLIC_ACCESS')]
public function setLocaleAction(Request $request, ValidatorInterface $validator, $language = null)
{
if (!$this->isCsrfTokenValid('change-locale', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$errors = $validator->validate($language, new LocaleConstraint(['canonicalize' => true]));
if (0 === \count($errors)) {

View file

@ -14,6 +14,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
@ -52,6 +53,10 @@ class EntryController extends AbstractController
#[IsGranted('EDIT_ENTRIES')]
public function massAction(Request $request, TagRepository $tagRepository)
{
if (!$this->isCsrfTokenValid('mass-action', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$values = $request->request->all();
$tagsToAdd = [];
@ -395,10 +400,14 @@ class EntryController extends AbstractController
*
* @return RedirectResponse
*/
#[Route(path: '/reload/{id}', name: 'reload_entry', methods: ['GET'], requirements: ['id' => '\d+'])]
#[Route(path: '/reload/{id}', name: 'reload_entry', methods: ['POST'], requirements: ['id' => '\d+'])]
#[IsGranted('RELOAD', subject: 'entry')]
public function reloadAction(Entry $entry)
public function reloadAction(Request $request, Entry $entry)
{
if (!$this->isCsrfTokenValid('reload-entry', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$this->updateEntry($entry, 'entry_reloaded');
// if refreshing entry failed, don't save it
@ -422,10 +431,14 @@ class EntryController extends AbstractController
*
* @return RedirectResponse
*/
#[Route(path: '/archive/{id}', name: 'archive_entry', methods: ['GET'], requirements: ['id' => '\d+'])]
#[Route(path: '/archive/{id}', name: 'archive_entry', methods: ['POST'], requirements: ['id' => '\d+'])]
#[IsGranted('ARCHIVE', subject: 'entry')]
public function toggleArchiveAction(Request $request, Entry $entry)
{
if (!$this->isCsrfTokenValid('archive-entry', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$entry->toggleArchive();
$this->entityManager->flush();
@ -449,10 +462,14 @@ class EntryController extends AbstractController
*
* @return RedirectResponse
*/
#[Route(path: '/star/{id}', name: 'star_entry', methods: ['GET'], requirements: ['id' => '\d+'])]
#[Route(path: '/star/{id}', name: 'star_entry', methods: ['POST'], requirements: ['id' => '\d+'])]
#[IsGranted('STAR', subject: 'entry')]
public function toggleStarAction(Request $request, Entry $entry)
{
if (!$this->isCsrfTokenValid('star-entry', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$entry->toggleStar();
$entry->updateStar($entry->isStarred());
$this->entityManager->flush();
@ -477,10 +494,14 @@ class EntryController extends AbstractController
*
* @return RedirectResponse
*/
#[Route(path: '/delete/{id}', name: 'delete_entry', methods: ['GET'], requirements: ['id' => '\d+'])]
#[Route(path: '/delete/{id}', name: 'delete_entry', methods: ['POST'], requirements: ['id' => '\d+'])]
#[IsGranted('DELETE', subject: 'entry')]
public function deleteEntryAction(Request $request, Entry $entry)
{
if (!$this->isCsrfTokenValid('delete-entry', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
// generates the view url for this entry to check for redirection later
// to avoid redirecting to the deleted entry. Ugh.
$url = $this->generateUrl(
@ -513,10 +534,14 @@ class EntryController extends AbstractController
*
* @return Response
*/
#[Route(path: '/share/{id}', name: 'share', methods: ['GET'], requirements: ['id' => '\d+'])]
#[Route(path: '/share/{id}', name: 'share', methods: ['POST'], requirements: ['id' => '\d+'])]
#[IsGranted('SHARE', subject: 'entry')]
public function shareAction(Entry $entry)
public function shareAction(Request $request, Entry $entry)
{
if (!$this->isCsrfTokenValid('share-entry', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
if (null === $entry->getUid()) {
$entry->generateUid();
@ -534,10 +559,14 @@ class EntryController extends AbstractController
*
* @return Response
*/
#[Route(path: '/share/delete/{id}', name: 'delete_share', methods: ['GET'], requirements: ['id' => '\d+'])]
#[Route(path: '/share/delete/{id}', name: 'delete_share', methods: ['POST'], requirements: ['id' => '\d+'])]
#[IsGranted('UNSHARE', subject: 'entry')]
public function deleteShareAction(Entry $entry)
public function deleteShareAction(Request $request, Entry $entry)
{
if (!$this->isCsrfTokenValid('delete-share', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$entry->cleanUid();
$this->entityManager->persist($entry);

View file

@ -10,6 +10,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
@ -85,10 +86,14 @@ class TagController extends AbstractController
*
* @return Response
*/
#[Route(path: '/remove-tag/{entry}/{tag}', name: 'remove_tag', methods: ['GET'], requirements: ['entry' => '\d+', 'tag' => '\d+'])]
#[Route(path: '/remove-tag/{entry}/{tag}', name: 'remove_tag', methods: ['POST'], requirements: ['entry' => '\d+', 'tag' => '\d+'])]
#[IsGranted('UNTAG', subject: 'entry')]
public function removeTagFromEntry(Request $request, Entry $entry, Tag $tag)
{
if (!$this->isCsrfTokenValid('remove-tag', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$entry->removeTag($tag);
$this->entityManager->flush();
@ -225,10 +230,14 @@ class TagController extends AbstractController
*
* @return Response
*/
#[Route(path: '/tag/search/{filter}', name: 'tag_this_search', methods: ['GET'])]
#[Route(path: '/tag/search/{filter}', name: 'tag_this_search', methods: ['POST'])]
#[IsGranted('CREATE_TAGS')]
public function tagThisSearchAction($filter, Request $request, EntryRepository $entryRepository)
{
if (!$this->isCsrfTokenValid('tag-this-search', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
$currentRoute = $request->query->has('currentRoute') ? $request->query->get('currentRoute') : '';
/** @var QueryBuilder $qb */
@ -260,11 +269,15 @@ class TagController extends AbstractController
*
* @return Response
*/
#[Route(path: '/tag/delete/{slug}', name: 'tag_delete', methods: ['GET'])]
#[Route(path: '/tag/delete/{slug}', name: 'tag_delete', methods: ['POST'])]
#[ParamConverter('tag', options: ['mapping' => ['slug' => 'slug']])]
#[IsGranted('DELETE', subject: 'tag')]
public function removeTagAction(Tag $tag, Request $request, EntryRepository $entryRepository)
{
if (!$this->isCsrfTokenValid('tag-delete', $request->request->get('token'))) {
throw new BadRequestHttpException('Bad CSRF token.');
}
foreach ($tag->getEntriesByUserId($this->getUser()->getId()) as $entry) {
$entryRepository->removeTag($this->getUser()->getId(), $tag);
}