diff --git a/app/Resources/static/themes/material/css/cards.scss b/app/Resources/static/themes/material/css/cards.scss
index 830897b24..0330da5d9 100644
--- a/app/Resources/static/themes/material/css/cards.scss
+++ b/app/Resources/static/themes/material/css/cards.scss
@@ -177,6 +177,7 @@ a.original:not(.waves-effect) {
.card-entry-tags a,
.card-entry-labels a,
.card-tag-labels a,
+.card-tag-labels button,
.card-entry-labels-hidden a,
#list .chip a {
text-decoration: none;
diff --git a/app/Resources/static/themes/material/css/dark_theme.scss b/app/Resources/static/themes/material/css/dark_theme.scss
index ac38b566d..532442360 100644
--- a/app/Resources/static/themes/material/css/dark_theme.scss
+++ b/app/Resources/static/themes/material/css/dark_theme.scss
@@ -62,7 +62,9 @@
.nav-panels .input-field input:focus,
.results-item,
.side-nav li > a,
- .side-nav li > a > i.material-icons {
+ .side-nav li > a > i.material-icons,
+ .side-nav li button,
+ .side-nav li button > i.material-icons {
color: #dfdfdf;
}
@@ -87,6 +89,7 @@
.mass-action-tags .mass-action-tags-input.mass-action-tags-input,
.side-nav li:not(.logo) > a:hover,
+ .side-nav li:not(.logo) button:hover,
.side-nav .collapsible-header:hover,
.side-nav.fixed .collapsible-header:hover {
background-color: #1d1d1d;
diff --git a/app/Resources/static/themes/material/css/nav.scss b/app/Resources/static/themes/material/css/nav.scss
index a085febd9..8a83596ff 100644
--- a/app/Resources/static/themes/material/css/nav.scss
+++ b/app/Resources/static/themes/material/css/nav.scss
@@ -6,11 +6,32 @@ nav {
line-height: initial;
}
+// adapted from anchor styles from node_modules/materialize-css/sass/components/_navbar.scss
+nav ul button {
+ transition: background-color .3s;
+ font-size: 1rem;
+ color: #fff;
+ display: block;
+ padding: 0 15px;
+ cursor: pointer;
+ background: none;
+ border: 0;
+
+ &:focus {
+ background: none;
+ }
+
+ &:hover {
+ background-color: rgba(0 0 0 / 10%);
+ }
+}
+
nav {
input {
color: #aaa;
}
+ ul button:hover,
ul a:hover {
background-color: initial;
}
@@ -34,6 +55,7 @@ nav {
justify-content: space-between;
align-items: center;
+ button,
a {
padding: 10px 15px;
}
diff --git a/app/Resources/static/themes/material/css/sidenav.scss b/app/Resources/static/themes/material/css/sidenav.scss
index 00e4c5c2a..a7e50851e 100644
--- a/app/Resources/static/themes/material/css/sidenav.scss
+++ b/app/Resources/static/themes/material/css/sidenav.scss
@@ -12,6 +12,7 @@
background: initial;
}
+ & button > i.material-icons.theme-toggle-icon,
& > a > i.material-icons.theme-toggle-icon {
float: none;
margin-left: 0;
@@ -22,6 +23,7 @@
margin: 0;
}
+ &.fixed button,
&.fixed a {
font-size: 13px;
line-height: 44px;
@@ -41,7 +43,35 @@
}
}
-.bold > a {
+// adapted from anchor styles from node_modules/materialize-css/sass/components/_sideNav.scss
+.side-nav li button {
+ color: rgba(0 0 0 / 87%);
+ display: block;
+ font-size: 14px;
+ font-weight: 500;
+ height: 48px;
+ line-height: 48px;
+ padding: 0 (16px * 2);
+ width: 100%;
+ text-align: left;
+
+ &:hover {
+ background-color: rgba(0 0 0 / 5%);
+ }
+
+ & > i,
+ & > i.material-icons {
+ float: left;
+ height: 48px;
+ line-height: 48px;
+ margin: 0 (16px * 2) 0 0;
+ width: 24px;
+ color: rgba(0 0 0 / 54%);
+ }
+}
+
+.bold > a,
+.bold > button {
font-weight: bold;
}
diff --git a/app/Resources/static/themes/material/css/various.scss b/app/Resources/static/themes/material/css/various.scss
index ad0703afa..94bb95bd0 100644
--- a/app/Resources/static/themes/material/css/various.scss
+++ b/app/Resources/static/themes/material/css/various.scss
@@ -38,3 +38,18 @@ nav .input-field input {
.tab {
flex: 1;
}
+
+.btn-link {
+ background: none;
+ border: 0;
+ padding: 0;
+ color: $blue-accent-color;
+
+ &:focus {
+ background: none;
+ }
+}
+
+.inline-block {
+ display: inline-block;
+}
diff --git a/app/Resources/static/themes/material/index.js b/app/Resources/static/themes/material/index.js
index 704a9ea11..24adf8aab 100755
--- a/app/Resources/static/themes/material/index.js
+++ b/app/Resources/static/themes/material/index.js
@@ -228,10 +228,10 @@ $(document).ready(() => {
});
});
}
- $('form[name="form_mass_action"] input[name="tags"]').on('keydown', (e) => {
+ $('input[name="tags"][form="form_mass_action"]').on('keydown', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
- $('form[name="form_mass_action"] button[name="tag"]').trigger('click');
+ $('button[name="tag"][form="form_mass_action"]').trigger('click');
}
});
});
diff --git a/app/Resources/static/themes/material/js/shortcuts/entry.js b/app/Resources/static/themes/material/js/shortcuts/entry.js
index e19800bd3..1c916b200 100644
--- a/app/Resources/static/themes/material/js/shortcuts/entry.js
+++ b/app/Resources/static/themes/material/js/shortcuts/entry.js
@@ -10,17 +10,17 @@ $(document).ready(() => {
/* mark as favorite */
Mousetrap.bind('f', () => {
- $('ul.side-nav a.favorite i')[0].click();
+ $('ul.side-nav button.favorite i')[0].click();
});
/* mark as read */
Mousetrap.bind('a', () => {
- $('ul.side-nav a.markasread i')[0].click();
+ $('ul.side-nav button.markasread i')[0].click();
});
/* delete */
Mousetrap.bind('del', () => {
- $('ul.side-nav a.delete i')[0].click();
+ $('ul.side-nav button.delete i')[0].click();
});
}
});
diff --git a/app/config/config.yml b/app/config/config.yml
index 064df3623..cd981163d 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -30,6 +30,7 @@ framework:
handler_id: session.handler.native_file
save_path: "%kernel.project_dir%/var/sessions/%kernel.environment%"
cookie_secure: auto
+ cookie_samesite: lax
fragments: ~
http_method_override: true
assets: ~
diff --git a/src/Wallabag/ApiBundle/Controller/DeveloperController.php b/src/Wallabag/ApiBundle/Controller/DeveloperController.php
index 0c08968e2..5b2d6accc 100644
--- a/src/Wallabag/ApiBundle/Controller/DeveloperController.php
+++ b/src/Wallabag/ApiBundle/Controller/DeveloperController.php
@@ -7,6 +7,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
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\ApiBundle\Entity\Client;
@@ -76,7 +77,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()) {
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php
index 4709a4d2e..1ba7faaed 100644
--- a/src/Wallabag/CoreBundle/Controller/ConfigController.php
+++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php
@@ -16,6 +16,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;
@@ -262,7 +263,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();
@@ -286,7 +287,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();
@@ -313,7 +314,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();
@@ -339,7 +340,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();
@@ -398,7 +399,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(
@@ -429,22 +430,22 @@ class ConfigController extends AbstractController
}
/**
- * @Route("/generate-token", name="generate_token")
+ * @Route("/generate-token", name="generate_token", methods={"POST"})
*
* @return RedirectResponse|JsonResponse
*/
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'
@@ -454,22 +455,22 @@ class ConfigController extends AbstractController
}
/**
- * @Route("/revoke-token", name="revoke_token")
+ * @Route("/revoke-token", name="revoke_token", methods={"POST"})
*
* @return RedirectResponse|JsonResponse
*/
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'
@@ -481,12 +482,16 @@ class ConfigController extends AbstractController
/**
* Deletes a tagging rule and redirect to the config homepage.
*
- * @Route("/tagging-rule/delete/{id}", requirements={"id" = "\d+"}, name="delete_tagging_rule")
+ * @Route("/tagging-rule/delete/{id}", name="delete_tagging_rule", methods={"POST"}, requirements={"id" = "\d+"})
*
* @return RedirectResponse
*/
- public function deleteTaggingRuleAction(TaggingRule $rule)
+ public function deleteTaggingRuleAction(Request $request, TaggingRule $rule)
{
+ if (!$this->isCsrfTokenValid('delete-tagging-rule', $request->request->get('token'))) {
+ throw new BadRequestHttpException('Bad CSRF token.');
+ }
+
$this->validateRuleAction($rule);
$this->entityManager->remove($rule);
@@ -517,12 +522,16 @@ class ConfigController extends AbstractController
/**
* Deletes an ignore origin rule and redirect to the config homepage.
*
- * @Route("/ignore-origin-user-rule/delete/{id}", requirements={"id" = "\d+"}, name="delete_ignore_origin_rule")
+ * @Route("/ignore-origin-user-rule/delete/{id}", name="delete_ignore_origin_rule", methods={"POST"}, requirements={"id" = "\d+"})
*
* @return RedirectResponse
*/
- public function deleteIgnoreOriginRuleAction(IgnoreOriginUserRule $rule)
+ public function deleteIgnoreOriginRuleAction(Request $request, IgnoreOriginUserRule $rule)
{
+ if (!$this->isCsrfTokenValid('delete-ignore-origin-rule', $request->request->get('token'))) {
+ throw new BadRequestHttpException('Bad CSRF token.');
+ }
+
$this->validateRuleAction($rule);
$this->entityManager->remove($rule);
@@ -560,7 +569,7 @@ class ConfigController extends AbstractController
public function resetAction(Request $request, string $type, AnnotationRepository $annotationRepository, EntryRepository $entryRepository)
{
if (!$this->isCsrfTokenValid('reset-area', $request->request->get('token'))) {
- throw $this->createAccessDeniedException('Bad CSRF token.');
+ throw new BadRequestHttpException('Bad CSRF token.');
}
switch ($type) {
@@ -614,7 +623,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();
@@ -637,12 +646,16 @@ class ConfigController extends AbstractController
/**
* Switch view mode for current user.
*
- * @Route("/config/view-mode", name="switch_view_mode")
+ * @Route("/config/view-mode", name="switch_view_mode", methods={"POST"})
*
* @return RedirectResponse
*/
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());
@@ -659,12 +672,16 @@ class ConfigController extends AbstractController
*
* @param string $language
*
- * @Route("/locale/{language}", name="changeLocale")
+ * @Route("/locale/{language}", name="changeLocale", methods={"POST"})
*
* @return RedirectResponse
*/
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()));
if (0 === \count($errors)) {
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php
index 3b624dd1f..be862d750 100644
--- a/src/Wallabag/CoreBundle/Controller/EntryController.php
+++ b/src/Wallabag/CoreBundle/Controller/EntryController.php
@@ -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\Contracts\Translation\TranslatorInterface;
use Wallabag\CoreBundle\Entity\Entry;
@@ -52,12 +53,16 @@ class EntryController extends AbstractController
}
/**
- * @Route("/mass", name="mass_action")
+ * @Route("/mass", name="mass_action", methods={"POST"})
*
* @return Response
*/
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 = [];
@@ -400,12 +405,16 @@ class EntryController extends AbstractController
* Reload an entry.
* Refetch content from the website and make it readable again.
*
- * @Route("/reload/{id}", requirements={"id" = "\d+"}, name="reload_entry")
+ * @Route("/reload/{id}", name="reload_entry", methods={"POST"}, requirements={"id" = "\d+"})
*
* @return RedirectResponse
*/
- 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->checkUserAction($entry);
$this->updateEntry($entry, 'entry_reloaded');
@@ -429,12 +438,16 @@ class EntryController extends AbstractController
/**
* Changes read status for an entry.
*
- * @Route("/archive/{id}", requirements={"id" = "\d+"}, name="archive_entry")
+ * @Route("/archive/{id}", name="archive_entry", methods={"POST"}, requirements={"id" = "\d+"})
*
* @return RedirectResponse
*/
public function toggleArchiveAction(Request $request, Entry $entry)
{
+ if (!$this->isCsrfTokenValid('archive-entry', $request->request->get('token'))) {
+ throw new BadRequestHttpException('Bad CSRF token.');
+ }
+
$this->checkUserAction($entry);
$entry->toggleArchive();
@@ -458,12 +471,16 @@ class EntryController extends AbstractController
/**
* Changes starred status for an entry.
*
- * @Route("/star/{id}", requirements={"id" = "\d+"}, name="star_entry")
+ * @Route("/star/{id}", name="star_entry", methods={"POST"}, requirements={"id" = "\d+"})
*
* @return RedirectResponse
*/
public function toggleStarAction(Request $request, Entry $entry)
{
+ if (!$this->isCsrfTokenValid('star-entry', $request->request->get('token'))) {
+ throw new BadRequestHttpException('Bad CSRF token.');
+ }
+
$this->checkUserAction($entry);
$entry->toggleStar();
@@ -488,12 +505,16 @@ class EntryController extends AbstractController
/**
* Deletes entry and redirect to the homepage or the last viewed page.
*
- * @Route("/delete/{id}", requirements={"id" = "\d+"}, name="delete_entry")
+ * @Route("/delete/{id}", name="delete_entry", methods={"POST"}, requirements={"id" = "\d+"})
*
* @return RedirectResponse
*/
public function deleteEntryAction(Request $request, Entry $entry)
{
+ if (!$this->isCsrfTokenValid('delete-entry', $request->request->get('token'))) {
+ throw new BadRequestHttpException('Bad CSRF token.');
+ }
+
$this->checkUserAction($entry);
// generates the view url for this entry to check for redirection later
@@ -526,12 +547,16 @@ class EntryController extends AbstractController
/**
* Get public URL for entry (and generate it if necessary).
*
- * @Route("/share/{id}", requirements={"id" = "\d+"}, name="share")
+ * @Route("/share/{id}", name="share", methods={"POST"}, requirements={"id" = "\d+"})
*
* @return Response
*/
- 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.');
+ }
+
$this->checkUserAction($entry);
if (null === $entry->getUid()) {
@@ -549,12 +574,16 @@ class EntryController extends AbstractController
/**
* Disable public sharing for an entry.
*
- * @Route("/share/delete/{id}", requirements={"id" = "\d+"}, name="delete_share")
+ * @Route("/share/delete/{id}", name="delete_share", methods={"POST"}, requirements={"id" = "\d+"})
*
* @return Response
*/
- 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.');
+ }
+
$this->checkUserAction($entry);
$entry->cleanUid();
@@ -570,7 +599,7 @@ class EntryController extends AbstractController
/**
* Ability to view a content publicly.
*
- * @Route("/share/{uid}", requirements={"uid" = ".+"}, name="share_entry")
+ * @Route("/share/{uid}", name="share_entry", methods={"GET"}, requirements={"uid" = ".+"})
* @Cache(maxage="25200", smaxage="25200", public=true)
*
* @return Response
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php
index 804512563..9b7a189bf 100644
--- a/src/Wallabag/CoreBundle/Controller/TagController.php
+++ b/src/Wallabag/CoreBundle/Controller/TagController.php
@@ -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);
@@ -228,12 +233,16 @@ class TagController extends AbstractController
/**
* Tag search results with the current search term.
*
- * @Route("/tag/search/{filter}", name="tag_this_search")
+ * @Route("/tag/search/{filter}", name="tag_this_search", methods={"POST"})
*
* @return Response
*/
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 */
@@ -263,13 +272,17 @@ class TagController extends AbstractController
/**
* Delete a given tag for the current user.
*
- * @Route("/tag/delete/{slug}", name="tag_delete")
+ * @Route("/tag/delete/{slug}", name="tag_delete", methods={"POST"})
* @ParamConverter("tag", options={"mapping": {"slug": "slug"}})
*
* @return Response
*/
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);
}
diff --git a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig
index d52aa4c51..59031054d 100644
--- a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig
@@ -123,48 +123,63 @@
+
+
+ {{ 'config.form_feed.description'|trans }}
+
+
+
+
+
+
{{ 'config.form_feed.token_label'|trans }}
+
+ {% if feed.token %}
+ {{ feed.token }}
+ {% else %}
+ {{ 'config.form_feed.no_token'|trans }}
+ {% endif %}
+
+ {% if feed.token %}
+ –
+
+ –
+
+ {% else %}
+ –
+
+ {% endif %}
+
+
+
+ {% if feed.token %}
+
+
+
{{ 'config.form_feed.feed_links'|trans }}
+
+
+
+ {% endif %}
+
{{ form_start(form.feed) }}
{{ form_errors(form.feed) }}
-
-
- {{ 'config.form_feed.description'|trans }}
-
-
-
-
-
-
{{ 'config.form_feed.token_label'|trans }}
-
-
-
- {% if feed.token %}
-
-
-
{{ 'config.form_feed.feed_links'|trans }}
-
-
-
- {% endif %}
-
diff --git a/src/Wallabag/CoreBundle/Resources/views/Entry/_card_list.html.twig b/src/Wallabag/CoreBundle/Resources/views/Entry/_card_list.html.twig
index 78b918912..41877a0f5 100644
--- a/src/Wallabag/CoreBundle/Resources/views/Entry/_card_list.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/Entry/_card_list.html.twig
@@ -15,9 +15,27 @@
diff --git a/src/Wallabag/CoreBundle/Resources/views/Entry/_tags.html.twig b/src/Wallabag/CoreBundle/Resources/views/Entry/_tags.html.twig
index 2ab67e1c8..9a7db546f 100644
--- a/src/Wallabag/CoreBundle/Resources/views/Entry/_tags.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/Entry/_tags.html.twig
@@ -5,9 +5,13 @@
{{ tag.label }}
{% if withRemove is defined and withRemove == true %}
{% set current_path = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %}
-
- delete
-
+
{% endif %}
{% endfor %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/Entry/entries.html.twig
index 2c26b24af..a02094d42 100644
--- a/src/Wallabag/CoreBundle/Resources/views/Entry/entries.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/Entry/entries.html.twig
@@ -26,12 +26,20 @@
{% if current_route == 'homepage' %}
{% set current_route = 'unread' %}
{% endif %}
-
- {% if current_route == 'search' %}
{% endif %}
+ {% if current_route == 'search' %}
+
+ {% endif %}
{% if entries.getNbPages > 1 %}
{{ pagerfanta(entries, 'default_wallabag') }}
{% endif %}
@@ -50,15 +64,15 @@
@@ -77,7 +91,6 @@
{% endfor %}
{% endif %}
-
{% if entries.getNbPages > 1 %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig
index 9ce783bbf..505f60eba 100644
--- a/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig
@@ -26,14 +26,22 @@
@@ -56,10 +64,14 @@
-
+
@@ -69,25 +81,37 @@
{% endif %}
-
+
-
+
-
+
@@ -135,14 +159,22 @@
diff --git a/src/Wallabag/CoreBundle/Resources/views/Tag/tags.html.twig b/src/Wallabag/CoreBundle/Resources/views/Tag/tags.html.twig
index bff22436e..361947762 100644
--- a/src/Wallabag/CoreBundle/Resources/views/Tag/tags.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/Tag/tags.html.twig
@@ -28,9 +28,13 @@
mode_edit
{% endif %}
-
- delete
-
+
{% if app.user.config.feedToken %}
rss_feed
{% endif %}
diff --git a/templates/bundles/FOSUserBundle/layout.html.twig b/templates/bundles/FOSUserBundle/layout.html.twig
index 937fd5cb0..191b492e5 100644
--- a/templates/bundles/FOSUserBundle/layout.html.twig
+++ b/templates/bundles/FOSUserBundle/layout.html.twig
@@ -16,9 +16,23 @@
{% endblock fos_user_content %}
diff --git a/tests/Wallabag/ApiBundle/Controller/DeveloperControllerTest.php b/tests/Wallabag/ApiBundle/Controller/DeveloperControllerTest.php
index 35573809a..31218a057 100644
--- a/tests/Wallabag/ApiBundle/Controller/DeveloperControllerTest.php
+++ b/tests/Wallabag/ApiBundle/Controller/DeveloperControllerTest.php
@@ -105,7 +105,7 @@ class DeveloperControllerTest extends WallabagCoreTestCase
$this->logInAs('bob');
$client->request('POST', '/developer/client/delete/' . $adminApiClient->getId());
- $this->assertSame(403, $client->getResponse()->getStatusCode());
+ $this->assertSame(400, $client->getResponse()->getStatusCode());
// Try to remove the admin's client with the good user
$this->logInAs('admin');
diff --git a/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php
index 6c049e1dc..c4bcf6194 100644
--- a/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php
@@ -328,7 +328,8 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('config.form_feed.no_token', $body[0]);
- $client->request('GET', '/generate-token');
+ $client->submit($crawler->selectButton('config.form_feed.token_create')->form());
+
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
@@ -337,38 +338,34 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertStringContainsString('config.form_feed.token_reset', $body[0]);
}
- public function testGenerateTokenAjax()
- {
- $this->logInAs('admin');
- $client = $this->getTestClient();
-
- $client->request(
- 'GET',
- '/generate-token',
- [],
- [],
- ['HTTP_X-Requested-With' => 'XMLHttpRequest']
- );
-
- $this->assertSame(200, $client->getResponse()->getStatusCode());
- $content = json_decode($client->getResponse()->getContent(), true);
- $this->assertArrayHasKey('token', $content);
- }
-
public function testRevokeTokenAjax()
{
$this->logInAs('admin');
$client = $this->getTestClient();
- $client->request(
- 'GET',
- '/revoke-token',
- [],
- [],
- ['HTTP_X-Requested-With' => 'XMLHttpRequest']
- );
+ // set the token
+ $em = $client->getContainer()->get(EntityManagerInterface::class);
+ $user = $em
+ ->getRepository(User::class)
+ ->findOneByUsername('admin');
- $this->assertSame(200, $client->getResponse()->getStatusCode());
+ if (!$user) {
+ $this->markTestSkipped('No user found in db.');
+ }
+
+ $config = $user->getConfig();
+ $config->setFeedToken('abcd1234');
+ $em->persist($config);
+ $em->flush();
+
+ $crawler = $client->request('GET', '/config');
+
+ $client->submit($crawler->selectButton('config.form_feed.token_revoke')->form());
+
+ $crawler = $client->followRedirect();
+
+ $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+ $this->assertStringContainsString('config.form_feed.token_create', $body[0]);
}
public function testFeedUpdate()
@@ -484,9 +481,8 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertStringContainsString('readingTime <= 30', $crawler->filter('body')->extract(['_text'])[0]);
- $deleteLink = $crawler->filter('.delete_tagging_rule')->last()->link();
+ $crawler = $client->submit($crawler->filter('#set5')->selectButton('delete')->form());
- $crawler = $client->click($deleteLink);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
@@ -576,11 +572,11 @@ class ConfigControllerTest extends WallabagCoreTestCase
->getRepository(TaggingRule::class)
->findAll()[0];
- $crawler = $client->request('GET', '/tagging-rule/delete/' . $rule->getId());
+ $crawler = $client->request('POST', '/tagging-rule/delete/' . $rule->getId());
- $this->assertSame(403, $client->getResponse()->getStatusCode());
+ $this->assertSame(400, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
- $this->assertStringContainsString('You can not access this rule', $body[0]);
+ $this->assertStringContainsString('Bad CSRF token.', $body[0]);
}
public function testEditingTaggingRuleFromAnOtherUser()
@@ -646,9 +642,9 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertStringContainsString('host = "example.org"', $crawler->filter('body')->extract(['_text'])[0]);
- $deleteLink = $crawler->filter('div[id=set6] a.delete')->last()->link();
+ $form = $crawler->filter('#set6')->selectButton('delete')->form();
- $crawler = $client->click($deleteLink);
+ $crawler = $client->submit($form);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
@@ -713,11 +709,11 @@ class ConfigControllerTest extends WallabagCoreTestCase
->getRepository(IgnoreOriginUserRule::class)
->findAll()[0];
- $crawler = $client->request('GET', '/ignore-origin-user-rule/edit/' . $rule->getId());
+ $crawler = $client->request('POST', '/ignore-origin-user-rule/delete/' . $rule->getId());
- $this->assertSame(403, $client->getResponse()->getStatusCode());
+ $this->assertSame(400, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
- $this->assertStringContainsString('You can not access this rule', $body[0]);
+ $this->assertStringContainsString('Bad CSRF token.', $body[0]);
}
public function testEditingIgnoreOriginRuleFromAnOtherUser()
@@ -798,7 +794,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertStringNotContainsString('config.form_user.delete.button', $body[0]);
$client->request('POST', '/account/delete');
- $this->assertSame(403, $client->getResponse()->getStatusCode());
+ $this->assertSame(400, $client->getResponse()->getStatusCode());
$user = $em
->getRepository(User::class)
@@ -1120,37 +1116,38 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->logInAs('admin');
$client = $this->getTestClient();
- $client->request('GET', '/unread/list');
+ $crawler = $client->request('GET', '/unread/list');
$this->assertStringContainsString('row data', $client->getResponse()->getContent());
- $client->request('GET', '/config/view-mode');
- $crawler = $client->followRedirect();
+ $form = $crawler->filter('.nb-results')->selectButton('view_list')->form();
- $client->request('GET', '/unread/list');
+ $client->submit($form);
+
+ $client->followRedirect();
$this->assertStringContainsString('collection', $client->getResponse()->getContent());
-
- $client->request('GET', '/config/view-mode');
}
public function testChangeLocaleWithoutReferer()
{
$client = $this->getTestClient();
- $client->request('GET', '/locale/de');
- $client->followRedirect();
+ $crawler = $client->request('POST', '/locale/de');
- $this->assertSame('de', $client->getRequest()->getLocale());
- $this->assertSame('de', $client->getContainer()->get(SessionInterface::class)->get('_locale'));
+ $this->assertSame(400, $client->getResponse()->getStatusCode());
+ $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+ $this->assertStringContainsString('Bad CSRF token.', $body[0]);
}
public function testChangeLocaleWithReferer()
{
$client = $this->getTestClient();
- $client->request('GET', '/login');
- $client->request('GET', '/locale/de');
+ $crawler = $client->request('GET', '/login');
+
+ $client->submit($crawler->selectButton('Deutsch')->form());
+
$client->followRedirect();
$this->assertSame('de', $client->getRequest()->getLocale());
@@ -1161,8 +1158,12 @@ class ConfigControllerTest extends WallabagCoreTestCase
{
$client = $this->getTestClient();
- $client->request('GET', '/login');
- $client->request('GET', '/locale/yuyuyuyu');
+ $crawler = $client->request('GET', '/login');
+ $token = $crawler->filter('form[action="/locale/de"] input[name=token]')->attr('value');
+
+ $client->request('POST', '/locale/yuyuyuyu', [
+ 'token' => $token,
+ ]);
$client->followRedirect();
$this->assertNotSame('yuyuyuyu', $client->getRequest()->getLocale());
@@ -1382,7 +1383,5 @@ class ConfigControllerTest extends WallabagCoreTestCase
$client->request('GET', '/unread/list');
$this->assertStringNotContainsString('class="preview"', $client->getResponse()->getContent());
-
- $client->request('GET', '/config/view-mode');
}
}
diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
index 78143770e..f8f47d8b7 100644
--- a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
@@ -509,7 +509,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
- $client->request('GET', '/reload/' . $entry->getId());
+ $crawler = $client->request('GET', '/view/' . $entry->getId());
+
+ $client->submit($crawler->selectButton('entry.view.left_menu.re_fetch_content')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode());
@@ -530,7 +532,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->persist($entry);
$this->getEntityManager()->flush();
- $client->request('GET', '/reload/' . $entry->getId());
+ $crawler = $client->request('GET', '/view/' . $entry->getId());
+
+ $client->submit($crawler->selectButton('entry.view.left_menu.re_fetch_content')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode());
@@ -641,7 +645,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
- $client->request('GET', '/archive/' . $entry->getId());
+ $crawler = $client->request('GET', '/view/' . $entry->getId());
+
+ $client->submit($crawler->filter('.left-bar')->selectButton('entry.view.left_menu.set_as_read')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode());
@@ -664,7 +670,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
- $client->request('GET', '/star/' . $entry->getId());
+ $crawler = $client->request('GET', '/view/' . $entry->getId());
+
+ $client->submit($crawler->filter('.left-bar')->selectButton('entry.view.left_menu.set_as_starred')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode());
@@ -686,13 +694,11 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->persist($entry);
$this->getEntityManager()->flush();
- $client->request('GET', '/delete/' . $entry->getId());
+ $crawler = $client->request('POST', '/delete/' . $entry->getId());
- $this->assertSame(302, $client->getResponse()->getStatusCode());
-
- $client->request('GET', '/delete/' . $entry->getId());
-
- $this->assertSame(404, $client->getResponse()->getStatusCode());
+ $this->assertSame(400, $client->getResponse()->getStatusCode());
+ $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+ $this->assertStringContainsString('Bad CSRF token.', $body[0]);
}
/**
@@ -728,10 +734,11 @@ class EntryControllerTest extends WallabagCoreTestCase
$em->persist($content);
$em->flush();
- $client->request('GET', '/view/' . $content->getId());
+ $crawler = $client->request('GET', '/view/' . $content->getId());
$this->assertSame(200, $client->getResponse()->getStatusCode());
- $client->request('GET', '/delete/' . $content->getId());
+ $client->submit($crawler->filter('.left-bar')->selectButton('entry.view.left_menu.delete')->form());
+
$this->assertSame(302, $client->getResponse()->getStatusCode());
$client->followRedirect();
@@ -1148,7 +1155,10 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertSame(404, $client->getResponse()->getStatusCode());
// generating the uid
- $client->request('GET', '/share/' . $content->getId());
+ $crawler = $client->request('GET', '/view/' . $content->getId());
+
+ $client->submit($crawler->filter('.left-bar')->selectButton('entry.view.left_menu.public_link')->form());
+
$this->assertSame(302, $client->getResponse()->getStatusCode());
$shareUrl = $client->getResponse()->getTargetUrl();
@@ -1175,12 +1185,19 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertSame(404, $client->getResponse()->getStatusCode());
// removing the share
- $client->request('GET', '/share/delete/' . $content->getId());
+ $client->getContainer()->get(Config::class)->set('share_public', 1);
+ $this->logInAs('admin');
+ $crawler = $client->request('GET', '/view/' . $content->getId());
+
+ $client->submit($crawler->filter('.left-bar')->selectButton('entry.view.left_menu.delete_public_link')->form());
+
$this->assertSame(302, $client->getResponse()->getStatusCode());
- // share is now disable
+ // share is now removed
$client->request('GET', '/share/' . $content->getUid());
$this->assertSame(404, $client->getResponse()->getStatusCode());
+
+ $client->getContainer()->get(Config::class)->set('share_public', 0);
}
/**
@@ -1256,7 +1273,9 @@ class EntryControllerTest extends WallabagCoreTestCase
->getRepository(Entry::class)
->findByUrlAndUserId($url, $this->getLoggedInUserId());
- $client->request('GET', '/delete/' . $content->getId());
+ $crawler = $client->request('GET', '/view/' . $content->getId());
+
+ $client->submit($crawler->filter('.left-bar')->selectButton('entry.view.left_menu.delete')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode());
@@ -1279,8 +1298,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->flush();
- $client->request('GET', '/view/' . $entry->getId());
- $client->request('GET', '/archive/' . $entry->getId());
+ $crawler = $client->request('GET', '/view/' . $entry->getId());
+
+ $client->submit($crawler->filter('.left-bar')->selectButton('entry.view.left_menu.set_as_read')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertSame('/', $client->getResponse()->headers->get('location'));
@@ -1304,8 +1324,7 @@ class EntryControllerTest extends WallabagCoreTestCase
$crawler = $client->request('GET', '/view/' . $entry->getId());
- $link = $crawler->filter('a[id="markAsRead"]')->link();
- $client->click($link);
+ $client->submit($crawler->filter('.left-bar')->selectButton('entry.view.left_menu.set_as_read')->form());
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('/view/' . $entry->getId(), $client->getResponse()->headers->get('location'));
@@ -1429,7 +1448,8 @@ class EntryControllerTest extends WallabagCoreTestCase
$crawler = $client->submit($form, $data);
$this->assertCount(1, $crawler->filter($this->entryDataTestAttribute));
- $client->request('GET', '/delete/' . $entry->getId());
+
+ $client->submit($crawler->filter('.tools, .tools-list')->selectButton('delete')->form());
// test on list of all articles
$crawler = $client->request('GET', '/all/list');
@@ -1500,8 +1520,8 @@ class EntryControllerTest extends WallabagCoreTestCase
$crawler = $client->submit($form, $data);
$currentUrl = $client->getRequest()->getUri();
- $element = $crawler->filter('a[data-action="delete"]')->link();
- $client->click($element);
+ $form = $crawler->filter('.tools, .tools-list')->selectButton('delete')->form();
+ $client->submit($form);
$client->followRedirect();
$nextUrl = $client->getRequest()->getUri();
$this->assertSame($currentUrl, $nextUrl);
@@ -1674,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();
@@ -1685,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);
}
@@ -1744,11 +1761,15 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->clear();
$entries = [];
- $entries[] = $entry1->getId();
- $entries[] = $entry2->getId();
+ $entries[] = $entry1Id = $entry1->getId();
+ $entries[] = $entry2Id = $entry2->getId();
+
+ $crawler = $client->request('GET', '/all/list');
+ $token = $crawler->filter('#form_mass_action input[name=token]')->attr('value');
// Mass actions : archive
$client->request('POST', '/mass', [
+ 'token' => $token,
'toggle-archive' => '',
'entry-checkbox' => $entries,
]);
@@ -1769,8 +1790,12 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertSame(1, $res->isArchived());
+ $crawler = $client->request('GET', '/all/list');
+ $token = $crawler->filter('#form_mass_action input[name=token]')->attr('value');
+
// Mass actions : star
$client->request('POST', '/mass', [
+ 'token' => $token,
'toggle-star' => '',
'entry-checkbox' => $entries,
]);
@@ -1791,8 +1816,12 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertSame(1, $res->isStarred());
+ $crawler = $client->request('GET', '/all/list');
+ $token = $crawler->filter('#form_mass_action input[name=token]')->attr('value');
+
// Mass actions : tag
$client->request('POST', '/mass', [
+ 'token' => $token,
'tag' => '',
'tags' => 'foo',
'entry-checkbox' => $entries,
@@ -1821,17 +1850,29 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertNotContains('foo', $res->getTagsLabel());
+ $crawler = $client->request('GET', '/all/list');
+ $token = $crawler->filter('#form_mass_action input[name=token]')->attr('value');
+
// Mass actions : delete
$client->request('POST', '/mass', [
+ 'token' => $token,
'delete' => '',
'entry-checkbox' => $entries,
]);
- $client->request('GET', '/delete/' . $entry1->getId());
- $this->assertSame(404, $client->getResponse()->getStatusCode());
+ $res = $client->getContainer()
+ ->get(EntityManagerInterface::class)
+ ->getRepository(Entry::class)
+ ->find($entry1Id);
- $client->request('GET', '/delete/' . $entry2->getId());
- $this->assertSame(404, $client->getResponse()->getStatusCode());
+ $this->assertNull($res);
+
+ $res = $client->getContainer()
+ ->get(EntityManagerInterface::class)
+ ->getRepository(Entry::class)
+ ->find($entry2Id);
+
+ $this->assertNull($res);
}
public function testGetSameDomainEntries()
diff --git a/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php b/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php
index 9c5f61fd0..a49656c94 100644
--- a/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php
@@ -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)
@@ -169,8 +168,8 @@ class TagControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->clear();
$crawler = $client->request('GET', '/tag/list');
- $link = $crawler->filter('a[id="delete-' . $tag->getSlug() . '"]')->link();
- $client->click($link);
+ $form = $crawler->filter('#tag-' . $tag->getId())->selectButton('delete')->form();
+ $client->submit($form);
$tag = $client->getContainer()
->get(EntityManagerInterface::class)
@@ -548,7 +547,7 @@ class TagControllerTest extends WallabagCoreTestCase
$crawler = $client->submit($form, $data);
- $client->click($crawler->selectLink('entry.list.assign_search_tag')->link());
+ $client->submit($crawler->selectButton('entry.list.assign_search_tag')->form());
$client->followRedirect();
$entries = $client->getContainer()