diff --git a/.travis.yml b/.travis.yml
index 34756a47..960da5ae 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@ php:
branches:
only:
- master
- - 3.0
+ - /^v\d+\.\d+(\.\d+)?(-\S*)?$/
addons:
mariadb: '10.1'
diff --git a/app/modules/web/Controllers/PluginController.php b/app/modules/web/Controllers/PluginController.php
index 44d3c1e0..b6ad3d3f 100644
--- a/app/modules/web/Controllers/PluginController.php
+++ b/app/modules/web/Controllers/PluginController.php
@@ -29,12 +29,13 @@ use Psr\Container\NotFoundExceptionInterface;
use SP\Core\Acl\Acl;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
-use SP\DataModel\PluginData;
use SP\Http\JsonResponse;
use SP\Modules\Web\Controllers\Helpers\Grid\PluginGrid;
use SP\Modules\Web\Controllers\Traits\ItemTrait;
use SP\Modules\Web\Controllers\Traits\JsonTrait;
use SP\Plugin\PluginManager;
+use SP\Repositories\Plugin\PluginModel;
+use SP\Services\Plugin\PluginDataService;
use SP\Services\Plugin\PluginService;
/**
@@ -50,6 +51,10 @@ final class PluginController extends ControllerBase
* @var PluginService
*/
protected $pluginService;
+ /**
+ * @var PluginDataService
+ */
+ protected $pluginDataService;
/**
* indexAction
@@ -165,8 +170,8 @@ final class PluginController extends ControllerBase
{
$this->view->addTemplate('plugin');
- $pluginData = $pluginId ? $this->pluginService->getById($pluginId) : new PluginData();
- $pluginInfo = $this->dic->get(PluginManager::class)->getPluginInfo($pluginData->name);
+ $pluginData = $pluginId ? $this->pluginService->getById($pluginId) : new PluginModel();
+ $pluginInfo = $this->dic->get(PluginManager::class)->getPlugin($pluginData->getName());
$this->view->assign('plugin', $pluginData);
$this->view->assign('pluginInfo', $pluginInfo);
@@ -252,7 +257,8 @@ final class PluginController extends ControllerBase
try {
$this->checkSecurityToken($this->previousSk, $this->request);
- $this->pluginService->resetById($id);
+ $pluginModel = $this->pluginService->getById($id);
+ $this->pluginDataService->delete($pluginModel->getName());
$this->eventDispatcher->notifyEvent('edit.plugin.reset',
new Event($this,
@@ -317,5 +323,6 @@ final class PluginController extends ControllerBase
$this->checkLoggedIn();
$this->pluginService = $this->dic->get(PluginService::class);
+ $this->pluginDataService = $this->dic->get(PluginDataService::class);
}
}
\ No newline at end of file
diff --git a/app/modules/web/themes/material-blue/views/plugin/plugin.inc b/app/modules/web/themes/material-blue/views/plugin/plugin.inc
index 08666b9c..ba4a51d0 100644
--- a/app/modules/web/themes/material-blue/views/plugin/plugin.inc
+++ b/app/modules/web/themes/material-blue/views/plugin/plugin.inc
@@ -1,11 +1,11 @@
{$name};
+ }
+
+ return null;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Plugin/PluginInterface.php b/lib/SP/Plugin/PluginInterface.php
index a4d4d1c9..e48a7977 100644
--- a/lib/SP/Plugin/PluginInterface.php
+++ b/lib/SP/Plugin/PluginInterface.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -24,8 +24,6 @@
namespace SP\Plugin;
-use SP\DataModel\PluginData;
-
/**
* Interface PluginInterface
*
@@ -88,9 +86,9 @@ interface PluginInterface extends PluginEventReceiver
public function getData();
/**
- * @param PluginData $pluginData
+ * @param PluginOperation $pluginOperation
*/
- public function onLoadData(PluginData $pluginData);
+ public function onLoad(PluginOperation $pluginOperation);
/**
* @return int
@@ -101,4 +99,11 @@ interface PluginInterface extends PluginEventReceiver
* @param int $enabled
*/
public function setEnabled($enabled);
+
+ /**
+ * @param string $version
+ * @param PluginOperation $pluginOperation
+ * @param mixed $extra
+ */
+ public function upgrade(string $version, PluginOperation $pluginOperation, $extra = null);
}
\ No newline at end of file
diff --git a/lib/SP/Plugin/PluginManager.php b/lib/SP/Plugin/PluginManager.php
index 7e0818d2..5109e862 100644
--- a/lib/SP/Plugin/PluginManager.php
+++ b/lib/SP/Plugin/PluginManager.php
@@ -32,10 +32,12 @@ use SP\Core\Events\EventDispatcher;
use SP\Core\Events\EventMessage;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\QueryException;
-use SP\DataModel\PluginData;
use SP\Repositories\NoSuchItemException;
+use SP\Repositories\Plugin\PluginModel;
use SP\Services\Install\Installer;
+use SP\Services\Plugin\PluginDataService;
use SP\Services\Plugin\PluginService;
+use SP\Util\VersionUtil;
/**
* Class PluginUtil
@@ -72,17 +74,26 @@ final class PluginManager
* @var EventDispatcher
*/
private $eventDispatcher;
+ /**
+ * @var PluginDataService
+ */
+ private $pluginDataService;
/**
* PluginManager constructor.
*
- * @param PluginService $pluginService
- * @param ContextInterface $context
- * @param EventDispatcher $eventDispatcher
+ * @param PluginService $pluginService
+ * @param PluginDataService $pluginDataService
+ * @param ContextInterface $context
+ * @param EventDispatcher $eventDispatcher
*/
- public function __construct(PluginService $pluginService, ContextInterface $context, EventDispatcher $eventDispatcher)
+ public function __construct(PluginService $pluginService,
+ PluginDataService $pluginDataService,
+ ContextInterface $context,
+ EventDispatcher $eventDispatcher)
{
$this->pluginService = $pluginService;
+ $this->pluginDataService = $pluginDataService;
$this->context = $context;
$this->eventDispatcher = $eventDispatcher;
@@ -127,13 +138,17 @@ final class PluginManager
*
* @return PluginInterface
*/
- public function getPluginInfo($name)
+ public function getPlugin($name)
{
if (isset(self::$pluginsAvailable[$name])) {
- return $this->loadPluginClass(
+ $plugin = $this->loadPluginClass(
$name,
self::$pluginsAvailable[$name]['namespace']
);
+
+ $this->initPluginData($plugin);
+
+ return $plugin;
}
return null;
@@ -147,7 +162,7 @@ final class PluginManager
*
* @return PluginInterface
*/
- public function loadPluginClass(string $name, string $namespace)
+ private function loadPluginClass(string $name, string $namespace)
{
$name = ucfirst($name);
@@ -171,16 +186,6 @@ final class PluginManager
);
$this->disabledPlugins[] = $name;
-
- return $plugin;
- }
-
- $pluginData = $this->pluginService->getByName($name);
-
- if ($pluginData->getEnabled() === 1) {
- $plugin->onLoadData($pluginData);
- } else {
- $this->disabledPlugins[] = $name;
}
return $plugin;
@@ -225,6 +230,31 @@ final class PluginManager
return true;
}
+ /**
+ * @param PluginInterface $plugin
+ */
+ private function initPluginData(PluginInterface $plugin)
+ {
+ try {
+ $pluginData = $this->pluginService->getByName($plugin->getName());
+
+ if ($pluginData->getEnabled() === 1) {
+ $plugin->onLoad(new PluginOperation($this->pluginDataService, $plugin->getName()));
+ } else {
+ $this->disabledPlugins[] = $plugin->getName();
+ }
+ } catch (\Exception $e) {
+ processException($e);
+
+ $this->eventDispatcher->notifyEvent('exception',
+ new Event($e, EventMessage::factory()
+ ->addDescription(sprintf(__('Unable to load the "%s" plugin'), $plugin->getName()))
+ ->addDescription($e->getMessage())
+ ->addDetail(__u('Plugin'), $plugin->getName()))
+ );
+ }
+ }
+
/**
* Loads the available and enabled plugins
*
@@ -287,6 +317,8 @@ final class PluginManager
);
if ($plugin !== null) {
+ $this->initPluginData($plugin);
+
logger(sprintf('Plugin loaded: %s', $pluginName));
$this->eventDispatcher->notifyEvent('plugin.load',
@@ -308,7 +340,7 @@ final class PluginManager
*/
private function registerPlugin(string $name)
{
- $pluginData = new PluginData();
+ $pluginData = new PluginModel();
$pluginData->setName($name);
$pluginData->setEnabled(false);
@@ -323,6 +355,61 @@ final class PluginManager
$this->disabledPlugins[] = $name;
}
+ /**
+ * @param string $version
+ */
+ public function upgradePlugins(string $version)
+ {
+ $available = array_keys(self::$pluginsAvailable);
+
+ foreach ($available as $pluginName) {
+ $plugin = $this->loadPluginClass(
+ $pluginName,
+ self::$pluginsAvailable[$pluginName]['namespace']
+ );
+
+ try {
+ $pluginModel = $this->pluginService->getByName($pluginName);
+
+ if ($pluginModel->getVersionLevel() === null
+ || VersionUtil::checkVersion($pluginModel->getVersionLevel(), $version)
+ ) {
+ $this->eventDispatcher->notifyEvent('upgrade.plugin.process',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Upgrading plugin'))
+ ->addDetail(__u('Name'), $pluginName))
+ );
+
+ $plugin->upgrade(
+ $version,
+ new PluginOperation($this->pluginDataService, $pluginName),
+ $pluginModel
+ );
+
+ $pluginModel->setData(null);
+ $pluginModel->setVersionLevel($version);
+
+ $this->pluginService->update($pluginModel);
+
+ $this->eventDispatcher->notifyEvent('upgrade.plugin.process',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Plugin upgraded'))
+ ->addDetail(__u('Name'), $pluginName))
+ );
+ }
+ } catch (\Exception $e) {
+ processException($e);
+
+ $this->eventDispatcher->notifyEvent('exception',
+ new Event($e, EventMessage::factory()
+ ->addDescription(sprintf(__('Unable to upgrade the "%s" plugin'), $pluginName))
+ ->addDescription($e->getMessage())
+ ->addDetail(__u('Plugin'), $pluginName))
+ );
+ }
+ }
+ }
+
/**
* Comprobar disponibilidad de plugins habilitados
*
diff --git a/lib/SP/Plugin/PluginOperation.php b/lib/SP/Plugin/PluginOperation.php
new file mode 100644
index 00000000..a0b2c917
--- /dev/null
+++ b/lib/SP/Plugin/PluginOperation.php
@@ -0,0 +1,119 @@
+.
+ */
+
+namespace SP\Plugin;
+
+use SP\Repositories\Plugin\PluginDataModel;
+use SP\Services\Plugin\PluginDataService;
+
+/**
+ * Class PluginOperation
+ *
+ * @package SP\Plugin
+ */
+final class PluginOperation
+{
+ /**
+ * @var PluginDataService
+ */
+ private $pluginDataService;
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * PluginOperation constructor.
+ *
+ * @param PluginDataService $pluginDataService
+ * @param string $name
+ */
+ public function __construct(PluginDataService $pluginDataService, string $name)
+ {
+ $this->pluginDataService = $pluginDataService;
+ $this->name = $name;
+ }
+
+ /**
+ * @param int $itemId
+ * @param string $data
+ *
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function create(int $itemId, string $data)
+ {
+ $itemData = new PluginDataModel();
+ $itemData->setName($this->name);
+ $itemData->setItemId($itemId);
+ $itemData->setData($data);
+
+ $this->pluginDataService->create($itemData);
+ }
+
+ /**
+ * @param int $itemId
+ * @param string $data
+ *
+ * @return int
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function update(int $itemId, string $data)
+ {
+ $itemData = new PluginDataModel();
+ $itemData->setName($this->name);
+ $itemData->setItemId($itemId);
+ $itemData->setData($data);
+
+ return $this->pluginDataService->update($itemData);
+ }
+
+ /**
+ * @param int $itemId
+ *
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Repositories\NoSuchItemException
+ */
+ public function delete(int $itemId)
+ {
+ $this->pluginDataService->deleteByItemId($this->name, $itemId);
+ }
+
+ /**
+ * @param int $itemId
+ * @param string|null $class
+ *
+ * @return mixed|null
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\NoSuchPropertyException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Repositories\NoSuchItemException
+ */
+ public function get(int $itemId, string $class = null)
+ {
+ return $this->pluginDataService->getByItemId($this->name, $itemId)->hydrate($class);
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Repositories/Plugin/PluginDataModel.php b/lib/SP/Repositories/Plugin/PluginDataModel.php
new file mode 100644
index 00000000..3b42656e
--- /dev/null
+++ b/lib/SP/Repositories/Plugin/PluginDataModel.php
@@ -0,0 +1,119 @@
+.
+ */
+
+namespace SP\Repositories\Plugin;
+
+use SP\Core\Exceptions\NoSuchPropertyException;
+use SP\DataModel\HydratableInterface;
+use SP\Util\Util;
+
+/**
+ * Class PluginData
+ *
+ * @package SP\Repositories\Plugin
+ */
+final class PluginDataModel implements HydratableInterface
+{
+ /**
+ * @var string
+ */
+ private $name;
+ /**
+ * @var int
+ */
+ private $itemId;
+ /**
+ * @var string
+ */
+ private $data;
+
+ /**
+ * @return string
+ */
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ /**
+ * @param string $name
+ */
+ public function setName(string $name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * @return int
+ */
+ public function getItemId(): int
+ {
+ return (int)$this->itemId;
+ }
+
+ /**
+ * @param int $itemId
+ */
+ public function setItemId(int $itemId)
+ {
+ $this->itemId = $itemId;
+ }
+
+ /**
+ * @return string
+ */
+ public function getData(): string
+ {
+ return $this->data;
+ }
+
+ /**
+ * @param string $data
+ */
+ public function setData(string $data)
+ {
+ $this->data = $data;
+ }
+
+ /**
+ * @param string $class
+ *
+ * @param string $property
+ *
+ * @return mixed|null
+ * @throws NoSuchPropertyException
+ */
+ public function hydrate(string $class = null, string $property = 'data')
+ {
+ if (property_exists($this, $property)) {
+ if ($this->data !== null) {
+ return $class !== null ? Util::unserialize($class, $this->data) : unserialize($this->data);
+ }
+
+ return null;
+ }
+
+ throw new NoSuchPropertyException($property);
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Repositories/Plugin/PluginDataRepository.php b/lib/SP/Repositories/Plugin/PluginDataRepository.php
new file mode 100644
index 00000000..ce5437a1
--- /dev/null
+++ b/lib/SP/Repositories/Plugin/PluginDataRepository.php
@@ -0,0 +1,315 @@
+.
+ */
+
+namespace SP\Repositories\Plugin;
+
+use SP\Core\Exceptions\ConstraintException;
+use SP\Core\Exceptions\QueryException;
+use SP\DataModel\ItemSearchData;
+use SP\Repositories\Repository;
+use SP\Repositories\RepositoryItemInterface;
+use SP\Repositories\RepositoryItemTrait;
+use SP\Storage\Database\QueryData;
+use SP\Storage\Database\QueryResult;
+
+/**
+ * Class PluginDataRepository
+ *
+ * @package SP\Repositories\Plugin
+ */
+final class PluginDataRepository extends Repository implements RepositoryItemInterface
+{
+ use RepositoryItemTrait;
+
+ /**
+ * Creates an item
+ *
+ * @param PluginDataModel $itemData
+ *
+ * @return QueryResult
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws QueryException
+ */
+ public function create($itemData)
+ {
+ $query = /** @lang SQL */
+ 'INSERT INTO PluginData SET `name` = ?, itemId = ?, `data` = ?';
+
+ $queryData = new QueryData();
+ $queryData->setQuery($query);
+ $queryData->setParams([
+ $itemData->getName(),
+ $itemData->getItemId(),
+ $itemData->getData()
+ ]);
+ $queryData->setOnErrorMessage(__u('Error while adding plugin\'s data'));
+
+ return $this->db->doQuery($queryData);
+ }
+
+ /**
+ * Updates an item
+ *
+ * @param PluginDataModel $itemData
+ *
+ * @return int
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws QueryException
+ */
+ public function update($itemData)
+ {
+ $query = /** @lang SQL */
+ 'UPDATE PluginData
+ SET `data` = ?
+ WHERE `name` = ? AND itemId = ? LIMIT 1';
+
+ $queryData = new QueryData();
+ $queryData->setQuery($query);
+ $queryData->setParams([
+ $itemData->getData(),
+ $itemData->getName(),
+ $itemData->getItemId()
+ ]);
+ $queryData->setOnErrorMessage(__u('Error while updating plugin\'s data'));
+
+ return $this->db->doQuery($queryData)->getAffectedNumRows();
+ }
+
+ /**
+ * Deletes an item
+ *
+ * @param $id
+ *
+ * @return int
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws QueryException
+ */
+ public function delete($id)
+ {
+ $queryData = new QueryData();
+ $queryData->setQuery('DELETE FROM PluginData WHERE `name` = ?');
+ $queryData->addParam($id);
+ $queryData->setOnErrorMessage(__u('Error while deleting plugin\'s data'));
+
+ return $this->db->doQuery($queryData)->getAffectedNumRows();
+ }
+
+ /**
+ * Deletes an item
+ *
+ * @param string $name
+ * @param int $itemId
+ *
+ * @return int
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ public function deleteByItemId($name, $itemId)
+ {
+ $queryData = new QueryData();
+ $queryData->setQuery('DELETE FROM PluginData WHERE `name` = ? AND itemId = ? LIMIT 1');
+ $queryData->setParams([$name, $itemId]);
+ $queryData->setOnErrorMessage(__u('Error while deleting plugin\'s data'));
+
+ return $this->db->doQuery($queryData)->getAffectedNumRows();
+ }
+
+ /**
+ * Returns the item for given id
+ *
+ * @param int $id
+ *
+ * @return QueryResult
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ public function getById($id)
+ {
+ $query = /** @lang SQL */
+ 'SELECT itemId,
+ `name`,
+ `data`
+ FROM PluginData
+ WHERE `name` = ?';
+
+ $queryData = new QueryData();
+ $queryData->setMapClassName(PluginDataModel::class);
+ $queryData->setQuery($query);
+ $queryData->addParam($id);
+
+ return $this->db->doSelect($queryData);
+ }
+
+ /**
+ * Returns all the items
+ *
+ * @return QueryResult
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ public function getAll()
+ {
+ $query = /** @lang SQL */
+ 'SELECT itemId,
+ `name`,
+ `data`
+ FROM PluginData
+ ORDER BY `name`';
+
+ $queryData = new QueryData();
+ $queryData->setMapClassName(PluginDataModel::class);
+ $queryData->setQuery($query);
+
+ return $this->db->doSelect($queryData);
+ }
+
+ /**
+ * Returns all the items for given ids
+ *
+ * @param array $ids
+ *
+ * @return QueryResult
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ public function getByIdBatch(array $ids)
+ {
+ if (empty($ids)) {
+ return new QueryResult();
+ }
+
+ $query = /** @lang SQL */
+ 'SELECT itemId,
+ `name`,
+ `data`
+ FROM PluginData
+ WHERE `name` IN (' . $this->getParamsFromArray($ids) . ')
+ ORDER BY `name`';
+
+ $queryData = new QueryData();
+ $queryData->setMapClassName(PluginDataModel::class);
+ $queryData->setQuery($query);
+ $queryData->setParams($ids);
+
+ return $this->db->doSelect($queryData);
+ }
+
+ /**
+ * Deletes all the items for given ids
+ *
+ * @param array $ids
+ *
+ * @return int
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ public function deleteByIdBatch(array $ids)
+ {
+ if (empty($ids)) {
+ return 0;
+ }
+
+ $queryData = new QueryData();
+ $queryData->setQuery('DELETE FROM PluginData WHERE `name` IN (' . $this->getParamsFromArray($ids) . ')');
+ $queryData->setParams($ids);
+ $queryData->setOnErrorMessage(__u('Error while deleting plugin\'s data'));
+
+ return $this->db->doQuery($queryData)->getAffectedNumRows();
+ }
+
+ /**
+ * Checks whether the item is in use or not
+ *
+ * @param $id int
+ *
+ * @return void
+ */
+ public function checkInUse($id)
+ {
+ throw new \RuntimeException('Not implemented');
+ }
+
+ /**
+ * Checks whether the item is duplicated on updating
+ *
+ * @param mixed $itemData
+ *
+ * @return void
+ */
+ public function checkDuplicatedOnUpdate($itemData)
+ {
+ throw new \RuntimeException('Not implemented');
+ }
+
+ /**
+ * Checks whether the item is duplicated on adding
+ *
+ * @param mixed $itemData
+ *
+ * @return void
+ */
+ public function checkDuplicatedOnAdd($itemData)
+ {
+ throw new \RuntimeException('Not implemented');
+ }
+
+ /**
+ * Searches for items by a given filter
+ *
+ * @param ItemSearchData $SearchData
+ *
+ * @return mixed
+ */
+ public function search(ItemSearchData $SearchData)
+ {
+ throw new \RuntimeException('Not implemented');
+ }
+
+ /**
+ * Devuelve los datos de un plugin por su nombre
+ *
+ * @param string $name
+ * @param int $itemId
+ *
+ * @return QueryResult
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ public function getByItemId($name, $itemId)
+ {
+ $query = /** @lang SQL */
+ 'SELECT itemId,
+ `name`,
+ `data`
+ FROM PluginData
+ WHERE `name` = ? AND itemId = ? LIMIT 1';
+
+ $queryData = new QueryData();
+ $queryData->setMapClassName(PluginDataModel::class);
+ $queryData->setQuery($query);
+ $queryData->setParams([$name, $itemId]);
+
+ return $this->db->doSelect($queryData);
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/DataModel/PluginData.php b/lib/SP/Repositories/Plugin/PluginModel.php
similarity index 75%
rename from lib/SP/DataModel/PluginData.php
rename to lib/SP/Repositories/Plugin/PluginModel.php
index 410610fe..52ea23f1 100644
--- a/lib/SP/DataModel/PluginData.php
+++ b/lib/SP/Repositories/Plugin/PluginModel.php
@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
- * @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
+ * @copyright 2012-2019, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -22,35 +22,42 @@
* along with sysPass. If not, see .
*/
-namespace SP\DataModel;
+namespace SP\Repositories\Plugin;
+
+use SP\DataModel\DataModelBase;
+use SP\DataModel\DataModelInterface;
/**
* Class PluginData
*
* @package SP\DataModel
*/
-class PluginData extends DataModelBase implements DataModelInterface
+class PluginModel extends DataModelBase implements DataModelInterface
{
/**
* @var int
*/
- public $id;
+ protected $id;
/**
* @var string
*/
- public $name;
+ protected $name;
/**
* @var string
*/
- public $data;
+ protected $data;
/**
* @var int
*/
- public $enabled = 0;
+ protected $enabled = 0;
/**
* @var int
*/
- public $available = 1;
+ protected $available = 1;
+ /**
+ * @var string
+ */
+ protected $versionLevel;
/**
* @return int
@@ -60,14 +67,6 @@ class PluginData extends DataModelBase implements DataModelInterface
return (int)$this->id;
}
- /**
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
-
/**
* @param int $id
*/
@@ -76,6 +75,14 @@ class PluginData extends DataModelBase implements DataModelInterface
$this->id = (int)$id;
}
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
/**
* @param string $name
*/
@@ -131,4 +138,20 @@ class PluginData extends DataModelBase implements DataModelInterface
{
$this->available = (int)$available;
}
+
+ /**
+ * @return string
+ */
+ public function getVersionLevel()
+ {
+ return $this->versionLevel;
+ }
+
+ /**
+ * @param string $versionLevel
+ */
+ public function setVersionLevel(string $versionLevel)
+ {
+ $this->versionLevel = $versionLevel;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Repositories/Plugin/PluginRepository.php b/lib/SP/Repositories/Plugin/PluginRepository.php
index 5dd2d33d..c2fc7a20 100644
--- a/lib/SP/Repositories/Plugin/PluginRepository.php
+++ b/lib/SP/Repositories/Plugin/PluginRepository.php
@@ -29,7 +29,6 @@ use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\ItemData;
use SP\DataModel\ItemSearchData;
-use SP\DataModel\PluginData;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemInterface;
use SP\Repositories\RepositoryItemTrait;
@@ -48,7 +47,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa
/**
* Creates an item
*
- * @param PluginData $itemData
+ * @param PluginModel $itemData
*
* @return QueryResult
* @throws ConstraintException
@@ -75,7 +74,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa
/**
* Updates an item
*
- * @param PluginData $itemData
+ * @param PluginModel $itemData
*
* @return int
* @throws ConstraintException
@@ -88,7 +87,8 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa
SET `name` = ?,
`data` = ?,
enabled = ?,
- available = ?
+ available = ?,
+ versionLevel = ?
WHERE `name` = ? OR id = ? LIMIT 1';
$queryData = new QueryData();
@@ -98,6 +98,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa
$itemData->getData(),
$itemData->getEnabled(),
$itemData->getAvailable(),
+ $itemData->getVersionLevel(),
$itemData->getName(),
$itemData->getId()
]);
@@ -122,12 +123,13 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa
`name`,
`data`,
enabled,
- available
+ available,
+ versionLevel
FROM Plugin
WHERE id = ? LIMIT 1';
$queryData = new QueryData();
- $queryData->setMapClassName(PluginData::class);
+ $queryData->setMapClassName(PluginModel::class);
$queryData->setQuery($query);
$queryData->addParam($id);
@@ -147,12 +149,13 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa
'SELECT id,
`name`,
enabled,
- available
+ available,
+ versionLevel
FROM Plugin
ORDER BY `name`';
$queryData = new QueryData();
- $queryData->setMapClassName(PluginData::class);
+ $queryData->setMapClassName(PluginModel::class);
$queryData->setQuery($query);
return $this->db->doSelect($queryData);
@@ -177,13 +180,14 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa
'SELECT id,
`name`,
enabled,
- available
+ available,
+ versionLevel
FROM Plugin
WHERE id IN (' . $this->getParamsFromArray($ids) . ')
ORDER BY id';
$queryData = new QueryData();
- $queryData->setMapClassName(PluginData::class);
+ $queryData->setMapClassName(PluginModel::class);
$queryData->setQuery($query);
$queryData->setParams($ids);
@@ -282,8 +286,8 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa
public function search(ItemSearchData $itemSearchData)
{
$queryData = new QueryData();
- $queryData->setMapClassName(PluginData::class);
- $queryData->setSelect('id, name, enabled, available');
+ $queryData->setMapClassName(PluginModel::class);
+ $queryData->setSelect('id, name, enabled, available, versionLevel');
$queryData->setFrom('Plugin');
$queryData->setOrder('name');
@@ -318,12 +322,13 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa
`name`,
`data`,
enabled,
- available
+ available,
+ versionLevel
FROM Plugin
WHERE `name` = ? LIMIT 1';
$queryData = new QueryData();
- $queryData->setMapClassName(PluginData::class);
+ $queryData->setMapClassName(PluginModel::class);
$queryData->setQuery($query);
$queryData->addParam($name);
diff --git a/lib/SP/Services/Install/Installer.php b/lib/SP/Services/Install/Installer.php
index ec3f39a2..969b01dd 100644
--- a/lib/SP/Services/Install/Installer.php
+++ b/lib/SP/Services/Install/Installer.php
@@ -56,7 +56,7 @@ final class Installer extends Service
*/
const VERSION = [3, 0, 1];
const VERSION_TEXT = '3.0';
- const BUILD = 19012002;
+ const BUILD = 19012201;
/**
* @var DatabaseSetupInterface
diff --git a/lib/SP/Services/Plugin/PluginDataService.php b/lib/SP/Services/Plugin/PluginDataService.php
new file mode 100644
index 00000000..6c292063
--- /dev/null
+++ b/lib/SP/Services/Plugin/PluginDataService.php
@@ -0,0 +1,169 @@
+.
+ */
+
+namespace SP\Services\Plugin;
+
+use SP\Repositories\NoSuchItemException;
+use SP\Repositories\Plugin\PluginDataModel;
+use SP\Repositories\Plugin\PluginDataRepository;
+use SP\Services\Service;
+
+/**
+ * Class PluginDataService
+ *
+ * @package SP\Services\Plugin
+ */
+final class PluginDataService extends Service
+{
+ /**
+ * @var PluginDataRepository
+ */
+ protected $pluginRepository;
+
+ /**
+ * Creates an item
+ *
+ * @param PluginDataModel $itemData
+ *
+ * @return \SP\Storage\Database\QueryResult
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function create(PluginDataModel $itemData)
+ {
+ $itemData->setData(serialize($itemData->getData()));
+
+ return $this->pluginRepository->create($itemData);
+ }
+
+ /**
+ * Updates an item
+ *
+ * @param PluginDataModel $itemData
+ *
+ * @return int
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function update(PluginDataModel $itemData)
+ {
+ $itemData->setData(serialize($itemData->getData()));
+
+ return $this->pluginRepository->update($itemData);
+ }
+
+ /**
+ * Returns the item for given plugin and id
+ *
+ * @param string $name
+ * @param int $id
+ *
+ * @return PluginDataModel
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function getByItemId(string $name, int $id)
+ {
+ $result = $this->pluginRepository->getByItemId($name, $id);
+
+ if ($result->getNumRows() === 0) {
+ throw new NoSuchItemException(__u('Plugin\'s data not found'), NoSuchItemException::INFO);
+ }
+
+ return $result->getData();
+ }
+
+ /**
+ * Returns the item for given id
+ *
+ * @param int $id
+ *
+ * @return PluginDataModel[]
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws NoSuchItemException
+ */
+ public function getById($id)
+ {
+ $result = $this->pluginRepository->getById($id);
+
+ if ($result->getNumRows() === 0) {
+ throw new NoSuchItemException(__u('Plugin\'s data not found'), NoSuchItemException::INFO);
+ }
+
+ return $result->getDataAsArray();
+ }
+
+ /**
+ * Returns all the items
+ *
+ * @return PluginDataModel[]
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function getAll()
+ {
+ return $this->pluginRepository->getAll()->getDataAsArray();
+ }
+
+ /**
+ * Deletes an item
+ *
+ * @param $id
+ *
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function delete($id)
+ {
+ if ($this->pluginRepository->delete($id) === 0) {
+ throw new NoSuchItemException(__u('Plugin\'s data not found'), NoSuchItemException::INFO);
+ }
+ }
+
+ /**
+ * Deletes an item
+ *
+ * @param string $name
+ * @param int $itemId
+ *
+ * @return void
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function deleteByItemId(string $name, int $itemId)
+ {
+ if ($this->pluginRepository->deleteByItemId($name, $itemId) === 0) {
+ throw new NoSuchItemException(__u('Plugin\'s data not found'), NoSuchItemException::INFO);
+ }
+ }
+
+ protected function initialize()
+ {
+ $this->pluginRepository = $this->dic->get(PluginDataRepository::class);
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Services/Plugin/PluginService.php b/lib/SP/Services/Plugin/PluginService.php
index 8eaac480..c08e4af5 100644
--- a/lib/SP/Services/Plugin/PluginService.php
+++ b/lib/SP/Services/Plugin/PluginService.php
@@ -27,8 +27,8 @@ namespace SP\Services\Plugin;
use SP\Core\Exceptions\SPException;
use SP\DataModel\ItemData;
use SP\DataModel\ItemSearchData;
-use SP\DataModel\PluginData;
use SP\Repositories\NoSuchItemException;
+use SP\Repositories\Plugin\PluginModel;
use SP\Repositories\Plugin\PluginRepository;
use SP\Services\Service;
use SP\Services\ServiceException;
@@ -49,13 +49,13 @@ final class PluginService extends Service
/**
* Creates an item
*
- * @param PluginData $itemData
+ * @param \SP\Repositories\Plugin\PluginModel $itemData
*
* @return int
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
*/
- public function create(PluginData $itemData)
+ public function create(PluginModel $itemData)
{
return $this->pluginRepository->create($itemData)->getLastId();
}
@@ -63,13 +63,13 @@ final class PluginService extends Service
/**
* Updates an item
*
- * @param PluginData $itemData
+ * @param \SP\Repositories\Plugin\PluginModel $itemData
*
* @return mixed
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
*/
- public function update(PluginData $itemData)
+ public function update(PluginModel $itemData)
{
return $this->pluginRepository->update($itemData);
}
@@ -79,7 +79,7 @@ final class PluginService extends Service
*
* @param int $id
*
- * @return PluginData
+ * @return \SP\Repositories\Plugin\PluginModel
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
* @throws NoSuchItemException
@@ -98,7 +98,7 @@ final class PluginService extends Service
/**
* Returns all the items
*
- * @return PluginData[]
+ * @return PluginModel[]
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
*/
@@ -112,7 +112,7 @@ final class PluginService extends Service
*
* @param array $ids
*
- * @return PluginData[]
+ * @return \SP\Repositories\Plugin\PluginModel[]
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
*/
@@ -173,7 +173,7 @@ final class PluginService extends Service
*
* @param string $name
*
- * @return PluginData
+ * @return \SP\Repositories\Plugin\PluginModel
* @throws NoSuchItemException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
diff --git a/lib/SP/Services/Upgrade/UpgradeAppService.php b/lib/SP/Services/Upgrade/UpgradeAppService.php
index abf15c19..4de58960 100644
--- a/lib/SP/Services/Upgrade/UpgradeAppService.php
+++ b/lib/SP/Services/Upgrade/UpgradeAppService.php
@@ -38,7 +38,12 @@ use SP\Util\VersionUtil;
*/
final class UpgradeAppService extends Service implements UpgradeInterface
{
- const UPGRADES = ['300.18010101', '300.18072901', '300.18072902'];
+ const UPGRADES = [
+ '300.18010101',
+ '300.18072901',
+ '300.18072902',
+ '310.19012201'
+ ];
/**
* @param $version
@@ -55,8 +60,6 @@ final class UpgradeAppService extends Service implements UpgradeInterface
* @param ConfigData $configData
*
* @throws UpgradeException
- * @throws \DI\DependencyException
- * @throws \DI\NotFoundException
* @throws \SP\Storage\File\FileException
*/
public function upgrade($version, ConfigData $configData)
@@ -117,6 +120,10 @@ final class UpgradeAppService extends Service implements UpgradeInterface
$this->dic->get(UpgradeCustomFieldData::class)
->upgrade_300_18072902();
return true;
+ case '310.19012201':
+ $this->dic->get(UpgradePlugin::class)
+ ->upgrade_310_19012201();
+ return true;
}
} catch (\Exception $e) {
processException($e);
diff --git a/lib/SP/Services/Upgrade/UpgradePlugin.php b/lib/SP/Services/Upgrade/UpgradePlugin.php
new file mode 100644
index 00000000..67f94f32
--- /dev/null
+++ b/lib/SP/Services/Upgrade/UpgradePlugin.php
@@ -0,0 +1,61 @@
+.
+ */
+
+namespace SP\Services\Upgrade;
+
+use SP\Core\Events\Event;
+use SP\Core\Events\EventMessage;
+use SP\Plugin\PluginManager;
+use SP\Services\Service;
+
+/**
+ * Class UpgradePlugin
+ *
+ * @package SP\Services\Upgrade
+ */
+final class UpgradePlugin extends Service
+{
+ /**
+ * upgrade_300_18010101
+ *
+ * @throws \Exception
+ */
+ public function upgrade_310_19012201()
+ {
+ $this->eventDispatcher->notifyEvent('upgrade.plugin.start',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Plugins upgrade'))
+ ->addDescription(__FUNCTION__))
+ );
+
+ $this->dic->get(PluginManager::class)
+ ->upgradePlugins('310.19012201');
+
+ $this->eventDispatcher->notifyEvent('upgrade.plugin.end',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Plugins upgrade'))
+ ->addDescription(__FUNCTION__))
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Util/VersionUtil.php b/lib/SP/Util/VersionUtil.php
index 95fdf3b8..4bb7a236 100644
--- a/lib/SP/Util/VersionUtil.php
+++ b/lib/SP/Util/VersionUtil.php
@@ -44,12 +44,12 @@ final class VersionUtil
}
/**
- * Comprobar si una versión necesita actualización
+ * Compare versions
*
* @param string $currentVersion
* @param array|string $upgradeableVersion
*
- * @return bool True si la versión es menor.
+ * @return bool True if $currentVersion is lower than $upgradeableVersion
*/
public static function checkVersion($currentVersion, $upgradeableVersion)
{
diff --git a/schemas/30119012201.sql b/schemas/30119012201.sql
new file mode 100644
index 00000000..82781dec
--- /dev/null
+++ b/schemas/30119012201.sql
@@ -0,0 +1,16 @@
+DELIMITER $$
+
+alter table Plugin
+ add versionLevel varchar(15) null $$
+
+create table PluginData
+(
+ name varchar(100) not null,
+ itemId int null,
+ data blob not null,
+ constraint `PRIMARY`
+ primary key (name, itemId),
+ constraint fk_PluginData_name
+ foreign key (name) references Plugin (name)
+ on update cascade on delete cascade
+)$$
\ No newline at end of file
diff --git a/schemas/dbstructure.sql b/schemas/dbstructure.sql
index d178834a..50c6480e 100644
--- a/schemas/dbstructure.sql
+++ b/schemas/dbstructure.sql
@@ -417,11 +417,12 @@ DROP TABLE IF EXISTS `Plugin`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `Plugin` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(100) NOT NULL,
- `data` mediumblob DEFAULT NULL,
- `enabled` tinyint(1) NOT NULL DEFAULT 0,
- `available` tinyint(1) DEFAULT 0,
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(100) NOT NULL,
+ `data` mediumblob DEFAULT NULL,
+ `enabled` tinyint(1) NOT NULL DEFAULT 0,
+ `available` tinyint(1) DEFAULT 0,
+ `versionLevel` varchar(15) NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_Plugin_01` (`name`)
)
@@ -596,6 +597,24 @@ CREATE TABLE `UserToUserGroup` (
DEFAULT CHARSET = utf8
COLLATE utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
+DROP TABLE IF EXISTS `PluginData`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+create table PluginData
+(
+ name varchar(100) not null,
+ itemId int not null,
+ data blob not null,
+ primary key (name, itemId),
+ constraint fk_PluginData_name
+ foreign key (name) references Plugin (name)
+ on update cascade
+ on delete cascade
+)
+ ENGINE = InnoDB
+ DEFAULT CHARSET = utf8
+ COLLATE utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `account_data_v`;
/*!50001 DROP VIEW IF EXISTS `account_data_v`*/;
SET @saved_cs_client = @@character_set_client;
diff --git a/tests/SP/Repositories/PluginDataRepositoryTest.php b/tests/SP/Repositories/PluginDataRepositoryTest.php
new file mode 100644
index 00000000..c7a159df
--- /dev/null
+++ b/tests/SP/Repositories/PluginDataRepositoryTest.php
@@ -0,0 +1,270 @@
+.
+ */
+
+namespace SP\Tests\Repositories;
+
+use DI\DependencyException;
+use SP\Core\Exceptions\ConstraintException;
+use SP\Repositories\Plugin\PluginDataModel;
+use SP\Repositories\Plugin\PluginDataRepository;
+use SP\Storage\Database\DatabaseConnectionData;
+use SP\Tests\DatabaseTestCase;
+use function SP\Tests\setupContext;
+
+/**
+ * Class PluginDataRepositoryTest
+ *
+ * @package SP\Tests\Repositories
+ */
+class PluginDataRepositoryTest extends DatabaseTestCase
+{
+ /**
+ * @var PluginDataRepository
+ */
+ private static $repository;
+
+ /**
+ * @throws DependencyException
+ * @throws \DI\NotFoundException
+ * @throws \SP\Core\Context\ContextException
+ */
+ public static function setUpBeforeClass()
+ {
+ $dic = setupContext();
+
+ self::$dataset = 'syspass_plugin.xml';
+
+ // Datos de conexión a la BBDD
+ self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class);
+
+ // Inicializar el repositorio
+ self::$repository = $dic->get(PluginDataRepository::class);
+ }
+
+ /**
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testUpdate()
+ {
+ $data = new PluginDataModel();
+ $data->setItemId(1);
+ $data->setName('Authenticator');
+ $data->setData('data_updated');
+
+ $this->assertEquals(1, self::$repository->update($data));
+
+ $result = self::$repository->getByItemId($data->getName(), $data->getItemId());
+
+ $this->assertEquals(1, $result->getNumRows());
+ $this->assertEquals($data, $result->getData());
+
+ $data = new PluginDataModel();
+ $data->setItemId(0);
+ $data->setName('Authenticator');
+ $data->setData('data_updated');
+
+ $this->assertEquals(0, self::$repository->update($data));
+ }
+
+ /**
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testUpdateUnkown()
+ {
+ $data = new PluginDataModel();
+ $data->setItemId(2);
+ $data->setName('Test');
+ $data->setData('data');
+
+ $this->assertEquals(0, self::$repository->update($data));
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testGetAll()
+ {
+ $result = self::$repository->getAll();
+ /** @var PluginDataModel[] $data */
+ $data = $result->getDataAsArray();
+
+ $this->assertEquals(4, $result->getNumRows());
+ $this->assertCount(4, $data);
+ $this->assertEquals(1, $data[0]->getItemId());
+ $this->assertEquals('Authenticator', $data[0]->getName());
+ $this->assertEquals('data_item1', $data[0]->getData());
+
+ $this->assertEquals(2, $data[1]->getItemId());
+ $this->assertEquals(3, $data[2]->getItemId());
+ $this->assertEquals(2, $data[3]->getItemId());
+ }
+
+ /**
+ * @requires testGetById
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function testDelete()
+ {
+ $this->assertEquals(2, self::$repository->delete('Authenticator'));
+ $this->assertEquals(0, self::$repository->getById('Authenticator')->getNumRows());
+
+ $this->assertEquals(1, self::$repository->delete('DokuWiki'));
+ $this->assertEquals(0, self::$repository->getById('DokuWiki')->getNumRows());
+
+ $this->assertEquals(0, self::$repository->delete('Test'));
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testDeleteByItemId()
+ {
+ $this->assertEquals(1, self::$repository->deleteByItemId('Authenticator', 1));
+ $this->assertEquals(1, self::$repository->getById('Authenticator')->getNumRows());
+
+ $this->assertEquals(0, self::$repository->delete('Test'));
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testGetById()
+ {
+ $result = self::$repository->getById('Authenticator');
+ /** @var PluginDataModel[] $data */
+ $data = $result->getDataAsArray();
+
+ $this->assertEquals(2, $result->getNumRows());
+ $this->assertInstanceOf(PluginDataModel::class, $data[0]);
+ $this->assertEquals(1, $data[0]->getItemId());
+ $this->assertEquals('Authenticator', $data[0]->getName());
+ $this->assertEquals('data_item1', $data[0]->getData());
+
+ $this->assertInstanceOf(PluginDataModel::class, $data[1]);
+ $this->assertEquals(2, $data[1]->getItemId());
+ $this->assertEquals('Authenticator', $data[1]->getName());
+ $this->assertEquals('plugin_data', $data[1]->getData());
+
+ $this->assertEquals(1, self::$repository->getById('XML Exporter')->getNumRows());
+
+ $this->assertEquals(0, self::$repository->getById('Test')->getNumRows());
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testGetByItemId()
+ {
+ $result = self::$repository->getByItemId('Authenticator', 1);
+ /** @var PluginDataModel $data */
+ $data = $result->getData();
+
+ $this->assertEquals(1, $result->getNumRows());
+ $this->assertInstanceOf(PluginDataModel::class, $data);
+ $this->assertEquals(1, $data->getItemId());
+ $this->assertEquals('Authenticator', $data->getName());
+ $this->assertEquals('data_item1', $data->getData());
+
+ $this->assertEquals(0, self::$repository->getByItemId('Test', 1)->getNumRows());
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function testDeleteByIdBatch()
+ {
+ $this->assertEquals(3, self::$repository->deleteByIdBatch(['Authenticator', 'XML Exporter', 'Test']));
+ $this->assertEquals(0, self::$repository->deleteByIdBatch([]));
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testCreate()
+ {
+ $data = new PluginDataModel();
+ $data->setItemId(4);
+ $data->setName('Authenticator');
+ $data->setData('data');
+
+ self::$repository->create($data);
+
+ $result = self::$repository->getByItemId($data->getName(), $data->getItemId());
+
+ $this->assertEquals(1, $result->getNumRows());
+ $this->assertEquals($data, $result->getData());
+
+ $this->expectException(ConstraintException::class);
+
+ self::$repository->create($data);
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testCreateUnknown()
+ {
+ $this->expectException(ConstraintException::class);
+
+ $data = new PluginDataModel();
+ $data->setItemId(4);
+ $data->setName('Test');
+ $data->setData('data');
+
+ self::$repository->create($data);
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testGetByIdBatch()
+ {
+ $result = self::$repository->getByIdBatch(['Authenticator', 'XML Exporter', 'Test']);
+ /** @var \SP\Repositories\Plugin\PluginDataModel[] $data */
+ $data = $result->getDataAsArray();
+
+ $this->assertEquals(3, $result->getNumRows());
+ $this->assertCount(3, $data);
+ $this->assertEquals(1, $data[0]->getItemId());
+ $this->assertEquals(2, $data[1]->getItemId());
+ $this->assertEquals(2, $data[2]->getItemId());
+
+ $result = self::$repository->getByIdBatch([]);
+
+ $this->assertEquals(0, $result->getNumRows());
+ }
+}
diff --git a/tests/SP/Repositories/PluginRepositoryTest.php b/tests/SP/Repositories/PluginRepositoryTest.php
index 2351f022..c8376405 100644
--- a/tests/SP/Repositories/PluginRepositoryTest.php
+++ b/tests/SP/Repositories/PluginRepositoryTest.php
@@ -28,7 +28,7 @@ use DI\DependencyException;
use SP\Core\Exceptions\ConstraintException;
use SP\DataModel\ItemData;
use SP\DataModel\ItemSearchData;
-use SP\DataModel\PluginData;
+use SP\Repositories\Plugin\PluginModel;
use SP\Repositories\Plugin\PluginRepository;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
@@ -70,7 +70,7 @@ class PluginRepositoryTest extends DatabaseTestCase
*/
public function testUpdate()
{
- $data = new PluginData();
+ $data = new PluginModel();
$data->setId(1);
$data->setName('Authenticator 2');
$data->setAvailable(1);
@@ -104,7 +104,7 @@ class PluginRepositoryTest extends DatabaseTestCase
public function testGetAll()
{
$result = self::$repository->getAll();
- /** @var PluginData[] $data */
+ /** @var \SP\Repositories\Plugin\PluginModel[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(3, $result->getNumRows());
@@ -126,11 +126,11 @@ class PluginRepositoryTest extends DatabaseTestCase
public function testGetByName()
{
$result = self::$repository->getByName('Authenticator');
- /** @var PluginData $data */
+ /** @var \SP\Repositories\Plugin\PluginModel $data */
$data = $result->getData();
$this->assertEquals(1, $result->getNumRows());
- $this->assertInstanceOf(PluginData::class, $data);
+ $this->assertInstanceOf(PluginModel::class, $data);
$this->assertEquals(1, $data->getId());
$this->assertEquals('Authenticator', $data->getName());
$this->assertNull($data->getData());
@@ -148,7 +148,7 @@ class PluginRepositoryTest extends DatabaseTestCase
{
$this->assertEquals(1, self::$repository->toggleAvailableByName('Authenticator', 0));
- /** @var PluginData $data */
+ /** @var PluginModel $data */
$data = self::$repository->getByName('Authenticator')->getData();
$this->assertEquals(0, $data->getAvailable());
@@ -187,11 +187,11 @@ class PluginRepositoryTest extends DatabaseTestCase
public function testGetById()
{
$result = self::$repository->getById(1);
- /** @var PluginData $data */
+ /** @var \SP\Repositories\Plugin\PluginModel $data */
$data = $result->getData();
$this->assertEquals(1, $result->getNumRows());
- $this->assertInstanceOf(PluginData::class, $data);
+ $this->assertInstanceOf(PluginModel::class, $data);
$this->assertEquals(1, $data->getId());
$this->assertEquals('Authenticator', $data->getName());
$this->assertNull($data->getData());
@@ -238,7 +238,7 @@ class PluginRepositoryTest extends DatabaseTestCase
*/
public function testCreate()
{
- $data = new PluginData();
+ $data = new PluginModel();
$data->setId(4);
$data->setName('Authenticator 2');
$data->setAvailable(1);
@@ -266,7 +266,7 @@ class PluginRepositoryTest extends DatabaseTestCase
{
$this->expectException(ConstraintException::class);
- self::$repository->create(new PluginData());
+ self::$repository->create(new PluginModel());
}
/**
@@ -277,7 +277,7 @@ class PluginRepositoryTest extends DatabaseTestCase
{
$this->assertEquals(1, self::$repository->resetById(2));
- /** @var PluginData $data */
+ /** @var \SP\Repositories\Plugin\PluginModel $data */
$data = self::$repository->getById(2)->getData();
$this->assertNull($data->getData());
@@ -296,7 +296,7 @@ class PluginRepositoryTest extends DatabaseTestCase
$itemSearchData->setSeachString('Auth');
$result = self::$repository->search($itemSearchData);
- /** @var PluginData[] $data */
+ /** @var PluginModel[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(1, $result->getNumRows());
@@ -325,7 +325,7 @@ class PluginRepositoryTest extends DatabaseTestCase
{
$this->assertEquals(1, self::$repository->toggleEnabledByName('Authenticator', 1));
- /** @var PluginData $data */
+ /** @var \SP\Repositories\Plugin\PluginModel $data */
$data = self::$repository->getByName('Authenticator')->getData();
$this->assertEquals(1, $data->getEnabled());
@@ -341,7 +341,7 @@ class PluginRepositoryTest extends DatabaseTestCase
{
$this->assertEquals(1, self::$repository->toggleAvailable(1, 0));
- /** @var PluginData $data */
+ /** @var \SP\Repositories\Plugin\PluginModel $data */
$data = self::$repository->getByName('Authenticator')->getData();
$this->assertEquals(0, $data->getAvailable());
@@ -356,7 +356,7 @@ class PluginRepositoryTest extends DatabaseTestCase
public function testGetByIdBatch()
{
$result = self::$repository->getByIdBatch([1, 2, 4]);
- /** @var PluginData[] $data */
+ /** @var \SP\Repositories\Plugin\PluginModel[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(2, $result->getNumRows());
diff --git a/tests/SP/Services/Plugin/PluginDataServiceTest.php b/tests/SP/Services/Plugin/PluginDataServiceTest.php
new file mode 100644
index 00000000..e682b1f4
--- /dev/null
+++ b/tests/SP/Services/Plugin/PluginDataServiceTest.php
@@ -0,0 +1,271 @@
+.
+ */
+
+namespace SP\Tests\Services\Plugin;
+
+use SP\Core\Exceptions\ConstraintException;
+use SP\Repositories\NoSuchItemException;
+use SP\Repositories\Plugin\PluginDataModel;
+use SP\Services\Plugin\PluginDataService;
+use SP\Storage\Database\DatabaseConnectionData;
+use SP\Tests\DatabaseTestCase;
+use function SP\Tests\setupContext;
+
+/**
+ * Class PluginDataServiceTest
+ *
+ * @package SP\Tests\Services\Plugin
+ */
+class PluginDataServiceTest extends DatabaseTestCase
+{
+ /**
+ * @var PluginDataService
+ */
+ private static $service;
+
+ /**
+ * @throws \DI\NotFoundException
+ * @throws \SP\Core\Context\ContextException
+ * @throws \DI\DependencyException
+ */
+ public static function setUpBeforeClass()
+ {
+ $dic = setupContext();
+
+ self::$dataset = 'syspass_plugin.xml';
+
+ // Datos de conexión a la BBDD
+ self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class);
+
+ // Inicializar el servicio
+ self::$service = $dic->get(PluginDataService::class);
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testUpdate()
+ {
+ $data = new PluginDataModel();
+ $data->setItemId(1);
+ $data->setName('Authenticator');
+ $data->setData('data_updated');
+
+ $this->assertEquals(1, self::$service->update($data));
+
+ $this->assertEquals($data, self::$service->getByItemId($data->getName(), $data->getItemId()));
+
+ $data = new PluginDataModel();
+ $data->setItemId(0);
+ $data->setName('Authenticator');
+ $data->setData('data_updated');
+
+ $this->assertEquals(0, self::$service->update($data));
+ }
+
+ /**
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testUpdateUnkown()
+ {
+ $data = new PluginDataModel();
+ $data->setItemId(2);
+ $data->setName('Test');
+ $data->setData('data');
+
+ $this->assertEquals(0, self::$service->update($data));
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testGetAll()
+ {
+ $data = self::$service->getAll();
+
+ $this->assertCount(4, $data);
+ $this->assertEquals(1, $data[0]->getItemId());
+ $this->assertEquals('Authenticator', $data[0]->getName());
+ $this->assertEquals('data_item1', $data[0]->getData());
+
+ $this->assertEquals(2, $data[1]->getItemId());
+ $this->assertEquals(3, $data[2]->getItemId());
+ $this->assertEquals(2, $data[3]->getItemId());
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function testDelete()
+ {
+ self::$service->delete('Authenticator');
+
+ $this->assertTableRowCount('PluginData', 2);
+
+ self::$service->delete('DokuWiki');
+
+ $this->assertTableRowCount('PluginData', 1);
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function testDeleteUnkown()
+ {
+ $this->expectException(NoSuchItemException::class);
+
+ self::$service->delete('Test');
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testCreate()
+ {
+ $data = new PluginDataModel();
+ $data->setItemId(4);
+ $data->setName('Authenticator');
+ $data->setData('data');
+
+ self::$service->create($data);
+
+ $this->assertEquals($data, self::$service->getByItemId($data->getName(), $data->getItemId()));
+
+ $this->expectException(ConstraintException::class);
+
+ self::$service->create($data);
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testCreateUnknown()
+ {
+ $this->expectException(ConstraintException::class);
+
+ $data = new PluginDataModel();
+ $data->setItemId(4);
+ $data->setName('Test');
+ $data->setData('data');
+
+ self::$service->create($data);
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testGetByItemId()
+ {
+ $data = self::$service->getByItemId('Authenticator', 1);
+
+ $this->assertInstanceOf(PluginDataModel::class, $data);
+ $this->assertEquals(1, $data->getItemId());
+ $this->assertEquals('Authenticator', $data->getName());
+ $this->assertEquals('data_item1', $data->getData());
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testGetByItemIdUnkown()
+ {
+ $this->expectException(NoSuchItemException::class);
+
+ self::$service->getByItemId('Test', 1);
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testGetById()
+ {
+ $result = self::$service->getById('Authenticator');
+
+ $this->assertCount(2, $result);
+ $this->assertInstanceOf(PluginDataModel::class, $result[0]);
+ $this->assertEquals(1, $result[0]->getItemId());
+ $this->assertEquals('Authenticator', $result[0]->getName());
+ $this->assertEquals('data_item1', $result[0]->getData());
+
+ $this->assertInstanceOf(PluginDataModel::class, $result[1]);
+ $this->assertEquals(2, $result[1]->getItemId());
+ $this->assertEquals('Authenticator', $result[1]->getName());
+ $this->assertEquals('plugin_data', $result[1]->getData());
+
+ $this->assertCount(1, self::$service->getById('XML Exporter'));
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testGetByIdUnkown()
+ {
+ $this->expectException(NoSuchItemException::class);
+
+ self::$service->getById('Test');
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testDeleteByItemId()
+ {
+ self::$service->deleteByItemId('Authenticator', 1);
+
+ $this->assertCount(1, self::$service->getById('Authenticator'));
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws NoSuchItemException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testDeleteByItemIdUnkown()
+ {
+ $this->expectException(NoSuchItemException::class);
+
+ self::$service->deleteByItemId('Test', 1);
+ }
+}
diff --git a/tests/SP/Services/Plugin/PluginServiceTest.php b/tests/SP/Services/Plugin/PluginServiceTest.php
index a75998be..86da6e75 100644
--- a/tests/SP/Services/Plugin/PluginServiceTest.php
+++ b/tests/SP/Services/Plugin/PluginServiceTest.php
@@ -27,8 +27,8 @@ namespace SP\Tests\Services\Plugin;
use SP\Core\Exceptions\ConstraintException;
use SP\DataModel\ItemData;
use SP\DataModel\ItemSearchData;
-use SP\DataModel\PluginData;
use SP\Repositories\NoSuchItemException;
+use SP\Repositories\Plugin\PluginModel;
use SP\Services\Plugin\PluginService;
use SP\Services\ServiceException;
use SP\Storage\Database\DatabaseConnectionData;
@@ -72,7 +72,7 @@ class PluginServiceTest extends DatabaseTestCase
*/
public function testUpdate()
{
- $data = new PluginData();
+ $data = new PluginModel();
$data->setId(1);
$data->setName('Authenticator 2');
$data->setAvailable(1);
@@ -159,7 +159,7 @@ class PluginServiceTest extends DatabaseTestCase
{
$data = self::$service->getByName('Authenticator');
- $this->assertInstanceOf(PluginData::class, $data);
+ $this->assertInstanceOf(PluginModel::class, $data);
$this->assertEquals(1, $data->getId());
$this->assertEquals('Authenticator', $data->getName());
$this->assertNull($data->getData());
@@ -201,7 +201,7 @@ class PluginServiceTest extends DatabaseTestCase
$this->assertEquals(1, $result->getNumRows());
- /** @var PluginData[] $data */
+ /** @var PluginModel[] $data */
$data = $result->getDataAsArray();
$this->assertCount(1, $data);
@@ -230,7 +230,7 @@ class PluginServiceTest extends DatabaseTestCase
{
$data = self::$service->getById(1);
- $this->assertInstanceOf(PluginData::class, $data);
+ $this->assertInstanceOf(PluginModel::class, $data);
$this->assertEquals(1, $data->getId());
$this->assertEquals('Authenticator', $data->getName());
$this->assertNull($data->getData());
@@ -249,7 +249,7 @@ class PluginServiceTest extends DatabaseTestCase
*/
public function testCreate()
{
- $data = new PluginData();
+ $data = new PluginModel();
$data->setId(4);
$data->setName('Authenticator 2');
$data->setAvailable(1);
@@ -273,7 +273,7 @@ class PluginServiceTest extends DatabaseTestCase
{
$this->expectException(ConstraintException::class);
- self::$service->create(new PluginData());
+ self::$service->create(new PluginModel());
}
/**
diff --git a/tests/res/datasets/syspass_plugin.xml b/tests/res/datasets/syspass_plugin.xml
index 1e57c34f..96bc20e1 100644
--- a/tests/res/datasets/syspass_plugin.xml
+++ b/tests/res/datasets/syspass_plugin.xml
@@ -24,5 +24,27 @@
0
+
+
+ 1
+ Authenticator
+ data_item1
+
+
+ 2
+ Authenticator
+ plugin_data
+
+
+ 2
+ XML Exporter
+ data
+
+
+ 3
+ DokuWiki
+ data_item3
+
+
diff --git a/tests/res/scripts/db.sql b/tests/res/scripts/db.sql
new file mode 100644
index 00000000..a410454d
--- /dev/null
+++ b/tests/res/scripts/db.sql
@@ -0,0 +1,127 @@
+-- MySQL dump 10.16 Distrib 10.1.26-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: syspass
+-- ------------------------------------------------------
+-- Server version 10.2.17-MariaDB-1:10.2.17+maria~bionic
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+/*!40000 ALTER TABLE `Account` DISABLE KEYS */;
+INSERT INTO `Account` VALUES (1,1,1,1,3,'Amazon SES',2,'admin','https://aws.amazon.com/','def502008fde3a27bb1a6023f1b4ec524ba147c80ae78f90f9b3d0637af6809ad9263afaa36d34237ded5e8803b53f17121bd5e2a66919c0ce21d27c9360dfbc39d8151df9cbb4aadd1a0daa83ff59181ce1f1535c4b93d2701fa72c662115e919','def10000def502002937bbb81177ff4f769aeae126108783a141170588f3482fcbab44ae3390e80f85ab38521bafa8ec19648d267c9d46062294f5068a16706dcdb9042ddbb5b23ef54b3a12e7c5723b15d32ab9d8f5559e1fbc658c0b547a2a88a34b2498ef934d55395f857f28c9e3314493f319ebd4140d4a1b968e678cc12b58b5d2d057530be80f5f58c592cedcd85a90529d0895b11d6c04768bfbf4f1527babf5ee563798d35886f1c1017d1a3221cfd317cb84b13302d7d71c33e6753bcdb913dacd8909e195387f47b136a2789f85c48c3600f4ac6433a26e2bd0cae74fa2c461e4495108d340d7120febc65cfe79a4e2acc046f9bac29a0ce35cda','Simple Email Service',8,1,'2018-08-25 20:12:20','2018-08-25 20:16:11',0,0,0,0,1535227940,0,0);
+INSERT INTO `Account` VALUES (2,1,1,1,1,'Google GCP',1,'admin','https://cloud.google.com/','def50200894e22b540a4975a3efe7dae669760aa6337195c690ac79ebff28f03393ae1070c5c7a635fa5a9aee5059df912c1948c41d8198f24f9f892a728d400d12d200c184a793d03a3f13eebfa45614efd0004ad7ea83338d1a04e20e6846078','def10000def50200f3d572936f4496e90369f6cc1feadce57c803b01a78c64b5987efd6369f7ecf526494a148d0e056feafe60d903bbb65ea9f79ad9b4f7ad42c7fe3c9c586f1807d252444c42667129da3727cf6f702a5aadf5db2391ba4a581f950df65262ae04b314b88d69d3174e6f226cb1f939f04d102799e58e0b6ed839fe2282056c58069e6298865c386e3d2114635621ed14eb199b1dad6dfcabc9b364ea2ae147c38352cd72bc0c79761a9df0f58690d5da1d1e3cc5e17261d740ca6863383a869b0253790d46ba2df032e741e8bb788033d8eb7b97d124d58b3c4310d15df7a4fd4d373dcc0ae111d46f6d623bac7ccf330520439736b223ae81','Google Cloud',2,0,'2018-08-25 20:15:02',NULL,0,0,0,0,1535228102,0,0);
+/*!40000 ALTER TABLE `Account` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `AccountToTag` DISABLE KEYS */;
+INSERT INTO `AccountToTag` VALUES (1,6);
+INSERT INTO `AccountToTag` VALUES (2,3);
+/*!40000 ALTER TABLE `AccountToTag` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `AuthToken` DISABLE KEYS */;
+INSERT INTO `AuthToken` VALUES (1,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',2,1,1535228249,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (2,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',3,1,1535228254,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (3,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',7,1,1535228286,'O:19:\"SP\\Core\\Crypt\\Vault\":4:{s:25:\"\0SP\\Core\\Crypt\\Vault\0data\";s:190:\"def502005c9146e03665d0ecf8002f292580e91a5f20937e40414411038651ef6b5842a824c391b64ce1ef5781093302f0c64b574c4486faac0f7b4413a007e85f17e558e39482b470d971716d0b1ea50350c8c6128e37126e6f2b3e89a987\";s:24:\"\0SP\\Core\\Crypt\\Vault\0key\";s:512:\"def10000def50200dc68c3693660b0af530e6bfaaba9692b76459362b31b2c90106534a63ae6a193602de76b37de0d638c4aef7c9db0ff25e21a457fff326a1dc28c84d070b5df66f265779425b3e252b185342f7f0d9a0c977d4954860beabd1ff1f923f021b3dd19e0287d4be4051e43a6deae227e4f1475215db32b18d132aef7bf9d637c3f32ef39dd811e2fe28366a8ccb00f20fbe3b4d99ae7bbbbf170491a0275e9687ad53e511b2a3d3db32707105c24b64a3a931a3371aeb923234fa2814c3cef3785347024de8e337941812d8a1d5d48119052846cda8e280ff47d203f42d0954e446bd5dba77eef7889c5587605e74d439e21925603b24d15eea0\";s:28:\"\0SP\\Core\\Crypt\\Vault\0timeSet\";i:1535228286;s:32:\"\0SP\\Core\\Crypt\\Vault\0timeUpdated\";i:0;}','$2y$10$.uXTzsk75gEhgZXZJZML8O7au2HrMKY.WNhK3wN6RMe5ZaI2ZN2pG');
+INSERT INTO `AuthToken` VALUES (4,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',6,1,1535228293,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (5,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',4,1,1535228308,'O:19:\"SP\\Core\\Crypt\\Vault\":4:{s:25:\"\0SP\\Core\\Crypt\\Vault\0data\";s:190:\"def502001e44aef74b0e1ef844e0b4924e623e7b272826530cb4694388798bb5238a6f14bbcac2539697245ace4474e573fb39019576c1350c21d3bc141ae93b217c2722247ee431b04e2548cad4578a7de45c2877801500a045a395158192\";s:24:\"\0SP\\Core\\Crypt\\Vault\0key\";s:512:\"def10000def50200cf06fdb73f2529aff306eb7240631ef49a7455322b1030225aca3e6f46663b095d9097a5dca9eda13b9264db60cad8006ca1dcbc006f2c4beecca1d5859aca01ccd102c617aaee43e56c7e87071ddcb655d8c80478af75add7f0fff0acaf0970a96d4dca056c8e5f69a7fcfe1835c1b88ffb02072efb0b71de0ad28ddafe998e20f3370b71f868502457d29ea3a38498f04f4a6642a3420b45ac18acbabc3d8f673392b75eaeeac04bfc9e592967fec7804b1c23a5a8e1783139e530ef548207db1ad348e22122ad06d15caa45e4b14a89427f09822ad89d2d96fc2261e9857825f2b2cb02de74f6b16b981d83928ba8ea0affa8c3f26193\";s:28:\"\0SP\\Core\\Crypt\\Vault\0timeSet\";i:1535228308;s:32:\"\0SP\\Core\\Crypt\\Vault\0timeUpdated\";i:0;}','$2y$10$/myArYtpc/jfmO3AHEMe2uDrN7zwjGJk1fAcmXbZ.wcbyVwlunqjS');
+INSERT INTO `AuthToken` VALUES (6,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',102,1,1535228316,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (7,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',302,1,1535228368,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (8,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',202,1,1535228374,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (9,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',1541,1,1535228393,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (10,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',1561,1,1535228398,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (11,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',103,1,1535321537,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (12,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',104,1,1535321543,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (13,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',105,1,1535321552,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (14,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',106,1,1535321560,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (15,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',303,1,1535321568,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (16,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',304,1,1535321575,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (17,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',305,1,1535321580,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (18,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',306,1,1535321589,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (19,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',203,1,1535321594,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (20,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',204,1,1535321602,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (21,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',205,1,1535321608,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (22,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',206,1,1535321615,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (24,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',8,1,1535374384,'O:19:\"SP\\Core\\Crypt\\Vault\":4:{s:25:\"\0SP\\Core\\Crypt\\Vault\0data\";s:190:\"def50200d38515bf8e89df08a81876eba6d8522b86186bbea8b853a12cfe5226c674dbe5623d2f1b04b0accd39320fbc7d1a979caeb044c3664bf03eb00418798c35f9e5db87d97422d82f17726b0e57a9ff826e15e5ef94c2435d5ac5fb04\";s:24:\"\0SP\\Core\\Crypt\\Vault\0key\";s:512:\"def10000def5020049ec25f46b3d280f816e755f49fd3afccd74eba8a8d502fc15890212fbb240a4a8ca4d4758e2eaa0acff7ceea40f05e3af2cd898a8c2a64f44c839fc730ca2bfb38cd42611a3ff6d2b509112a57858c9c8613d1843d8224fba14ed940f4498759bfe8403f4f3c3cfe7d4f620f34bf11d7921714cc30d68937d685473f0d331cefd02e3f5a67d9dbaa52c9be66b0f291d776f13b9a1386e15fe61e3c91b3db06235ac76b9a1b5e8026262fe5150d398c969e1cf4112ef4925c88642cfaa52bf7daf0d8a0f90ef568adb549f868cf49280d13c2ad7e15e4acb0bf7e0d28627488d287e3817055e7e3e51cf9540ec2fb02a3c89afd20996a74f\";s:28:\"\0SP\\Core\\Crypt\\Vault\0timeSet\";i:1535374383;s:32:\"\0SP\\Core\\Crypt\\Vault\0timeUpdated\";i:0;}','$2y$10$vVrDPoi6wflaYzQIMuhVpeqtEvMN.4xwOAzLbxTZIw6gCP3kGTELG');
+INSERT INTO `AuthToken` VALUES (25,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',5,1,1535407845,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (26,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',803,1,1538818218,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (27,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',804,1,1538818227,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (28,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',805,1,1538818235,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (29,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',802,1,1538818243,NULL,NULL);
+INSERT INTO `AuthToken` VALUES (30,1,'4eb7a989fab4c8fd9ade0ea80df7032d5ee78d4496c1c10f9c4388a872bfff28',806,1,1538818294,NULL,NULL);
+/*!40000 ALTER TABLE `AuthToken` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `Category` DISABLE KEYS */;
+INSERT INTO `Category` VALUES (1,'GCP','','50f66ecbc45488ee5826941bfbc50411');
+INSERT INTO `Category` VALUES (2,'AWS','','ac68bbf921d953d1cfab916cb6120864');
+INSERT INTO `Category` VALUES (3,'SSH','','1787d7646304c5d987cf4e64a3973dc7');
+INSERT INTO `Category` VALUES (4,'Web','','2567a5ec9705eb7ac2c984033e06189d');
+/*!40000 ALTER TABLE `Category` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `Client` DISABLE KEYS */;
+INSERT INTO `Client` VALUES (1,'Google','c822c1b63853ed273b89687ac505f9fa','',0);
+INSERT INTO `Client` VALUES (2,'Apple','1f3870be274f6c49b3e31a0c6728957f','',0);
+INSERT INTO `Client` VALUES (3,'Amazon','2d0d4809e6bdb6f4db3e547f27b1873c','',0);
+/*!40000 ALTER TABLE `Client` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `Config` DISABLE KEYS */;
+INSERT INTO `Config` VALUES ('config_backup','789c955851739b3810ee6fe1ed1e72231060204f4e9ca4bde61a4f713279b8998c8484ad31461441e33493ff7e1260179348d017db32df27ad56bbfbadb88b1c1059f1f2bf4b9ea76cdd7d2d5085ac2808a357114127b23e7d04f85417eb1211fa95be58e72292d3a82f38d3c109dfd6cf6ccbae7284334aac73160145806384fb32fba30524fe0209dae7b8a31c41cb3f222c91107d423846f8867654142839b12bd0b132828a054d519d553725af8b1ec9051348cb92a72c9be683a2e4fb97c9a7d2a0635afe3c75986dc42f7959a9a903108071f4f03046e61e9c84d6a7458d33966fc5bf68ffc0e8b35006416344f5182bb6a38ae003308932f4a7d6fb2849789d5797ea43a16dc7e8fe0e7e2bd768d0c6b9930d4db6f705411595bbc5239634e89c572ce9a1b5d99f343f3f23b13904254e6d9bba0e4689eda1104027012981c4a58e0bc12cc1be7c96ca870aef684f89e0cf5c540a637b91255e64ce087146f099dc43f337d4c63fc1314fb6b4ea4583691d95910a333b2e33c638849aed4796fde8ff857fbcfd02d9d5c5e6ad2cc7b887a0565c513c7938b0b1ed139f02188eaedba50f84c057507d09a4b85e1fcf4e5f59e98e0f0354bbbcaa23629e65fc9992ab7d251d8022db8d5e3b5e642d17d7c7508cac7f96376ae4b4a39b2fd7c73493c86fcd33b71ddd2d566ae41d4671935fed687177a94633155acde8b1291fedc3c7db061a76a3f8b659beb3e6215e34c3ce9cd5e3ea775645d665fcd00c3b832ee65fadf3b7a9bb8fd92fda2ee5b8c64c6a483d079bb3749d718cb298a232d91cd1da9ac77251a1ac3fb1510f262b6103663999ac8407c2b0fe7a26c2f2a3faae8d53c518c4a9a3155a059e13710c68ad07157028aafa3aa7d0efe5cee815b53f5455e5b4f9f9fab8453c72f60afb93e66d0e82e8f5cda4443bc4b2795d6de8546557846155d0c696025f977cd7dfa3113c0c1333b82b788e2a0eaed61f0afa9dfea8a5324c175c458a695297ac7a9974422d61180146fb8711ee9b7790b082b5c73ad19c43144cc82109cf2b1903b9ea3cc75a002582cfbc2431ca1a15f5e5f4c40b3c1b040e82a1ed22df9d21087d12843690c24ea5aae3200de43d20755ce2cca0130217504c00715ba9d76fbea442b6aa622e2e51d94b5c2d5e502118cf552bc6eb263e42608e52c12a7a8bf2b5b243d6259a3fddc7e6965231561bda7606b6f4ea4e364f2543d919ce6a6a2e706d4bf4404b6565c397870801f8db967dafe3007be4fe223fb02cd76313688ffaa3db95368c14f89a65d5c452dcde79d6b43ebd8c697da1f0ada40d18230da5fcd96aac073de8037fa634dfd5920eedf6979db46df21d46b6a8dbba78daf49a5719be08433243204cb08c668fa85e35f453cff6430753884892a60e357b89ee0b59b94e26060e2558f20124d0b37100210dc3591822dbc39e8f027f066422616c96954d5515a2a713c0e87cd9ce9eca0a3096d116fe5d3685d53b1f6a2d6a49efeba2f6a85ac2a1b27bb67b6ebacb76f71ca51a2bde9ceef8b1b61114a3ce22e91e44762c3717219a27e54b51c56d6d393a6becbe765d6759d344cc13795d12e36d3492522c9b31960cd4ded5d6832343aa38bfe56b960f1b8571ea82abfa3fe9f58910fcf48d43b7236dc3f59b707cdbd052f4e9da39ef6a5fb0f25da869173a611d2ee236807e0064fd7ffb1fe0f40600');
+INSERT INTO `Config` VALUES ('config_backup_date','1535363117');
+INSERT INTO `Config` VALUES ('lastupdatempass','1535226221');
+INSERT INTO `Config` VALUES ('masterPwd','$2y$10$Aiht18h7jXSj6U.S6tCkreAFvlUq./F84TeCtyN4oSWVHQc9vjosO');
+INSERT INTO `Config` VALUES ('version','300.18082201');
+/*!40000 ALTER TABLE `Config` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `EventLog` DISABLE KEYS */;
+INSERT INTO `EventLog` VALUES (1,1538818164,'admin',1,'172.17.0.1','show.itemlist.security',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (2,1538818174,'admin',1,'172.17.0.1','show.itemlist.items',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (3,1538818177,'admin',1,'172.17.0.1','show.itemlist.accesses',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (4,1538818194,'admin',1,'172.17.0.1','show.authToken.create',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (5,1538818218,'admin',1,'172.17.0.1','show.itemlist.accesses',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (6,1538818219,'admin',1,'172.17.0.1','show.authToken.create',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (7,1538818227,'admin',1,'172.17.0.1','show.itemlist.accesses',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (8,1538818228,'admin',1,'172.17.0.1','show.authToken.create',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (9,1538818235,'admin',1,'172.17.0.1','show.itemlist.accesses',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (10,1538818236,'admin',1,'172.17.0.1','show.authToken.create',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (11,1538818243,'admin',1,'172.17.0.1','show.itemlist.accesses',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (12,1538818288,'admin',1,'172.17.0.1','show.authToken.create',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (13,1538818294,'admin',1,'172.17.0.1','show.itemlist.accesses',NULL,'INFO');
+INSERT INTO `EventLog` VALUES (14,1538818303,'admin',1,'172.17.0.1','show.account.search',NULL,'INFO');
+/*!40000 ALTER TABLE `EventLog` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `Tag` DISABLE KEYS */;
+INSERT INTO `Tag` VALUES (1,'SSH','1787d7646304c5d987cf4e64a3973dc7');
+INSERT INTO `Tag` VALUES (2,'JBoss','9764dc122be894c72f6314703587f596');
+INSERT INTO `Tag` VALUES (3,'SaaS','593be52a46f869eea8b31d146d21de7a');
+INSERT INTO `Tag` VALUES (4,'Apache','b6efd606d118d0f62066e31419ff04cc');
+INSERT INTO `Tag` VALUES (5,'Tomcat','1b359d8753858b55befa0441067aaed3');
+INSERT INTO `Tag` VALUES (6,'Email','0c83f57c786a0b4a39efab23731c7ebc');
+/*!40000 ALTER TABLE `Tag` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `User` DISABLE KEYS */;
+INSERT INTO `User` VALUES (1,'sysPass Admin',1,'admin',NULL,'$2y$10$YL0plKONrjT8ayrACgLZW.ZYytyz/Tm/6r5wLpLYSkl44niUHYvt6','def502003379170b312867d6c8e8b792773d912b9acb828728fb2b7b61fc3b98cac8dfd71073b44253c9eb2dc1ee68609d80bad2e00f78972eaf1fc98c38b88e85147709446027f1bddeec14c7e78983ac5e1aa52f2445cc84a824d16efbac','def10000def502003d5898af299ffc237380f5666737d8eb32e2be39e82c5116351047905c14b1f21c8e2f546865c4af7832fc83163dad672d85e00f64ddbee91ec9155eea15070966af390e1085addaef88c207f9d76cfd725f11784a3b62b816d51901ba74293837b68560d1db995aaee0ed4bf3e50c747023d544fdff78ef3b1294d8e788b30568a7b8e5a63ae7dfd83f1340e7e97428c1d8e1a6219610adc330e58d5d989524a6bd6d86e909153e733d2f08ab41d36e6892a9780b6a3f68b5942480c27b4f90fdf445ed711f736284d5285555a54b9c578292b140b741f3da1039e69997f7dc193cc536f033bab5778f8147925b161a43e83ae68b821587',NULL,NULL,24,1,'2018-08-27 12:45:05',NULL,1535226222,1,0,0,0,'',0,0,0,NULL);
+/*!40000 ALTER TABLE `User` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `UserGroup` DISABLE KEYS */;
+INSERT INTO `UserGroup` VALUES (1,'Admins','sysPass Admins');
+/*!40000 ALTER TABLE `UserGroup` ENABLE KEYS */;
+
+/*!40000 ALTER TABLE `UserProfile` DISABLE KEYS */;
+INSERT INTO `UserProfile` VALUES (1,'Admin','O:24:\"SP\\DataModel\\ProfileData\":29:{s:10:\"\0*\0accView\";b:0;s:14:\"\0*\0accViewPass\";b:0;s:17:\"\0*\0accViewHistory\";b:0;s:10:\"\0*\0accEdit\";b:0;s:14:\"\0*\0accEditPass\";b:0;s:9:\"\0*\0accAdd\";b:0;s:12:\"\0*\0accDelete\";b:0;s:11:\"\0*\0accFiles\";b:0;s:13:\"\0*\0accPrivate\";b:0;s:18:\"\0*\0accPrivateGroup\";b:0;s:16:\"\0*\0accPermission\";b:0;s:17:\"\0*\0accPublicLinks\";b:0;s:18:\"\0*\0accGlobalSearch\";b:0;s:16:\"\0*\0configGeneral\";b:0;s:19:\"\0*\0configEncryption\";b:0;s:15:\"\0*\0configBackup\";b:0;s:15:\"\0*\0configImport\";b:0;s:11:\"\0*\0mgmUsers\";b:0;s:12:\"\0*\0mgmGroups\";b:0;s:14:\"\0*\0mgmProfiles\";b:0;s:16:\"\0*\0mgmCategories\";b:0;s:15:\"\0*\0mgmCustomers\";b:0;s:15:\"\0*\0mgmApiTokens\";b:0;s:17:\"\0*\0mgmPublicLinks\";b:0;s:14:\"\0*\0mgmAccounts\";b:0;s:10:\"\0*\0mgmTags\";b:0;s:11:\"\0*\0mgmFiles\";b:0;s:6:\"\0*\0evl\";b:0;s:18:\"\0*\0mgmCustomFields\";b:0;}');
+/*!40000 ALTER TABLE `UserProfile` ENABLE KEYS */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2018-10-06 11:36:16
diff --git a/tests/res/scripts/dump_to_xml.sh b/tests/res/scripts/dump_to_xml.sh
new file mode 100755
index 00000000..472af506
--- /dev/null
+++ b/tests/res/scripts/dump_to_xml.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+DB_HOST=$(docker inspect syspass-db-test --format {{.NetworkSettings.Networks.bridge.IPAddress}})
+
+if [ -z "${DB_HOST}" ]; then
+ echo "Unknown host"
+ exit 1
+fi
+
+DB_TABLE=$1
+DUMP_PATH=$2
+
+if [ -z ${DB_TABLE} ]; then
+ echo "Table not set"
+ exit 1
+fi
+
+if [ -z ${DUMP_PATH} ]; then
+ echo "Dump path not set"
+ exit 1
+fi
+
+mysqldump --hex-blob -t -u root --password=syspass-test --host=${DB_HOST} --xml syspass-test `echo "${DB_TABLE^}"` >> ${DUMP_PATH}/syspass_${DB_TABLE}.xml
diff --git a/tests/res/scripts/reset_db.sh b/tests/res/scripts/reset_db.sh
new file mode 100755
index 00000000..df0c9623
--- /dev/null
+++ b/tests/res/scripts/reset_db.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+DB_HOST=$(docker inspect syspass-db-test --format {{.NetworkSettings.Networks.bridge.IPAddress}})
+
+if [[ -z "${DB_HOST}" ]]; then
+ echo "Unknown host"
+ exit 1
+fi
+
+SQL_FILE=$1
+DB_NAME=$2
+PROJECT_DIR=$3
+
+if [[ ! -e "${SQL_FILE}" ]]; then
+ echo "SQL file does not exist: ${SQL_FILE}"
+ exit 1
+fi
+
+echo "Database host: ${DB_HOST}"
+echo "Database name: ${DB_NAME}"
+
+case ${DB_NAME} in
+ "syspass")
+ mysql -h ${DB_HOST} -u root -psyspass ${DB_NAME} < ${PROJECT_DIR}/schemas/dbstructure.sql
+ mysql -h ${DB_HOST} -u root -psyspass ${DB_NAME} < ${SQL_FILE}
+ ;;
+ "syspass-test")
+ mysql -h ${DB_HOST} -u root -psyspass -e 'DROP DATABASE IF EXISTS `'"${DB_NAME}"'`;'
+ mysql -h ${DB_HOST} -u root -psyspass -e 'CREATE DATABASE `'"${DB_NAME}"'` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;'
+ mysql -h ${DB_HOST} -u root -psyspass ${DB_NAME} < ${SQL_FILE}
+ ;;
+ *)
+ echo "Database name not set"
+ exit 1
+ ;;
+esac
+
+if [[ $? -eq 0 ]]; then
+ echo "Database data imported"
+fi
\ No newline at end of file