aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--application/bookmark/BookmarkFileService.php36
-rw-r--r--application/bookmark/BookmarkIO.php8
-rw-r--r--application/bookmark/BookmarkInitializer.php9
-rw-r--r--application/bookmark/BookmarkServiceInterface.php14
-rw-r--r--application/bookmark/exception/DatastoreNotInitializedException.php10
-rw-r--r--application/front/controller/visitor/InstallController.php5
-rw-r--r--tests/bookmark/BookmarkInitializerTest.php14
-rw-r--r--tests/front/controller/visitor/InstallControllerTest.php3
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
7use Exception; 7use Exception;
8use Shaarli\Bookmark\Exception\BookmarkNotFoundException; 8use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
9use Shaarli\Bookmark\Exception\DatastoreNotInitializedException;
9use Shaarli\Bookmark\Exception\EmptyDataStoreException; 10use Shaarli\Bookmark\Exception\EmptyDataStoreException;
10use Shaarli\Config\ConfigManager; 11use Shaarli\Config\ConfigManager;
11use Shaarli\Formatter\BookmarkMarkdownFormatter; 12use 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
3namespace Shaarli\Bookmark; 3namespace Shaarli\Bookmark;
4 4
5use Shaarli\Bookmark\Exception\DatastoreNotInitializedException;
5use Shaarli\Bookmark\Exception\EmptyDataStoreException; 6use Shaarli\Bookmark\Exception\EmptyDataStoreException;
6use Shaarli\Bookmark\Exception\NotWritableDataStoreException; 7use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
7use Shaarli\Config\ConfigManager; 8use 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;
6use Shaarli\Bookmark\Exception\BookmarkNotFoundException; 6use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
7use Shaarli\Bookmark\Exception\NotWritableDataStoreException; 7use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
8use Shaarli\Config\ConfigManager; 8use Shaarli\Config\ConfigManager;
9use Shaarli\Exceptions\IOException;
10use Shaarli\History; 9use 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
3declare(strict_types=1);
4
5namespace Shaarli\Bookmark\Exception;
6
7class 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);
5namespace Shaarli\Front\Controller\Visitor; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use Shaarli\ApplicationUtils; 7use Shaarli\ApplicationUtils;
8use Shaarli\Bookmark\BookmarkFilter;
9use Shaarli\Container\ShaarliContainer; 8use Shaarli\Container\ShaarliContainer;
10use Shaarli\Front\Exception\AlreadyInstalledException; 9use Shaarli\Front\Exception\AlreadyInstalledException;
11use Shaarli\Front\Exception\ResourcePermissionException; 10use 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 @@
3namespace Shaarli\Bookmark; 3namespace Shaarli\Bookmark;
4 4
5use PHPUnit\Framework\TestCase; 5use PHPUnit\Framework\TestCase;
6use ReferenceLinkDB;
7use Shaarli\Config\ConfigManager; 6use Shaarli\Config\ConfigManager;
8use Shaarli\History; 7use 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')