aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorJérémy Benoist <j0k3r@users.noreply.github.com>2019-04-25 13:28:09 +0200
committerGitHub <noreply@github.com>2019-04-25 13:28:09 +0200
commit522e37ad274361dde697da13a92ff3f846599822 (patch)
treea2b9302d885d886e013a6c33e800f5b39293e861 /src
parent3620dae1e6b3fab5a4ba4001b4581ce7ed795996 (diff)
parent76bc05ebc02408b213b536fec44e94b092889118 (diff)
downloadwallabag-522e37ad274361dde697da13a92ff3f846599822.tar.gz
wallabag-522e37ad274361dde697da13a92ff3f846599822.tar.zst
wallabag-522e37ad274361dde697da13a92ff3f846599822.zip
Merge pull request #3158 from wallabag/hash-exist-url
Hash exist url
Diffstat (limited to 'src')
-rw-r--r--src/Wallabag/ApiBundle/Controller/EntryRestController.php40
-rw-r--r--src/Wallabag/CoreBundle/Command/GenerateUrlHashesCommand.php98
-rw-r--r--src/Wallabag/CoreBundle/Entity/Entry.php31
-rw-r--r--src/Wallabag/CoreBundle/Repository/EntryRepository.php24
4 files changed, 181 insertions, 12 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
index 5c850091..06520af9 100644
--- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -27,8 +27,10 @@ class EntryRestController extends WallabagRestController
27 * @ApiDoc( 27 * @ApiDoc(
28 * parameters={ 28 * parameters={
29 * {"name"="return_id", "dataType"="string", "required"=false, "format"="1 or 0", "description"="Set 1 if you want to retrieve ID in case entry(ies) exists, 0 by default"}, 29 * {"name"="return_id", "dataType"="string", "required"=false, "format"="1 or 0", "description"="Set 1 if you want to retrieve ID in case entry(ies) exists, 0 by default"},
30 * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"}, 30 * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="DEPRECATED, use hashed_url instead"},
31 * {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="Urls (as an array) to check if it exists"} 31 * {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="DEPRECATED, use hashed_urls instead"},
32 * {"name"="hashed_url", "dataType"="string", "required"=false, "format"="A hashed url", "description"="Hashed url using SHA1 to check if it exists"},
33 * {"name"="hashed_urls", "dataType"="string", "required"=false, "format"="An array of hashed urls (?hashed_urls[]=xxx...&hashed_urls[]=xxx...)", "description"="An array of hashed urls using SHA1 to check if they exist"}
32 * } 34 * }
33 * ) 35 * )
34 * 36 *
@@ -37,17 +39,30 @@ class EntryRestController extends WallabagRestController
37 public function getEntriesExistsAction(Request $request) 39 public function getEntriesExistsAction(Request $request)
38 { 40 {
39 $this->validateAuthentication(); 41 $this->validateAuthentication();
42 $repo = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry');
40 43
41 $returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id'); 44 $returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id');
45
42 $urls = $request->query->get('urls', []); 46 $urls = $request->query->get('urls', []);
47 $hashedUrls = $request->query->get('hashed_urls', []);
43 48
44 // handle multiple urls first 49 // handle multiple urls first
50 if (!empty($hashedUrls)) {
51 $results = [];
52 foreach ($hashedUrls as $hashedUrl) {
53 $res = $repo->findByHashedUrlAndUserId($hashedUrl, $this->getUser()->getId());
54
55 $results[$hashedUrl] = $this->returnExistInformation($res, $returnId);
56 }
57
58 return $this->sendResponse($results);
59 }
60
61 // @deprecated, to be remove in 3.0
45 if (!empty($urls)) { 62 if (!empty($urls)) {
46 $results = []; 63 $results = [];
47 foreach ($urls as $url) { 64 foreach ($urls as $url) {
48 $res = $this->getDoctrine() 65 $res = $repo->findByUrlAndUserId($url, $this->getUser()->getId());
49 ->getRepository('WallabagCoreBundle:Entry')
50 ->findByUrlAndUserId($url, $this->getUser()->getId());
51 66
52 $results[$url] = $this->returnExistInformation($res, $returnId); 67 $results[$url] = $this->returnExistInformation($res, $returnId);
53 } 68 }
@@ -57,18 +72,21 @@ class EntryRestController extends WallabagRestController
57 72
58 // let's see if it is a simple url? 73 // let's see if it is a simple url?
59 $url = $request->query->get('url', ''); 74 $url = $request->query->get('url', '');
75 $hashedUrl = $request->query->get('hashed_url', '');
60 76
61 if (empty($url)) { 77 if (empty($url) && empty($hashedUrl)) {
62 throw $this->createAccessDeniedException('URL is empty?, logged user id: ' . $this->getUser()->getId()); 78 throw $this->createAccessDeniedException('URL is empty?, logged user id: ' . $this->getUser()->getId());
63 } 79 }
64 80
65 $res = $this->getDoctrine() 81 $method = 'findByUrlAndUserId';
66 ->getRepository('WallabagCoreBundle:Entry') 82 if (!empty($hashedUrl)) {
67 ->findByUrlAndUserId($url, $this->getUser()->getId()); 83 $method = 'findByHashedUrlAndUserId';
84 $url = $hashedUrl;
85 }
68 86
69 $exists = $this->returnExistInformation($res, $returnId); 87 $res = $repo->$method($url, $this->getUser()->getId());
70 88
71 return $this->sendResponse(['exists' => $exists]); 89 return $this->sendResponse(['exists' => $this->returnExistInformation($res, $returnId)]);
72 } 90 }
73 91
74 /** 92 /**
diff --git a/src/Wallabag/CoreBundle/Command/GenerateUrlHashesCommand.php b/src/Wallabag/CoreBundle/Command/GenerateUrlHashesCommand.php
new file mode 100644
index 00000000..45bd8c5f
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Command/GenerateUrlHashesCommand.php
@@ -0,0 +1,98 @@
1<?php
2
3namespace Wallabag\CoreBundle\Command;
4
5use Doctrine\ORM\NoResultException;
6use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
7use Symfony\Component\Console\Input\InputArgument;
8use Symfony\Component\Console\Input\InputInterface;
9use Symfony\Component\Console\Output\OutputInterface;
10use Wallabag\UserBundle\Entity\User;
11
12class GenerateUrlHashesCommand extends ContainerAwareCommand
13{
14 /** @var OutputInterface */
15 protected $output;
16
17 protected function configure()
18 {
19 $this
20 ->setName('wallabag:generate-hashed-urls')
21 ->setDescription('Generates hashed urls for each entry')
22 ->setHelp('This command helps you to generates hashes of the url of each entry, to check through API if an URL is already saved')
23 ->addArgument('username', InputArgument::OPTIONAL, 'User to process entries');
24 }
25
26 protected function execute(InputInterface $input, OutputInterface $output)
27 {
28 $this->output = $output;
29
30 $username = (string) $input->getArgument('username');
31
32 if ($username) {
33 try {
34 $user = $this->getUser($username);
35 $this->generateHashedUrls($user);
36 } catch (NoResultException $e) {
37 $output->writeln(sprintf('<error>User "%s" not found.</error>', $username));
38
39 return 1;
40 }
41 } else {
42 $users = $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findAll();
43
44 $output->writeln(sprintf('Generating hashed urls for "%d" users', \count($users)));
45
46 foreach ($users as $user) {
47 $output->writeln(sprintf('Processing user: %s', $user->getUsername()));
48 $this->generateHashedUrls($user);
49 }
50 $output->writeln('Finished generated hashed urls');
51 }
52
53 return 0;
54 }
55
56 /**
57 * @param User $user
58 */
59 private function generateHashedUrls(User $user)
60 {
61 $em = $this->getContainer()->get('doctrine.orm.entity_manager');
62 $repo = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry');
63
64 $entries = $repo->findByUser($user->getId());
65
66 $i = 1;
67 foreach ($entries as $entry) {
68 $entry->setHashedUrl(hash('sha1', $entry->getUrl()));
69 $em->persist($entry);
70
71 if (0 === ($i % 20)) {
72 $em->flush();
73 }
74 ++$i;
75 }
76
77 $em->flush();
78
79 $this->output->writeln(sprintf('Generated hashed urls for user: %s', $user->getUserName()));
80 }
81
82 /**
83 * Fetches a user from its username.
84 *
85 * @param string $username
86 *
87 * @return \Wallabag\UserBundle\Entity\User
88 */
89 private function getUser($username)
90 {
91 return $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findOneByUserName($username);
92 }
93
94 private function getDoctrine()
95 {
96 return $this->getContainer()->get('doctrine');
97 }
98}
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php
index b3cfdc4a..c3fb87d2 100644
--- a/src/Wallabag/CoreBundle/Entity/Entry.php
+++ b/src/Wallabag/CoreBundle/Entity/Entry.php
@@ -25,7 +25,8 @@ use Wallabag\UserBundle\Entity\User;
25 * options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"}, 25 * options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"},
26 * indexes={ 26 * indexes={
27 * @ORM\Index(name="created_at", columns={"created_at"}), 27 * @ORM\Index(name="created_at", columns={"created_at"}),
28 * @ORM\Index(name="uid", columns={"uid"}) 28 * @ORM\Index(name="uid", columns={"uid"}),
29 * @ORM\Index(name="hashed_url_user_id", columns={"user_id", "hashed_url"}, options={"lengths"={null, 40}})
29 * } 30 * }
30 * ) 31 * )
31 * @ORM\HasLifecycleCallbacks() 32 * @ORM\HasLifecycleCallbacks()
@@ -76,6 +77,13 @@ class Entry
76 private $url; 77 private $url;
77 78
78 /** 79 /**
80 * @var string
81 *
82 * @ORM\Column(name="hashed_url", type="string", length=40, nullable=true)
83 */
84 private $hashedUrl;
85
86 /**
79 * @var bool 87 * @var bool
80 * 88 *
81 * @Exclude 89 * @Exclude
@@ -316,6 +324,7 @@ class Entry
316 public function setUrl($url) 324 public function setUrl($url)
317 { 325 {
318 $this->url = $url; 326 $this->url = $url;
327 $this->hashedUrl = hash('sha1', $url);
319 328
320 return $this; 329 return $this;
321 } 330 }
@@ -911,4 +920,24 @@ class Entry
911 { 920 {
912 return $this->originUrl; 921 return $this->originUrl;
913 } 922 }
923
924 /**
925 * @return string
926 */
927 public function getHashedUrl()
928 {
929 return $this->hashedUrl;
930 }
931
932 /**
933 * @param mixed $hashedUrl
934 *
935 * @return Entry
936 */
937 public function setHashedUrl($hashedUrl)
938 {
939 $this->hashedUrl = $hashedUrl;
940
941 return $this;
942 }
914} 943}
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
index 45366623..f5089729 100644
--- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
@@ -347,6 +347,30 @@ class EntryRepository extends EntityRepository
347 } 347 }
348 348
349 /** 349 /**
350 * Find an entry by its hashed url and its owner.
351 * If it exists, return the entry otherwise return false.
352 *
353 * @param string $hashedUrl Url hashed using sha1
354 * @param int $userId
355 *
356 * @return Entry|bool
357 */
358 public function findByHashedUrlAndUserId($hashedUrl, $userId)
359 {
360 $res = $this->createQueryBuilder('e')
361 ->where('e.hashedUrl = :hashed_url')->setParameter('hashed_url', $hashedUrl)
362 ->andWhere('e.user = :user_id')->setParameter('user_id', $userId)
363 ->getQuery()
364 ->getResult();
365
366 if (\count($res)) {
367 return current($res);
368 }
369
370 return false;
371 }
372
373 /**
350 * Count all entries for a user. 374 * Count all entries for a user.
351 * 375 *
352 * @param int $userId 376 * @param int $userId