Remove anonymous permission and initialize bookmarks on login

This commit is contained in:
ArthurHoaro 2020-08-01 11:10:57 +02:00
parent f7f08ceec1
commit d6e5f04d39
8 changed files with 42 additions and 57 deletions

View file

@ -6,6 +6,7 @@
use Exception; use Exception;
use Shaarli\Bookmark\Exception\BookmarkNotFoundException; use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
use Shaarli\Bookmark\Exception\DatastoreNotInitializedException;
use Shaarli\Bookmark\Exception\EmptyDataStoreException; use Shaarli\Bookmark\Exception\EmptyDataStoreException;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\Formatter\BookmarkMarkdownFormatter; use Shaarli\Formatter\BookmarkMarkdownFormatter;
@ -46,9 +47,6 @@ class BookmarkFileService implements BookmarkServiceInterface
/** @var bool true for logged in users. Default value to retrieve private bookmarks. */ /** @var bool true for logged in users. Default value to retrieve private bookmarks. */
protected $isLoggedIn; protected $isLoggedIn;
/** @var bool Allow datastore alteration from not logged in users. */
protected $anonymousPermission = false;
/** /**
* @inheritDoc * @inheritDoc
*/ */
@ -65,10 +63,16 @@ public function __construct(ConfigManager $conf, History $history, $isLoggedIn)
} else { } else {
try { try {
$this->bookmarks = $this->bookmarksIO->read(); $this->bookmarks = $this->bookmarksIO->read();
} catch (EmptyDataStoreException $e) { } catch (EmptyDataStoreException|DatastoreNotInitializedException $e) {
$this->bookmarks = new BookmarkArray(); $this->bookmarks = new BookmarkArray();
if ($this->isLoggedIn) { if ($this->isLoggedIn) {
$this->save(); // Datastore file does not exists, we initialize it with default bookmarks.
if ($e instanceof DatastoreNotInitializedException) {
$this->initialize();
} else {
$this->save();
}
} }
} }
@ -157,7 +161,7 @@ public function get($id, $visibility = null)
*/ */
public function set($bookmark, $save = true) public function set($bookmark, $save = true)
{ {
if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { if (true !== $this->isLoggedIn) {
throw new Exception(t('You\'re not authorized to alter the datastore')); throw new Exception(t('You\'re not authorized to alter the datastore'));
} }
if (! $bookmark instanceof Bookmark) { if (! $bookmark instanceof Bookmark) {
@ -182,7 +186,7 @@ public function set($bookmark, $save = true)
*/ */
public function add($bookmark, $save = true) public function add($bookmark, $save = true)
{ {
if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { if (true !== $this->isLoggedIn) {
throw new Exception(t('You\'re not authorized to alter the datastore')); throw new Exception(t('You\'re not authorized to alter the datastore'));
} }
if (! $bookmark instanceof Bookmark) { if (! $bookmark instanceof Bookmark) {
@ -207,7 +211,7 @@ public function add($bookmark, $save = true)
*/ */
public function addOrSet($bookmark, $save = true) public function addOrSet($bookmark, $save = true)
{ {
if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { if (true !== $this->isLoggedIn) {
throw new Exception(t('You\'re not authorized to alter the datastore')); throw new Exception(t('You\'re not authorized to alter the datastore'));
} }
if (! $bookmark instanceof Bookmark) { if (! $bookmark instanceof Bookmark) {
@ -224,7 +228,7 @@ public function addOrSet($bookmark, $save = true)
*/ */
public function remove($bookmark, $save = true) public function remove($bookmark, $save = true)
{ {
if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { if (true !== $this->isLoggedIn) {
throw new Exception(t('You\'re not authorized to alter the datastore')); throw new Exception(t('You\'re not authorized to alter the datastore'));
} }
if (! $bookmark instanceof Bookmark) { if (! $bookmark instanceof Bookmark) {
@ -277,7 +281,7 @@ public function count($visibility = null)
*/ */
public function save() public function save()
{ {
if (true !== $this->isLoggedIn && true !== $this->anonymousPermission) { if (true !== $this->isLoggedIn) {
// TODO: raise an Exception instead // TODO: raise an Exception instead
die('You are not authorized to change the database.'); die('You are not authorized to change the database.');
} }
@ -359,16 +363,10 @@ public function initialize()
{ {
$initializer = new BookmarkInitializer($this); $initializer = new BookmarkInitializer($this);
$initializer->initialize(); $initializer->initialize();
}
public function enableAnonymousPermission(): void if (true === $this->isLoggedIn) {
{ $this->save();
$this->anonymousPermission = true; }
}
public function disableAnonymousPermission(): void
{
$this->anonymousPermission = false;
} }
/** /**

View file

@ -2,6 +2,7 @@
namespace Shaarli\Bookmark; namespace Shaarli\Bookmark;
use Shaarli\Bookmark\Exception\DatastoreNotInitializedException;
use Shaarli\Bookmark\Exception\EmptyDataStoreException; use Shaarli\Bookmark\Exception\EmptyDataStoreException;
use Shaarli\Bookmark\Exception\NotWritableDataStoreException; use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -52,13 +53,14 @@ public function __construct($conf)
* *
* @return BookmarkArray instance * @return BookmarkArray instance
* *
* @throws NotWritableDataStoreException Data couldn't be loaded * @throws NotWritableDataStoreException Data couldn't be loaded
* @throws EmptyDataStoreException Datastore doesn't exist * @throws EmptyDataStoreException Datastore file exists but does not contain any bookmark
* @throws DatastoreNotInitializedException File does not exists
*/ */
public function read() public function read()
{ {
if (! file_exists($this->datastore)) { if (! file_exists($this->datastore)) {
throw new EmptyDataStoreException(); throw new DatastoreNotInitializedException();
} }
if (!is_writable($this->datastore)) { if (!is_writable($this->datastore)) {

View file

@ -6,8 +6,7 @@
* Class BookmarkInitializer * Class BookmarkInitializer
* *
* This class is used to initialized default bookmarks after a fresh install of Shaarli. * This class is used to initialized default bookmarks after a fresh install of Shaarli.
* It is no longer call when the data store is empty, * It should be only called if the datastore file does not exist(users might want to delete the default bookmarks).
* because user might want to delete default bookmarks after the install.
* *
* To prevent data corruption, it does not overwrite existing bookmarks, * To prevent data corruption, it does not overwrite existing bookmarks,
* even though there should not be any. * even though there should not be any.
@ -34,8 +33,6 @@ public function __construct($bookmarkService)
*/ */
public function initialize() public function initialize()
{ {
$this->bookmarkService->enableAnonymousPermission();
$bookmark = new Bookmark(); $bookmark = new Bookmark();
$bookmark->setTitle(t('My secret stuff... - Pastebin.com')); $bookmark->setTitle(t('My secret stuff... - Pastebin.com'));
$bookmark->setUrl('http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8='); $bookmark->setUrl('http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=');
@ -57,9 +54,5 @@ public function initialize()
)); ));
$bookmark->setTagsString('opensource software'); $bookmark->setTagsString('opensource software');
$this->bookmarkService->add($bookmark, false); $this->bookmarkService->add($bookmark, false);
$this->bookmarkService->save();
$this->bookmarkService->disableAnonymousPermission();
} }
} }

View file

@ -6,7 +6,6 @@
use Shaarli\Bookmark\Exception\BookmarkNotFoundException; use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
use Shaarli\Bookmark\Exception\NotWritableDataStoreException; use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\Exceptions\IOException;
use Shaarli\History; use Shaarli\History;
/** /**
@ -177,17 +176,4 @@ public function filterDay($request);
* Creates the default database after a fresh install. * Creates the default database after a fresh install.
*/ */
public function initialize(); public function initialize();
/**
* Allow to write the datastore from anonymous session (not logged in).
*
* This covers a few specific use cases, such as datastore initialization,
* but it should be used carefully as it can lead to security issues.
*/
public function enableAnonymousPermission();
/**
* Disable anonymous permission.
*/
public function disableAnonymousPermission();
} }

View file

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Shaarli\Bookmark\Exception;
class DatastoreNotInitializedException extends \Exception
{
}

View file

@ -5,7 +5,6 @@
namespace Shaarli\Front\Controller\Visitor; namespace Shaarli\Front\Controller\Visitor;
use Shaarli\ApplicationUtils; use Shaarli\ApplicationUtils;
use Shaarli\Bookmark\BookmarkFilter;
use Shaarli\Container\ShaarliContainer; use Shaarli\Container\ShaarliContainer;
use Shaarli\Front\Exception\AlreadyInstalledException; use Shaarli\Front\Exception\AlreadyInstalledException;
use Shaarli\Front\Exception\ResourcePermissionException; use Shaarli\Front\Exception\ResourcePermissionException;
@ -140,10 +139,6 @@ public function save(Request $request, Response $response): Response
return $response->write($this->render('error')); return $response->write($this->render('error'));
} }
if ($this->container->bookmarkService->count(BookmarkFilter::$ALL) === 0) {
$this->container->bookmarkService->initialize();
}
$this->container->sessionManager->setSessionParameter( $this->container->sessionManager->setSessionParameter(
SessionManager::KEY_SUCCESS_MESSAGES, SessionManager::KEY_SUCCESS_MESSAGES,
[t('Shaarli is now configured. Please login and start shaaring your bookmarks!')] [t('Shaarli is now configured. Please login and start shaaring your bookmarks!')]

View file

@ -3,7 +3,6 @@
namespace Shaarli\Bookmark; namespace Shaarli\Bookmark;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use ReferenceLinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
@ -54,9 +53,9 @@ public function setUp()
} }
/** /**
* Test initialize() with an empty data store. * Test initialize() with a data store containing bookmarks.
*/ */
public function testInitializeEmptyDataStore() public function testInitializeNotEmptyDataStore(): void
{ {
$refDB = new \ReferenceLinkDB(); $refDB = new \ReferenceLinkDB();
$refDB->write(self::$testDatastore); $refDB->write(self::$testDatastore);
@ -79,6 +78,8 @@ public function testInitializeEmptyDataStore()
); );
$this->assertFalse($bookmark->isPrivate()); $this->assertFalse($bookmark->isPrivate());
$this->bookmarkService->save();
// Reload from file // Reload from file
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true);
$this->assertEquals($refDB->countLinks() + 2, $this->bookmarkService->count()); $this->assertEquals($refDB->countLinks() + 2, $this->bookmarkService->count());
@ -97,10 +98,13 @@ public function testInitializeEmptyDataStore()
} }
/** /**
* Test initialize() with a data store containing bookmarks. * Test initialize() with an a non existent datastore file .
*/ */
public function testInitializeNotEmptyDataStore() public function testInitializeNonExistentDataStore(): void
{ {
$this->conf->set('resource.datastore', static::$testDatastore . '_empty');
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true);
$this->initializer->initialize(); $this->initializer->initialize();
$this->assertEquals(2, $this->bookmarkService->count()); $this->assertEquals(2, $this->bookmarkService->count());

View file

@ -224,9 +224,6 @@ public function testSaveInstallValid(): void
; ;
$this->container->conf->expects(static::once())->method('write'); $this->container->conf->expects(static::once())->method('write');
$this->container->bookmarkService->expects(static::once())->method('count')->willReturn(0);
$this->container->bookmarkService->expects(static::once())->method('initialize');
$this->container->sessionManager $this->container->sessionManager
->expects(static::once()) ->expects(static::once())
->method('setSessionParameter') ->method('setSessionParameter')