diff options
-rw-r--r-- | application/bookmark/BookmarkFileService.php | 36 | ||||
-rw-r--r-- | application/bookmark/BookmarkIO.php | 8 | ||||
-rw-r--r-- | application/bookmark/BookmarkInitializer.php | 9 | ||||
-rw-r--r-- | application/bookmark/BookmarkServiceInterface.php | 14 | ||||
-rw-r--r-- | application/bookmark/exception/DatastoreNotInitializedException.php | 10 | ||||
-rw-r--r-- | application/front/controller/visitor/InstallController.php | 5 | ||||
-rw-r--r-- | tests/bookmark/BookmarkInitializerTest.php | 14 | ||||
-rw-r--r-- | tests/front/controller/visitor/InstallControllerTest.php | 3 |
8 files changed, 42 insertions, 57 deletions
diff --git a/application/bookmark/BookmarkFileService.php b/application/bookmark/BookmarkFileService.php index 6e04f3b7..b3a90ed4 100644 --- a/application/bookmark/BookmarkFileService.php +++ b/application/bookmark/BookmarkFileService.php | |||
@@ -6,6 +6,7 @@ namespace Shaarli\Bookmark; | |||
6 | 6 | ||
7 | use Exception; | 7 | use Exception; |
8 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; | 8 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; |
9 | use Shaarli\Bookmark\Exception\DatastoreNotInitializedException; | ||
9 | use Shaarli\Bookmark\Exception\EmptyDataStoreException; | 10 | use Shaarli\Bookmark\Exception\EmptyDataStoreException; |
10 | use Shaarli\Config\ConfigManager; | 11 | use Shaarli\Config\ConfigManager; |
11 | use Shaarli\Formatter\BookmarkMarkdownFormatter; | 12 | use Shaarli\Formatter\BookmarkMarkdownFormatter; |
@@ -46,9 +47,6 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
46 | /** @var bool true for logged in users. Default value to retrieve private bookmarks. */ | 47 | /** @var bool true for logged in users. Default value to retrieve private bookmarks. */ |
47 | protected $isLoggedIn; | 48 | protected $isLoggedIn; |
48 | 49 | ||
49 | /** @var bool Allow datastore alteration from not logged in users. */ | ||
50 | protected $anonymousPermission = false; | ||
51 | |||
52 | /** | 50 | /** |
53 | * @inheritDoc | 51 | * @inheritDoc |
54 | */ | 52 | */ |
@@ -65,10 +63,16 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
65 | } else { | 63 | } else { |
66 | try { | 64 | try { |
67 | $this->bookmarks = $this->bookmarksIO->read(); | 65 | $this->bookmarks = $this->bookmarksIO->read(); |
68 | } catch (EmptyDataStoreException $e) { | 66 | } catch (EmptyDataStoreException|DatastoreNotInitializedException $e) { |
69 | $this->bookmarks = new BookmarkArray(); | 67 | $this->bookmarks = new BookmarkArray(); |
68 | |||
70 | if ($this->isLoggedIn) { | 69 | if ($this->isLoggedIn) { |
71 | $this->save(); | 70 | // Datastore file does not exists, we initialize it with default bookmarks. |
71 | if ($e instanceof DatastoreNotInitializedException) { | ||
72 | $this->initialize(); | ||
73 | } else { | ||
74 | $this->save(); | ||
75 | } | ||
72 | } | 76 | } |
73 | } | 77 | } |
74 | 78 | ||
@@ -157,7 +161,7 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
157 | */ | 161 | */ |
158 | public function set($bookmark, $save = true) | 162 | public function set($bookmark, $save = true) |
159 | { | 163 | { |
160 | if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { | 164 | if (true !== $this->isLoggedIn) { |
161 | throw new Exception(t('You\'re not authorized to alter the datastore')); | 165 | throw new Exception(t('You\'re not authorized to alter the datastore')); |
162 | } | 166 | } |
163 | if (! $bookmark instanceof Bookmark) { | 167 | if (! $bookmark instanceof Bookmark) { |
@@ -182,7 +186,7 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
182 | */ | 186 | */ |
183 | public function add($bookmark, $save = true) | 187 | public function add($bookmark, $save = true) |
184 | { | 188 | { |
185 | if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { | 189 | if (true !== $this->isLoggedIn) { |
186 | throw new Exception(t('You\'re not authorized to alter the datastore')); | 190 | throw new Exception(t('You\'re not authorized to alter the datastore')); |
187 | } | 191 | } |
188 | if (! $bookmark instanceof Bookmark) { | 192 | if (! $bookmark instanceof Bookmark) { |
@@ -207,7 +211,7 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
207 | */ | 211 | */ |
208 | public function addOrSet($bookmark, $save = true) | 212 | public function addOrSet($bookmark, $save = true) |
209 | { | 213 | { |
210 | if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { | 214 | if (true !== $this->isLoggedIn) { |
211 | throw new Exception(t('You\'re not authorized to alter the datastore')); | 215 | throw new Exception(t('You\'re not authorized to alter the datastore')); |
212 | } | 216 | } |
213 | if (! $bookmark instanceof Bookmark) { | 217 | if (! $bookmark instanceof Bookmark) { |
@@ -224,7 +228,7 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
224 | */ | 228 | */ |
225 | public function remove($bookmark, $save = true) | 229 | public function remove($bookmark, $save = true) |
226 | { | 230 | { |
227 | if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { | 231 | if (true !== $this->isLoggedIn) { |
228 | throw new Exception(t('You\'re not authorized to alter the datastore')); | 232 | throw new Exception(t('You\'re not authorized to alter the datastore')); |
229 | } | 233 | } |
230 | if (! $bookmark instanceof Bookmark) { | 234 | if (! $bookmark instanceof Bookmark) { |
@@ -277,7 +281,7 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
277 | */ | 281 | */ |
278 | public function save() | 282 | public function save() |
279 | { | 283 | { |
280 | if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { | 284 | if (true !== $this->isLoggedIn) { |
281 | // TODO: raise an Exception instead | 285 | // TODO: raise an Exception instead |
282 | die('You are not authorized to change the database.'); | 286 | die('You are not authorized to change the database.'); |
283 | } | 287 | } |
@@ -359,16 +363,10 @@ class BookmarkFileService implements BookmarkServiceInterface | |||
359 | { | 363 | { |
360 | $initializer = new BookmarkInitializer($this); | 364 | $initializer = new BookmarkInitializer($this); |
361 | $initializer->initialize(); | 365 | $initializer->initialize(); |
362 | } | ||
363 | 366 | ||
364 | public function enableAnonymousPermission(): void | 367 | if (true === $this->isLoggedIn) { |
365 | { | 368 | $this->save(); |
366 | $this->anonymousPermission = true; | 369 | } |
367 | } | ||
368 | |||
369 | public function disableAnonymousPermission(): void | ||
370 | { | ||
371 | $this->anonymousPermission = false; | ||
372 | } | 370 | } |
373 | 371 | ||
374 | /** | 372 | /** |
diff --git a/application/bookmark/BookmarkIO.php b/application/bookmark/BookmarkIO.php index 1026e2f9..6bf7f365 100644 --- a/application/bookmark/BookmarkIO.php +++ b/application/bookmark/BookmarkIO.php | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | namespace Shaarli\Bookmark; | 3 | namespace Shaarli\Bookmark; |
4 | 4 | ||
5 | use Shaarli\Bookmark\Exception\DatastoreNotInitializedException; | ||
5 | use Shaarli\Bookmark\Exception\EmptyDataStoreException; | 6 | use Shaarli\Bookmark\Exception\EmptyDataStoreException; |
6 | use Shaarli\Bookmark\Exception\NotWritableDataStoreException; | 7 | use Shaarli\Bookmark\Exception\NotWritableDataStoreException; |
7 | use Shaarli\Config\ConfigManager; | 8 | use Shaarli\Config\ConfigManager; |
@@ -52,13 +53,14 @@ class BookmarkIO | |||
52 | * | 53 | * |
53 | * @return BookmarkArray instance | 54 | * @return BookmarkArray instance |
54 | * | 55 | * |
55 | * @throws NotWritableDataStoreException Data couldn't be loaded | 56 | * @throws NotWritableDataStoreException Data couldn't be loaded |
56 | * @throws EmptyDataStoreException Datastore doesn't exist | 57 | * @throws EmptyDataStoreException Datastore file exists but does not contain any bookmark |
58 | * @throws DatastoreNotInitializedException File does not exists | ||
57 | */ | 59 | */ |
58 | public function read() | 60 | public function read() |
59 | { | 61 | { |
60 | if (! file_exists($this->datastore)) { | 62 | if (! file_exists($this->datastore)) { |
61 | throw new EmptyDataStoreException(); | 63 | throw new DatastoreNotInitializedException(); |
62 | } | 64 | } |
63 | 65 | ||
64 | if (!is_writable($this->datastore)) { | 66 | if (!is_writable($this->datastore)) { |
diff --git a/application/bookmark/BookmarkInitializer.php b/application/bookmark/BookmarkInitializer.php index 479ee9a9..cd2d1724 100644 --- a/application/bookmark/BookmarkInitializer.php +++ b/application/bookmark/BookmarkInitializer.php | |||
@@ -6,8 +6,7 @@ namespace Shaarli\Bookmark; | |||
6 | * Class BookmarkInitializer | 6 | * Class BookmarkInitializer |
7 | * | 7 | * |
8 | * This class is used to initialized default bookmarks after a fresh install of Shaarli. | 8 | * This class is used to initialized default bookmarks after a fresh install of Shaarli. |
9 | * It is no longer call when the data store is empty, | 9 | * It should be only called if the datastore file does not exist(users might want to delete the default bookmarks). |
10 | * because user might want to delete default bookmarks after the install. | ||
11 | * | 10 | * |
12 | * To prevent data corruption, it does not overwrite existing bookmarks, | 11 | * To prevent data corruption, it does not overwrite existing bookmarks, |
13 | * even though there should not be any. | 12 | * even though there should not be any. |
@@ -34,8 +33,6 @@ class BookmarkInitializer | |||
34 | */ | 33 | */ |
35 | public function initialize() | 34 | public function initialize() |
36 | { | 35 | { |
37 | $this->bookmarkService->enableAnonymousPermission(); | ||
38 | |||
39 | $bookmark = new Bookmark(); | 36 | $bookmark = new Bookmark(); |
40 | $bookmark->setTitle(t('My secret stuff... - Pastebin.com')); | 37 | $bookmark->setTitle(t('My secret stuff... - Pastebin.com')); |
41 | $bookmark->setUrl('http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8='); | 38 | $bookmark->setUrl('http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8='); |
@@ -57,9 +54,5 @@ You use the community supported version of the original Shaarli project, by Seba | |||
57 | )); | 54 | )); |
58 | $bookmark->setTagsString('opensource software'); | 55 | $bookmark->setTagsString('opensource software'); |
59 | $this->bookmarkService->add($bookmark, false); | 56 | $this->bookmarkService->add($bookmark, false); |
60 | |||
61 | $this->bookmarkService->save(); | ||
62 | |||
63 | $this->bookmarkService->disableAnonymousPermission(); | ||
64 | } | 57 | } |
65 | } | 58 | } |
diff --git a/application/bookmark/BookmarkServiceInterface.php b/application/bookmark/BookmarkServiceInterface.php index 37fbda89..ce8bd912 100644 --- a/application/bookmark/BookmarkServiceInterface.php +++ b/application/bookmark/BookmarkServiceInterface.php | |||
@@ -6,7 +6,6 @@ namespace Shaarli\Bookmark; | |||
6 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; | 6 | use Shaarli\Bookmark\Exception\BookmarkNotFoundException; |
7 | use Shaarli\Bookmark\Exception\NotWritableDataStoreException; | 7 | use Shaarli\Bookmark\Exception\NotWritableDataStoreException; |
8 | use Shaarli\Config\ConfigManager; | 8 | use Shaarli\Config\ConfigManager; |
9 | use Shaarli\Exceptions\IOException; | ||
10 | use Shaarli\History; | 9 | use Shaarli\History; |
11 | 10 | ||
12 | /** | 11 | /** |
@@ -177,17 +176,4 @@ interface BookmarkServiceInterface | |||
177 | * Creates the default database after a fresh install. | 176 | * Creates the default database after a fresh install. |
178 | */ | 177 | */ |
179 | public function initialize(); | 178 | public function initialize(); |
180 | |||
181 | /** | ||
182 | * Allow to write the datastore from anonymous session (not logged in). | ||
183 | * | ||
184 | * This covers a few specific use cases, such as datastore initialization, | ||
185 | * but it should be used carefully as it can lead to security issues. | ||
186 | */ | ||
187 | public function enableAnonymousPermission(); | ||
188 | |||
189 | /** | ||
190 | * Disable anonymous permission. | ||
191 | */ | ||
192 | public function disableAnonymousPermission(); | ||
193 | } | 179 | } |
diff --git a/application/bookmark/exception/DatastoreNotInitializedException.php b/application/bookmark/exception/DatastoreNotInitializedException.php new file mode 100644 index 00000000..f495049d --- /dev/null +++ b/application/bookmark/exception/DatastoreNotInitializedException.php | |||
@@ -0,0 +1,10 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Bookmark\Exception; | ||
6 | |||
7 | class DatastoreNotInitializedException extends \Exception | ||
8 | { | ||
9 | |||
10 | } | ||
diff --git a/application/front/controller/visitor/InstallController.php b/application/front/controller/visitor/InstallController.php index 5e3152c7..7cb32777 100644 --- a/application/front/controller/visitor/InstallController.php +++ b/application/front/controller/visitor/InstallController.php | |||
@@ -5,7 +5,6 @@ declare(strict_types=1); | |||
5 | namespace Shaarli\Front\Controller\Visitor; | 5 | namespace Shaarli\Front\Controller\Visitor; |
6 | 6 | ||
7 | use Shaarli\ApplicationUtils; | 7 | use Shaarli\ApplicationUtils; |
8 | use Shaarli\Bookmark\BookmarkFilter; | ||
9 | use Shaarli\Container\ShaarliContainer; | 8 | use Shaarli\Container\ShaarliContainer; |
10 | use Shaarli\Front\Exception\AlreadyInstalledException; | 9 | use Shaarli\Front\Exception\AlreadyInstalledException; |
11 | use Shaarli\Front\Exception\ResourcePermissionException; | 10 | use Shaarli\Front\Exception\ResourcePermissionException; |
@@ -140,10 +139,6 @@ class InstallController extends ShaarliVisitorController | |||
140 | return $response->write($this->render('error')); | 139 | return $response->write($this->render('error')); |
141 | } | 140 | } |
142 | 141 | ||
143 | if ($this->container->bookmarkService->count(BookmarkFilter::$ALL) === 0) { | ||
144 | $this->container->bookmarkService->initialize(); | ||
145 | } | ||
146 | |||
147 | $this->container->sessionManager->setSessionParameter( | 142 | $this->container->sessionManager->setSessionParameter( |
148 | SessionManager::KEY_SUCCESS_MESSAGES, | 143 | SessionManager::KEY_SUCCESS_MESSAGES, |
149 | [t('Shaarli is now configured. Please login and start shaaring your bookmarks!')] | 144 | [t('Shaarli is now configured. Please login and start shaaring your bookmarks!')] |
diff --git a/tests/bookmark/BookmarkInitializerTest.php b/tests/bookmark/BookmarkInitializerTest.php index d23eb069..3906cc7f 100644 --- a/tests/bookmark/BookmarkInitializerTest.php +++ b/tests/bookmark/BookmarkInitializerTest.php | |||
@@ -3,7 +3,6 @@ | |||
3 | namespace Shaarli\Bookmark; | 3 | namespace Shaarli\Bookmark; |
4 | 4 | ||
5 | use PHPUnit\Framework\TestCase; | 5 | use PHPUnit\Framework\TestCase; |
6 | use ReferenceLinkDB; | ||
7 | use Shaarli\Config\ConfigManager; | 6 | use Shaarli\Config\ConfigManager; |
8 | use Shaarli\History; | 7 | use Shaarli\History; |
9 | 8 | ||
@@ -54,9 +53,9 @@ class BookmarkInitializerTest extends TestCase | |||
54 | } | 53 | } |
55 | 54 | ||
56 | /** | 55 | /** |
57 | * Test initialize() with an empty data store. | 56 | * Test initialize() with a data store containing bookmarks. |
58 | */ | 57 | */ |
59 | public function testInitializeEmptyDataStore() | 58 | public function testInitializeNotEmptyDataStore(): void |
60 | { | 59 | { |
61 | $refDB = new \ReferenceLinkDB(); | 60 | $refDB = new \ReferenceLinkDB(); |
62 | $refDB->write(self::$testDatastore); | 61 | $refDB->write(self::$testDatastore); |
@@ -79,6 +78,8 @@ class BookmarkInitializerTest extends TestCase | |||
79 | ); | 78 | ); |
80 | $this->assertFalse($bookmark->isPrivate()); | 79 | $this->assertFalse($bookmark->isPrivate()); |
81 | 80 | ||
81 | $this->bookmarkService->save(); | ||
82 | |||
82 | // Reload from file | 83 | // Reload from file |
83 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); | 84 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); |
84 | $this->assertEquals($refDB->countLinks() + 2, $this->bookmarkService->count()); | 85 | $this->assertEquals($refDB->countLinks() + 2, $this->bookmarkService->count()); |
@@ -97,10 +98,13 @@ class BookmarkInitializerTest extends TestCase | |||
97 | } | 98 | } |
98 | 99 | ||
99 | /** | 100 | /** |
100 | * Test initialize() with a data store containing bookmarks. | 101 | * Test initialize() with an a non existent datastore file . |
101 | */ | 102 | */ |
102 | public function testInitializeNotEmptyDataStore() | 103 | public function testInitializeNonExistentDataStore(): void |
103 | { | 104 | { |
105 | $this->conf->set('resource.datastore', static::$testDatastore . '_empty'); | ||
106 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); | ||
107 | |||
104 | $this->initializer->initialize(); | 108 | $this->initializer->initialize(); |
105 | 109 | ||
106 | $this->assertEquals(2, $this->bookmarkService->count()); | 110 | $this->assertEquals(2, $this->bookmarkService->count()); |
diff --git a/tests/front/controller/visitor/InstallControllerTest.php b/tests/front/controller/visitor/InstallControllerTest.php index 089c64ac..3b855365 100644 --- a/tests/front/controller/visitor/InstallControllerTest.php +++ b/tests/front/controller/visitor/InstallControllerTest.php | |||
@@ -224,9 +224,6 @@ class InstallControllerTest extends TestCase | |||
224 | ; | 224 | ; |
225 | $this->container->conf->expects(static::once())->method('write'); | 225 | $this->container->conf->expects(static::once())->method('write'); |
226 | 226 | ||
227 | $this->container->bookmarkService->expects(static::once())->method('count')->willReturn(0); | ||
228 | $this->container->bookmarkService->expects(static::once())->method('initialize'); | ||
229 | |||
230 | $this->container->sessionManager | 227 | $this->container->sessionManager |
231 | ->expects(static::once()) | 228 | ->expects(static::once()) |
232 | ->method('setSessionParameter') | 229 | ->method('setSessionParameter') |