mirror of
https://github.com/wallabag/wallabag.git
synced 2026-03-01 05:57:34 +01:00
Compare commits
7 Commits
c6996e0e7f
...
80d3dacfac
| Author | SHA1 | Date | |
|---|---|---|---|
| 80d3dacfac | |||
| 7e9e179860 | |||
| 31ba90b060 | |||
| c20f37975b | |||
| ecb8b8ff49 | |||
| 67c359a6dd | |||
| da14f0ded3 |
@ -52,7 +52,7 @@
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-webpack-plugin": "^4.2.0",
|
||||
"eslint-webpack-plugin": "^5.0.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"lato-font": "^3.0.0",
|
||||
"mini-css-extract-plugin": "^2.9.2",
|
||||
|
||||
@ -8,6 +8,7 @@ use Nelmio\ApiDocBundle\Annotation\Operation;
|
||||
use OpenApi\Annotations as OA;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@ -85,13 +86,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/exists.{_format}", name="api_get_entries_exists", methods={"GET"}, defaults={"_format": "json"})
|
||||
* @IsGranted("LIST_ENTRIES")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getEntriesExistsAction(Request $request, EntryRepository $entryRepository)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
|
||||
$returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id');
|
||||
|
||||
$hashedUrls = $request->query->all('hashed_urls');
|
||||
@ -300,13 +300,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries.{_format}", name="api_get_entries", methods={"GET"}, defaults={"_format": "json"})
|
||||
* @IsGranted("LIST_ENTRIES")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getEntriesAction(Request $request, EntryRepository $entryRepository)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
|
||||
$isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
|
||||
$isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
|
||||
$isPublic = (null === $request->query->get('public')) ? null : (bool) $request->query->get('public');
|
||||
@ -392,14 +391,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/{entry}.{_format}", name="api_get_entry", methods={"GET"}, defaults={"_format": "json"})
|
||||
* @IsGranted("VIEW", subject="entry")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getEntryAction(Entry $entry)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
$this->validateUserAccess($entry->getUser()->getId());
|
||||
|
||||
return $this->sendResponse($entry);
|
||||
}
|
||||
|
||||
@ -436,14 +433,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/{entry}/export.{_format}", name="api_get_entry_export", methods={"GET"}, defaults={"_format": "json"})
|
||||
* @IsGranted("VIEW", subject="entry")
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function getEntryExportAction(Entry $entry, Request $request, EntriesExport $entriesExport)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
$this->validateUserAccess($entry->getUser()->getId());
|
||||
|
||||
return $entriesExport
|
||||
->setEntries($entry)
|
||||
->updateTitle('entry')
|
||||
@ -471,13 +466,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/list.{_format}", name="api_delete_entries_list", methods={"DELETE"}, defaults={"_format": "json"})
|
||||
* @IsGranted("DELETE_ENTRIES")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function deleteEntriesListAction(Request $request, EntryRepository $entryRepository, EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
|
||||
$urls = json_decode($request->query->get('urls', '[]'));
|
||||
|
||||
if (empty($urls)) {
|
||||
@ -495,7 +489,7 @@ class EntryRestController extends WallabagRestController
|
||||
|
||||
$results[$key]['url'] = $url;
|
||||
|
||||
if (false !== $entry) {
|
||||
if (false !== $entry && $this->authorizationChecker->isGranted('DELETE', $entry)) {
|
||||
// entry deleted, dispatch event about it!
|
||||
$eventDispatcher->dispatch(new EntryDeletedEvent($entry), EntryDeletedEvent::NAME);
|
||||
|
||||
@ -529,6 +523,7 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/lists.{_format}", name="api_post_entries_list", methods={"POST"}, defaults={"_format": "json"})
|
||||
* @IsGranted("CREATE_ENTRIES")
|
||||
*
|
||||
* @throws HttpException When limit is reached
|
||||
*
|
||||
@ -536,8 +531,6 @@ class EntryRestController extends WallabagRestController
|
||||
*/
|
||||
public function postEntriesListAction(Request $request, EntryRepository $entryRepository, EventDispatcherInterface $eventDispatcher, ContentProxy $contentProxy)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
|
||||
$urls = json_decode($request->query->get('urls', '[]'));
|
||||
|
||||
$limit = $this->getParameter('wallabag.api_limit_mass_actions');
|
||||
@ -714,6 +707,7 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries.{_format}", name="api_post_entries", methods={"POST"}, defaults={"_format": "json"})
|
||||
* @IsGranted("CREATE_ENTRIES")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
@ -726,8 +720,6 @@ class EntryRestController extends WallabagRestController
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
ValidatorInterface $validator,
|
||||
) {
|
||||
$this->validateAuthentication();
|
||||
|
||||
$url = $request->request->get('url');
|
||||
|
||||
$entry = $entryRepository->findByUrlAndUserId(
|
||||
@ -939,14 +931,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/{entry}.{_format}", name="api_patch_entries", methods={"PATCH"}, defaults={"_format": "json"})
|
||||
* @IsGranted("EDIT", subject="entry")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function patchEntriesAction(Entry $entry, Request $request, ContentProxy $contentProxy, LoggerInterface $logger, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
$this->validateUserAccess($entry->getUser()->getId());
|
||||
|
||||
$data = $this->retrieveValueFromRequest($request);
|
||||
|
||||
// this is a special case where user want to manually update the entry content
|
||||
@ -1056,14 +1046,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/{entry}/reload.{_format}", name="api_patch_entries_reload", methods={"PATCH"}, defaults={"_format": "json"})
|
||||
* @IsGranted("RELOAD", subject="entry")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function patchEntriesReloadAction(Entry $entry, ContentProxy $contentProxy, LoggerInterface $logger, EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
$this->validateUserAccess($entry->getUser()->getId());
|
||||
|
||||
try {
|
||||
$contentProxy->updateEntry($entry, $entry->getUrl());
|
||||
} catch (\Exception $e) {
|
||||
@ -1113,6 +1101,7 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/{entry}.{_format}", name="api_delete_entries", methods={"DELETE"}, defaults={"_format": "json"})
|
||||
* @IsGranted("DELETE", subject="entry")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
@ -1122,8 +1111,6 @@ class EntryRestController extends WallabagRestController
|
||||
if (!\in_array($expect, ['id', 'entry'], true)) {
|
||||
throw new BadRequestHttpException(\sprintf("expect: 'id' or 'entry' expected, %s given", $expect));
|
||||
}
|
||||
$this->validateAuthentication();
|
||||
$this->validateUserAccess($entry->getUser()->getId());
|
||||
|
||||
$response = $this->sendResponse([
|
||||
'id' => $entry->getId(),
|
||||
@ -1166,14 +1153,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/{entry}/tags.{_format}", name="api_get_entries_tags", methods={"GET"}, defaults={"_format": "json"})
|
||||
* @IsGranted("LIST_TAGS", subject="entry")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getEntriesTagsAction(Entry $entry)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
$this->validateUserAccess($entry->getUser()->getId());
|
||||
|
||||
return $this->sendResponse($entry->getTags());
|
||||
}
|
||||
|
||||
@ -1210,14 +1195,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/{entry}/tags.{_format}", name="api_post_entries_tags", methods={"POST"}, defaults={"_format": "json"})
|
||||
* @IsGranted("TAG", subject="entry")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function postEntriesTagsAction(Request $request, Entry $entry, TagsAssigner $tagsAssigner)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
$this->validateUserAccess($entry->getUser()->getId());
|
||||
|
||||
$tags = $request->request->get('tags', '');
|
||||
if (!empty($tags)) {
|
||||
$tagsAssigner->assignTagsToEntry($entry, $tags);
|
||||
@ -1262,14 +1245,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/{entry}/tags/{tag}.{_format}", name="api_delete_entries_tags", methods={"DELETE"}, defaults={"_format": "json"})
|
||||
* @IsGranted("UNTAG", subject="entry")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
$this->validateUserAccess($entry->getUser()->getId());
|
||||
|
||||
$entry->removeTag($tag);
|
||||
|
||||
$this->entityManager->persist($entry);
|
||||
@ -1298,13 +1279,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/tags/list.{_format}", name="api_delete_entries_tags_list", methods={"DELETE"}, defaults={"_format": "json"})
|
||||
* @IsGranted("DELETE_TAGS")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function deleteEntriesTagsListAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
|
||||
$list = json_decode($request->query->get('list', '[]'));
|
||||
|
||||
if (empty($list)) {
|
||||
@ -1325,7 +1305,7 @@ class EntryRestController extends WallabagRestController
|
||||
|
||||
$tags = $element->tags;
|
||||
|
||||
if (false !== $entry && !(empty($tags))) {
|
||||
if (false !== $entry && !(empty($tags)) && $this->authorizationChecker->isGranted('UNTAG', $entry)) {
|
||||
$tags = explode(',', $tags);
|
||||
foreach ($tags as $label) {
|
||||
$label = trim($label);
|
||||
@ -1365,13 +1345,12 @@ class EntryRestController extends WallabagRestController
|
||||
* )
|
||||
*
|
||||
* @Route("/api/entries/tags/lists.{_format}", name="api_post_entries_tags_list", methods={"POST"}, defaults={"_format": "json"})
|
||||
* @IsGranted("CREATE_TAGS")
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function postEntriesTagsListAction(Request $request, EntryRepository $entryRepository, TagsAssigner $tagsAssigner)
|
||||
{
|
||||
$this->validateAuthentication();
|
||||
|
||||
$list = json_decode($request->query->get('list', '[]'));
|
||||
|
||||
if (empty($list)) {
|
||||
@ -1392,7 +1371,7 @@ class EntryRestController extends WallabagRestController
|
||||
|
||||
$tags = $element->tags;
|
||||
|
||||
if (false !== $entry && !(empty($tags))) {
|
||||
if (false !== $entry && !(empty($tags)) && $this->authorizationChecker->isGranted('TAG', $entry)) {
|
||||
$tagsAssigner->assignTagsToEntry($entry, $tags);
|
||||
|
||||
$this->entityManager->persist($entry);
|
||||
|
||||
@ -101,22 +101,6 @@ class WallabagRestController extends AbstractFOSRestController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the first id is equal to the second one.
|
||||
* If not, throw exception. It means a user try to access information from an other user.
|
||||
*
|
||||
* @param int $requestUserId User id from the requested source
|
||||
*/
|
||||
protected function validateUserAccess($requestUserId)
|
||||
{
|
||||
$user = $this->tokenStorage->getToken()->getUser();
|
||||
\assert($user instanceof User);
|
||||
|
||||
if ($requestUserId !== $user->getId()) {
|
||||
throw $this->createAccessDeniedException('Access forbidden. Entry user id: ' . $requestUserId . ', logged user id: ' . $user->getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to send data serialized in json.
|
||||
*
|
||||
|
||||
@ -17,8 +17,6 @@ use Wallabag\Repository\IgnoreOriginInstanceRuleRepository;
|
||||
|
||||
/**
|
||||
* IgnoreOriginInstanceRuleController controller.
|
||||
*
|
||||
* @Route("/ignore-origin-instance-rules")
|
||||
*/
|
||||
class IgnoreOriginInstanceRuleController extends AbstractController
|
||||
{
|
||||
@ -34,7 +32,7 @@ class IgnoreOriginInstanceRuleController extends AbstractController
|
||||
/**
|
||||
* Lists all IgnoreOriginInstanceRule entities.
|
||||
*
|
||||
* @Route("/", name="ignore_origin_instance_rules_index", methods={"GET"})
|
||||
* @Route("/ignore-origin-instance-rules", name="ignore_origin_instance_rules_index", methods={"GET"})
|
||||
* @IsGranted("LIST_IGNORE_ORIGIN_INSTANCE_RULES")
|
||||
*/
|
||||
public function indexAction(IgnoreOriginInstanceRuleRepository $repository)
|
||||
@ -49,7 +47,7 @@ class IgnoreOriginInstanceRuleController extends AbstractController
|
||||
/**
|
||||
* Creates a new ignore origin instance rule entity.
|
||||
*
|
||||
* @Route("/new", name="ignore_origin_instance_rules_new", methods={"GET", "POST"})
|
||||
* @Route("/ignore-origin-instance-rules/new", name="ignore_origin_instance_rules_new", methods={"GET", "POST"})
|
||||
* @IsGranted("CREATE_IGNORE_ORIGIN_INSTANCE_RULES")
|
||||
*
|
||||
* @return Response
|
||||
@ -82,7 +80,7 @@ class IgnoreOriginInstanceRuleController extends AbstractController
|
||||
/**
|
||||
* Displays a form to edit an existing ignore origin instance rule entity.
|
||||
*
|
||||
* @Route("/{id}/edit", name="ignore_origin_instance_rules_edit", methods={"GET", "POST"})
|
||||
* @Route("/ignore-origin-instance-rules/{id}/edit", name="ignore_origin_instance_rules_edit", methods={"GET", "POST"})
|
||||
* @IsGranted("EDIT", subject="ignoreOriginInstanceRule")
|
||||
*
|
||||
* @return Response
|
||||
@ -115,7 +113,7 @@ class IgnoreOriginInstanceRuleController extends AbstractController
|
||||
/**
|
||||
* Deletes a site credential entity.
|
||||
*
|
||||
* @Route("/{id}", name="ignore_origin_instance_rules_delete", methods={"DELETE"})
|
||||
* @Route("/ignore-origin-instance-rules/{id}", name="ignore_origin_instance_rules_delete", methods={"DELETE"})
|
||||
* @IsGranted("DELETE", subject="ignoreOriginInstanceRule")
|
||||
*
|
||||
* @return RedirectResponse
|
||||
|
||||
@ -20,8 +20,6 @@ use Wallabag\Repository\SiteCredentialRepository;
|
||||
|
||||
/**
|
||||
* SiteCredential controller.
|
||||
*
|
||||
* @Route("/site-credentials")
|
||||
*/
|
||||
class SiteCredentialController extends AbstractController
|
||||
{
|
||||
@ -41,7 +39,7 @@ class SiteCredentialController extends AbstractController
|
||||
/**
|
||||
* Lists all User entities.
|
||||
*
|
||||
* @Route("/", name="site_credentials_index", methods={"GET"})
|
||||
* @Route("/site-credentials", name="site_credentials_index", methods={"GET"})
|
||||
* @IsGranted("LIST_SITE_CREDENTIALS")
|
||||
*/
|
||||
public function indexAction(SiteCredentialRepository $repository)
|
||||
@ -58,7 +56,7 @@ class SiteCredentialController extends AbstractController
|
||||
/**
|
||||
* Creates a new site credential entity.
|
||||
*
|
||||
* @Route("/new", name="site_credentials_new", methods={"GET", "POST"})
|
||||
* @Route("/site-credentials/new", name="site_credentials_new", methods={"GET", "POST"})
|
||||
* @IsGranted("CREATE_SITE_CREDENTIALS")
|
||||
*
|
||||
* @return Response
|
||||
@ -96,7 +94,7 @@ class SiteCredentialController extends AbstractController
|
||||
/**
|
||||
* Displays a form to edit an existing site credential entity.
|
||||
*
|
||||
* @Route("/{id}/edit", name="site_credentials_edit", methods={"GET", "POST"})
|
||||
* @Route("/site-credentials/{id}/edit", name="site_credentials_edit", methods={"GET", "POST"})
|
||||
* @IsGranted("EDIT", subject="siteCredential")
|
||||
*
|
||||
* @return Response
|
||||
@ -134,7 +132,7 @@ class SiteCredentialController extends AbstractController
|
||||
/**
|
||||
* Deletes a site credential entity.
|
||||
*
|
||||
* @Route("/{id}", name="site_credentials_delete", methods={"DELETE"})
|
||||
* @Route("/site-credentials/{id}", name="site_credentials_delete", methods={"DELETE"})
|
||||
* @IsGranted("DELETE", subject="siteCredential")
|
||||
*
|
||||
* @return RedirectResponse
|
||||
|
||||
@ -20,6 +20,7 @@ class EntryVoter extends Voter
|
||||
public const DELETE = 'DELETE';
|
||||
public const LIST_ANNOTATIONS = 'LIST_ANNOTATIONS';
|
||||
public const CREATE_ANNOTATIONS = 'CREATE_ANNOTATIONS';
|
||||
public const LIST_TAGS = 'LIST_TAGS';
|
||||
public const TAG = 'TAG';
|
||||
public const UNTAG = 'UNTAG';
|
||||
|
||||
@ -29,7 +30,7 @@ class EntryVoter extends Voter
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!\in_array($attribute, [self::VIEW, self::EDIT, self::RELOAD, self::STAR, self::ARCHIVE, self::SHARE, self::UNSHARE, self::EXPORT, self::DELETE, self::LIST_ANNOTATIONS, self::CREATE_ANNOTATIONS, self::TAG, self::UNTAG], true)) {
|
||||
if (!\in_array($attribute, [self::VIEW, self::EDIT, self::RELOAD, self::STAR, self::ARCHIVE, self::SHARE, self::UNSHARE, self::EXPORT, self::DELETE, self::LIST_ANNOTATIONS, self::CREATE_ANNOTATIONS, self::LIST_TAGS, self::TAG, self::UNTAG], true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -58,6 +59,7 @@ class EntryVoter extends Voter
|
||||
case self::DELETE:
|
||||
case self::LIST_ANNOTATIONS:
|
||||
case self::CREATE_ANNOTATIONS:
|
||||
case self::LIST_TAGS:
|
||||
case self::TAG:
|
||||
case self::UNTAG:
|
||||
return $user === $subject->getUser();
|
||||
|
||||
@ -13,8 +13,10 @@ class MainVoter extends Voter
|
||||
public const EDIT_ENTRIES = 'EDIT_ENTRIES';
|
||||
public const EXPORT_ENTRIES = 'EXPORT_ENTRIES';
|
||||
public const IMPORT_ENTRIES = 'IMPORT_ENTRIES';
|
||||
public const DELETE_ENTRIES = 'DELETE_ENTRIES';
|
||||
public const LIST_TAGS = 'LIST_TAGS';
|
||||
public const CREATE_TAGS = 'CREATE_TAGS';
|
||||
public const DELETE_TAGS = 'DELETE_TAGS';
|
||||
public const LIST_SITE_CREDENTIALS = 'LIST_SITE_CREDENTIALS';
|
||||
public const CREATE_SITE_CREDENTIALS = 'CREATE_SITE_CREDENTIALS';
|
||||
public const EDIT_CONFIG = 'EDIT_CONFIG';
|
||||
@ -32,7 +34,7 @@ class MainVoter extends Voter
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!\in_array($attribute, [self::LIST_ENTRIES, self::CREATE_ENTRIES, self::EDIT_ENTRIES, self::EXPORT_ENTRIES, self::IMPORT_ENTRIES, self::LIST_TAGS, self::CREATE_TAGS, self::LIST_SITE_CREDENTIALS, self::CREATE_SITE_CREDENTIALS, self::EDIT_CONFIG], true)) {
|
||||
if (!\in_array($attribute, [self::LIST_ENTRIES, self::CREATE_ENTRIES, self::EDIT_ENTRIES, self::EXPORT_ENTRIES, self::IMPORT_ENTRIES, self::DELETE_ENTRIES, self::LIST_TAGS, self::CREATE_TAGS, self::DELETE_TAGS, self::LIST_SITE_CREDENTIALS, self::CREATE_SITE_CREDENTIALS, self::EDIT_CONFIG], true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -47,8 +49,10 @@ class MainVoter extends Voter
|
||||
case self::EDIT_ENTRIES:
|
||||
case self::EXPORT_ENTRIES:
|
||||
case self::IMPORT_ENTRIES:
|
||||
case self::DELETE_ENTRIES:
|
||||
case self::LIST_TAGS:
|
||||
case self::CREATE_TAGS:
|
||||
case self::DELETE_TAGS:
|
||||
case self::LIST_SITE_CREDENTIALS:
|
||||
case self::CREATE_SITE_CREDENTIALS:
|
||||
case self::EDIT_CONFIG:
|
||||
|
||||
@ -6,7 +6,6 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Wallabag\Entity\Entry;
|
||||
use Wallabag\Entity\Tag;
|
||||
use Wallabag\Entity\User;
|
||||
use Wallabag\Helper\ContentProxy;
|
||||
|
||||
class EntryRestControllerTest extends WallabagApiTestCase
|
||||
@ -535,13 +534,13 @@ class EntryRestControllerTest extends WallabagApiTestCase
|
||||
public function testDeleteEntry()
|
||||
{
|
||||
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
|
||||
$entry = new Entry($em->getReference(User::class, 1));
|
||||
$entry = new Entry($this->user);
|
||||
$entry->setUrl('http://0.0.0.0/test-delete-entry');
|
||||
$entry->setTitle('Test delete entry');
|
||||
$em->persist($entry);
|
||||
$em->flush();
|
||||
|
||||
$em->clear();
|
||||
$this->client = $this->createAuthorizedClient();
|
||||
|
||||
$e = [
|
||||
'title' => $entry->getTitle(),
|
||||
@ -569,12 +568,12 @@ class EntryRestControllerTest extends WallabagApiTestCase
|
||||
public function testDeleteEntryExpectId()
|
||||
{
|
||||
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
|
||||
$entry = new Entry($em->getReference(User::class, 1));
|
||||
$entry = new Entry($this->user);
|
||||
$entry->setUrl('http://0.0.0.0/test-delete-entry-id');
|
||||
$em->persist($entry);
|
||||
$em->flush();
|
||||
|
||||
$em->clear();
|
||||
$this->client = $this->createAuthorizedClient();
|
||||
|
||||
$id = $entry->getId();
|
||||
|
||||
@ -659,14 +658,15 @@ class EntryRestControllerTest extends WallabagApiTestCase
|
||||
public function testPostSameEntry()
|
||||
{
|
||||
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
|
||||
$entry = new Entry($em->getReference(User::class, $this->getUserId()));
|
||||
$entry = new Entry($this->user);
|
||||
$entry->setUrl('https://www.20minutes.fr/sport/jo_2024/4095122-20240712-jo-paris-2024-saut-ange-bombe-comment-anne-hidalgo-va-plonger-seine-si-fait-vraiment');
|
||||
$entry->setArchived(true);
|
||||
$entry->addTag((new Tag())->setLabel('google'));
|
||||
$entry->addTag((new Tag())->setLabel('apple'));
|
||||
$em->persist($entry);
|
||||
$em->flush();
|
||||
$em->clear();
|
||||
|
||||
$this->client = $this->createAuthorizedClient();
|
||||
|
||||
$this->client->request('POST', '/api/entries.json', [
|
||||
'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',
|
||||
@ -1354,14 +1354,14 @@ class EntryRestControllerTest extends WallabagApiTestCase
|
||||
public function testDeleteEntriesTagsListAction()
|
||||
{
|
||||
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
|
||||
$entry = new Entry($em->getReference(User::class, $this->getUserId()));
|
||||
$entry = new Entry($this->user);
|
||||
$entry->setUrl('http://0.0.0.0/test-entry');
|
||||
$entry->addTag((new Tag())->setLabel('foo-tag'));
|
||||
$entry->addTag((new Tag())->setLabel('bar-tag'));
|
||||
$em->persist($entry);
|
||||
$em->flush();
|
||||
|
||||
$em->clear();
|
||||
$this->client = $this->createAuthorizedClient();
|
||||
|
||||
$list = [
|
||||
[
|
||||
@ -1422,10 +1422,12 @@ class EntryRestControllerTest extends WallabagApiTestCase
|
||||
public function testDeleteEntriesListAction()
|
||||
{
|
||||
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
|
||||
$em->persist((new Entry($em->getReference(User::class, $this->getUserId())))->setUrl('http://0.0.0.0/test-entry1'));
|
||||
$em->persist((new Entry($this->user))->setUrl('http://0.0.0.0/test-entry1'));
|
||||
|
||||
$em->flush();
|
||||
$em->clear();
|
||||
|
||||
$this->client = $this->createAuthorizedClient();
|
||||
|
||||
$list = [
|
||||
'http://0.0.0.0/test-entry1',
|
||||
'http://0.0.0.0/test-entry-not-exist',
|
||||
@ -1480,14 +1482,15 @@ class EntryRestControllerTest extends WallabagApiTestCase
|
||||
public function testRePostEntryAndReUsePublishedAt()
|
||||
{
|
||||
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
|
||||
$entry = new Entry($em->getReference(User::class, $this->getUserId()));
|
||||
$entry = new Entry($this->user);
|
||||
$entry->setTitle('Antoine de Caunes : « Je veux avoir le droit de tâtonner »');
|
||||
$entry->setContent('hihi');
|
||||
$entry->setUrl('https://www.lemonde.fr/m-perso/article/2017/06/25/antoine-de-caunes-je-veux-avoir-le-droit-de-tatonner_5150728_4497916.html');
|
||||
$entry->setPublishedAt(new \DateTime('2017-06-26T07:46:02+0200'));
|
||||
$em->persist($entry);
|
||||
$em->flush();
|
||||
$em->clear();
|
||||
|
||||
$this->client = $this->createAuthorizedClient();
|
||||
|
||||
$this->client->request('POST', '/api/entries.json', [
|
||||
'url' => 'https://www.lemonde.fr/m-perso/article/2017/06/25/antoine-de-caunes-je-veux-avoir-le-droit-de-tatonner_5150728_4497916.html',
|
||||
|
||||
@ -49,7 +49,8 @@ class TagRestControllerTest extends WallabagApiTestCase
|
||||
|
||||
$em->persist($entry);
|
||||
$em->flush();
|
||||
$em->clear();
|
||||
|
||||
$this->client = $this->createAuthorizedClient();
|
||||
|
||||
$this->client->request('DELETE', '/api/tags/' . $tag->getId() . '.json');
|
||||
|
||||
|
||||
@ -80,7 +80,8 @@ class ConfigControllerTest extends WallabagTestCase
|
||||
$this->getEntityManager()->persist($entry);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/unread/list');
|
||||
$form = $crawler->filter('button[id=submit-filter]')->form();
|
||||
|
||||
@ -538,7 +538,8 @@ class EntryControllerTest extends WallabagTestCase
|
||||
$entry->setContent('');
|
||||
$this->getEntityManager()->persist($entry);
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$client->request('GET', '/reload/' . $entry->getId());
|
||||
|
||||
@ -670,7 +671,8 @@ class EntryControllerTest extends WallabagTestCase
|
||||
$entry->setUrl($this->url);
|
||||
$this->getEntityManager()->persist($entry);
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$client->request('GET', '/archive/' . $entry->getId());
|
||||
|
||||
@ -693,7 +695,8 @@ class EntryControllerTest extends WallabagTestCase
|
||||
$entry->setUrl($this->url);
|
||||
$this->getEntityManager()->persist($entry);
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$client->request('GET', '/star/' . $entry->getId());
|
||||
|
||||
@ -1200,7 +1203,8 @@ class EntryControllerTest extends WallabagTestCase
|
||||
$content->setUrl($this->url);
|
||||
$this->getEntityManager()->persist($content);
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
// no uid
|
||||
$client->request('GET', '/share/' . $content->getUid());
|
||||
@ -1791,7 +1795,8 @@ class EntryControllerTest extends WallabagTestCase
|
||||
$this->getEntityManager()->persist($entry3);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$entries = [];
|
||||
$entries[] = $entry1->getId();
|
||||
|
||||
@ -11,7 +11,7 @@ class IgnoreOriginInstanceRuleControllerTest extends WallabagTestCase
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/ignore-origin-instance-rules/');
|
||||
$crawler = $client->request('GET', '/ignore-origin-instance-rules');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ class SiteCredentialControllerTest extends WallabagTestCase
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('restricted_access', 0);
|
||||
|
||||
$client->request('GET', '/site-credentials/');
|
||||
$client->request('GET', '/site-credentials');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
@ -29,7 +29,7 @@ class SiteCredentialControllerTest extends WallabagTestCase
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/site-credentials/');
|
||||
$crawler = $client->request('GET', '/site-credentials');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
|
||||
@ -35,7 +35,8 @@ class TagControllerTest extends WallabagTestCase
|
||||
$entry->setUrl('http://0.0.0.0/foo');
|
||||
$this->getEntityManager()->persist($entry);
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/view/' . $entry->getId());
|
||||
|
||||
@ -120,7 +121,8 @@ class TagControllerTest extends WallabagTestCase
|
||||
$entry->addTag($tag);
|
||||
$this->getEntityManager()->persist($entry);
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
// We make a first request to set an history and test redirection after tag deletion
|
||||
$crawler = $client->request('GET', '/view/' . $entry->getId());
|
||||
@ -166,7 +168,8 @@ class TagControllerTest extends WallabagTestCase
|
||||
$entry2->addTag($tag);
|
||||
$this->getEntityManager()->persist($entry2);
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/tag/list');
|
||||
$link = $crawler->filter('a[id="delete-' . $tag->getSlug() . '"]')->link();
|
||||
@ -254,7 +257,8 @@ class TagControllerTest extends WallabagTestCase
|
||||
$this->getEntityManager()->persist($entry2);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
// We make a first request to set an history and test redirection after tag deletion
|
||||
$crawler = $client->request('GET', '/tag/list');
|
||||
@ -321,7 +325,8 @@ class TagControllerTest extends WallabagTestCase
|
||||
$this->getEntityManager()->persist($entry);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
// We make a first request to set an history and test redirection after tag deletion
|
||||
$crawler = $client->request('GET', '/tag/list');
|
||||
@ -376,7 +381,8 @@ class TagControllerTest extends WallabagTestCase
|
||||
$this->getEntityManager()->persist($entry);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
// We make a first request to set an history and test redirection after tag deletion
|
||||
$crawler = $client->request('GET', '/tag/list');
|
||||
@ -446,7 +452,8 @@ class TagControllerTest extends WallabagTestCase
|
||||
$this->getEntityManager()->persist($entry2);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
// We make a first request to set an history and test redirection after tag deletion
|
||||
$crawler = $client->request('GET', '/tag/list');
|
||||
@ -496,7 +503,8 @@ class TagControllerTest extends WallabagTestCase
|
||||
$entry->setUrl('http://0.0.0.0/tag-caché');
|
||||
$this->getEntityManager()->persist($entry);
|
||||
$this->getEntityManager()->flush();
|
||||
$this->getEntityManager()->clear();
|
||||
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/view/' . $entry->getId());
|
||||
|
||||
|
||||
@ -189,6 +189,20 @@ class EntryVoterTest extends TestCase
|
||||
$this->assertSame(VoterInterface::ACCESS_GRANTED, $this->entryVoter->vote($this->token, $this->entry, [EntryVoter::CREATE_ANNOTATIONS]));
|
||||
}
|
||||
|
||||
public function testVoteReturnsDeniedForNonEntryUserListTags(): void
|
||||
{
|
||||
$this->token->method('getUser')->willReturn(new User());
|
||||
|
||||
$this->assertSame(VoterInterface::ACCESS_DENIED, $this->entryVoter->vote($this->token, $this->entry, [EntryVoter::LIST_TAGS]));
|
||||
}
|
||||
|
||||
public function testVoteReturnsGrantedForEntryUserListTags(): void
|
||||
{
|
||||
$this->token->method('getUser')->willReturn($this->user);
|
||||
|
||||
$this->assertSame(VoterInterface::ACCESS_GRANTED, $this->entryVoter->vote($this->token, $this->entry, [EntryVoter::LIST_TAGS]));
|
||||
}
|
||||
|
||||
public function testVoteReturnsDeniedForNonEntryUserTag(): void
|
||||
{
|
||||
$this->token->method('getUser')->willReturn(new User());
|
||||
|
||||
@ -112,6 +112,20 @@ class MainVoterTest extends TestCase
|
||||
$this->assertSame(VoterInterface::ACCESS_GRANTED, $this->mainVoter->vote($this->token, null, [MainVoter::IMPORT_ENTRIES]));
|
||||
}
|
||||
|
||||
public function testVoteReturnsDeniedForNonUserDeleteEntries(): void
|
||||
{
|
||||
$this->security->method('isGranted')->with('ROLE_USER')->willReturn(false);
|
||||
|
||||
$this->assertSame(VoterInterface::ACCESS_DENIED, $this->mainVoter->vote($this->token, null, [MainVoter::DELETE_ENTRIES]));
|
||||
}
|
||||
|
||||
public function testVoteReturnsGrantedForUserDeleteEntries(): void
|
||||
{
|
||||
$this->security->method('isGranted')->with('ROLE_USER')->willReturn(true);
|
||||
|
||||
$this->assertSame(VoterInterface::ACCESS_GRANTED, $this->mainVoter->vote($this->token, null, [MainVoter::DELETE_ENTRIES]));
|
||||
}
|
||||
|
||||
public function testVoteReturnsDeniedForNonUserListTags(): void
|
||||
{
|
||||
$this->security->method('isGranted')->with('ROLE_USER')->willReturn(false);
|
||||
@ -140,6 +154,20 @@ class MainVoterTest extends TestCase
|
||||
$this->assertSame(VoterInterface::ACCESS_GRANTED, $this->mainVoter->vote($this->token, null, [MainVoter::CREATE_TAGS]));
|
||||
}
|
||||
|
||||
public function testVoteReturnsDeniedForNonUserDeleteTags(): void
|
||||
{
|
||||
$this->security->method('isGranted')->with('ROLE_USER')->willReturn(false);
|
||||
|
||||
$this->assertSame(VoterInterface::ACCESS_DENIED, $this->mainVoter->vote($this->token, null, [MainVoter::DELETE_TAGS]));
|
||||
}
|
||||
|
||||
public function testVoteReturnsGrantedForUserDeleteTags(): void
|
||||
{
|
||||
$this->security->method('isGranted')->with('ROLE_USER')->willReturn(true);
|
||||
|
||||
$this->assertSame(VoterInterface::ACCESS_GRANTED, $this->mainVoter->vote($this->token, null, [MainVoter::DELETE_TAGS]));
|
||||
}
|
||||
|
||||
public function testVoteReturnsDeniedForNonUserListSiteCredentials(): void
|
||||
{
|
||||
$this->security->method('isGranted')->with('ROLE_USER')->willReturn(false);
|
||||
|
||||
26
yarn.lock
26
yarn.lock
@ -1090,7 +1090,7 @@
|
||||
"@types/eslint" "*"
|
||||
"@types/estree" "*"
|
||||
|
||||
"@types/eslint@*":
|
||||
"@types/eslint@*", "@types/eslint@^9.6.1":
|
||||
version "9.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584"
|
||||
integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==
|
||||
@ -1098,14 +1098,6 @@
|
||||
"@types/estree" "*"
|
||||
"@types/json-schema" "*"
|
||||
|
||||
"@types/eslint@^8.56.10":
|
||||
version "8.56.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.10.tgz#eb2370a73bf04a901eeba8f22595c7ee0f7eb58d"
|
||||
integrity sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==
|
||||
dependencies:
|
||||
"@types/estree" "*"
|
||||
"@types/json-schema" "*"
|
||||
|
||||
"@types/estree@*", "@types/estree@^1.0.6":
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
|
||||
@ -2510,16 +2502,16 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
|
||||
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
|
||||
|
||||
eslint-webpack-plugin@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-4.2.0.tgz#41f54b25379908eb9eca8645bc997c90cfdbd34e"
|
||||
integrity sha512-rsfpFQ01AWQbqtjgPRr2usVRxhWDuG0YDYcG8DJOteD3EFnpeuYuOwk0PQiN7PRBTqS6ElNdtPZPggj8If9WnA==
|
||||
eslint-webpack-plugin@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-5.0.0.tgz#f131f066efeae9ebf738901869f0034764e71bb4"
|
||||
integrity sha512-iDhXf2r55KO1UhMfpus8oGp93wdNF+934q5kEkwa7qn3BH9f51QEC11xQidt+8jfqRnEYYZa2/8lhac7U/vqWw==
|
||||
dependencies:
|
||||
"@types/eslint" "^8.56.10"
|
||||
"@types/eslint" "^9.6.1"
|
||||
jest-worker "^29.7.0"
|
||||
micromatch "^4.0.5"
|
||||
micromatch "^4.0.8"
|
||||
normalize-path "^3.0.0"
|
||||
schema-utils "^4.2.0"
|
||||
schema-utils "^4.3.0"
|
||||
|
||||
eslint@^8.57.1:
|
||||
version "8.57.1"
|
||||
@ -3617,7 +3609,7 @@ merge2@^1.3.0, merge2@^1.4.1:
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
micromatch@^4.0.4, micromatch@^4.0.5:
|
||||
micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
|
||||
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
|
||||
|
||||
Reference in New Issue
Block a user