diff options
author | ArthurHoaro <arthur@hoa.ro> | 2020-10-16 20:17:08 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2020-10-27 19:32:57 +0100 |
commit | 9c04921a8c28c18ef757f2d43ba35e7e2a7f1a4b (patch) | |
tree | bcc2cb0dbad3ea27c38e676a20f3a377b50e9066 /application | |
parent | e6215a2ad97182efcf88ef532ec6bd65ae35fd19 (diff) | |
download | Shaarli-9c04921a8c28c18ef757f2d43ba35e7e2a7f1a4b.tar.gz Shaarli-9c04921a8c28c18ef757f2d43ba35e7e2a7f1a4b.tar.zst Shaarli-9c04921a8c28c18ef757f2d43ba35e7e2a7f1a4b.zip |
Feature: Share private bookmarks using a URL containing a private key
- Add a share link next to « Permalink » in linklist (using share icon
from fork awesome)
- This link generates a private key associated to the bookmark
- Accessing the bookmark while logged out with the proper key will
display it
Fixes #475
Diffstat (limited to 'application')
4 files changed, 37 insertions, 5 deletions
diff --git a/application/bookmark/BookmarkFileService.php b/application/bookmark/BookmarkFileService.php index eb7899bf..14b3d620 100644 --- a/application/bookmark/BookmarkFileService.php +++ b/application/bookmark/BookmarkFileService.php | |||
@@ -97,12 +97,15 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
97 | /** | 97 | /** |
98 | * @inheritDoc | 98 | * @inheritDoc |
99 | */ | 99 | */ |
100 | public function findByHash(string $hash): Bookmark | 100 | public function findByHash(string $hash, string $privateKey = null): Bookmark |
101 | { | 101 | { |
102 | $bookmark = $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_HASH, $hash); | 102 | $bookmark = $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_HASH, $hash); |
103 | // PHP 7.3 introduced array_key_first() to avoid this hack | 103 | // PHP 7.3 introduced array_key_first() to avoid this hack |
104 | $first = reset($bookmark); | 104 | $first = reset($bookmark); |
105 | if (! $this->isLoggedIn && $first->isPrivate()) { | 105 | if (!$this->isLoggedIn |
106 | && $first->isPrivate() | ||
107 | && (empty($privateKey) || $privateKey !== $first->getAdditionalContentEntry('private_key')) | ||
108 | ) { | ||
106 | throw new Exception('Not authorized'); | 109 | throw new Exception('Not authorized'); |
107 | } | 110 | } |
108 | 111 | ||
diff --git a/application/bookmark/BookmarkServiceInterface.php b/application/bookmark/BookmarkServiceInterface.php index 37a54d03..9fa61533 100644 --- a/application/bookmark/BookmarkServiceInterface.php +++ b/application/bookmark/BookmarkServiceInterface.php | |||
@@ -20,13 +20,14 @@ interface BookmarkServiceInterface | |||
20 | /** | 20 | /** |
21 | * Find a bookmark by hash | 21 | * Find a bookmark by hash |
22 | * | 22 | * |
23 | * @param string $hash | 23 | * @param string $hash Bookmark's hash |
24 | * @param string|null $privateKey Optional key used to access private links while logged out | ||
24 | * | 25 | * |
25 | * @return Bookmark | 26 | * @return Bookmark |
26 | * | 27 | * |
27 | * @throws \Exception | 28 | * @throws \Exception |
28 | */ | 29 | */ |
29 | public function findByHash(string $hash): Bookmark; | 30 | public function findByHash(string $hash, string $privateKey = null); |
30 | 31 | ||
31 | /** | 32 | /** |
32 | * @param $url | 33 | * @param $url |
diff --git a/application/front/controller/admin/ManageShaareController.php b/application/front/controller/admin/ManageShaareController.php index 908ebae3..e490f85a 100644 --- a/application/front/controller/admin/ManageShaareController.php +++ b/application/front/controller/admin/ManageShaareController.php | |||
@@ -321,6 +321,32 @@ class ManageShaareController extends ShaarliAdminController | |||
321 | } | 321 | } |
322 | 322 | ||
323 | /** | 323 | /** |
324 | * GET /admin/shaare/private/{hash} - Attach a private key to given bookmark, then redirect to the sharing URL. | ||
325 | */ | ||
326 | public function sharePrivate(Request $request, Response $response, array $args): Response | ||
327 | { | ||
328 | $this->checkToken($request); | ||
329 | |||
330 | $hash = $args['hash'] ?? ''; | ||
331 | $bookmark = $this->container->bookmarkService->findByHash($hash); | ||
332 | |||
333 | if ($bookmark->isPrivate() !== true) { | ||
334 | return $this->redirect($response, '/shaare/' . $hash); | ||
335 | } | ||
336 | |||
337 | if (empty($bookmark->getAdditionalContentEntry('private_key'))) { | ||
338 | $privateKey = bin2hex(random_bytes(16)); | ||
339 | $bookmark->addAdditionalContentEntry('private_key', $privateKey); | ||
340 | $this->container->bookmarkService->set($bookmark); | ||
341 | } | ||
342 | |||
343 | return $this->redirect( | ||
344 | $response, | ||
345 | '/shaare/' . $hash . '?key=' . $bookmark->getAdditionalContentEntry('private_key') | ||
346 | ); | ||
347 | } | ||
348 | |||
349 | /** | ||
324 | * Helper function used to display the shaare form whether it's a new or existing bookmark. | 350 | * Helper function used to display the shaare form whether it's a new or existing bookmark. |
325 | * | 351 | * |
326 | * @param array $link data used in template, either from parameters or from the data store | 352 | * @param array $link data used in template, either from parameters or from the data store |
diff --git a/application/front/controller/visitor/BookmarkListController.php b/application/front/controller/visitor/BookmarkListController.php index 5267c8f5..78c474c9 100644 --- a/application/front/controller/visitor/BookmarkListController.php +++ b/application/front/controller/visitor/BookmarkListController.php | |||
@@ -137,8 +137,10 @@ class BookmarkListController extends ShaarliVisitorController | |||
137 | */ | 137 | */ |
138 | public function permalink(Request $request, Response $response, array $args): Response | 138 | public function permalink(Request $request, Response $response, array $args): Response |
139 | { | 139 | { |
140 | $privateKey = $request->getParam('key'); | ||
141 | |||
140 | try { | 142 | try { |
141 | $bookmark = $this->container->bookmarkService->findByHash($args['hash']); | 143 | $bookmark = $this->container->bookmarkService->findByHash($args['hash'], $privateKey); |
142 | } catch (BookmarkNotFoundException $e) { | 144 | } catch (BookmarkNotFoundException $e) { |
143 | $this->assignView('error_message', $e->getMessage()); | 145 | $this->assignView('error_message', $e->getMessage()); |
144 | 146 | ||