chore(tests): UT for UpgradeConfig service

Signed-off-by: Rubén D <nuxsmin@syspass.org>
This commit is contained in:
Rubén D
2024-01-15 18:05:20 +01:00
parent 78de6f9607
commit 49805d6b27
21 changed files with 510 additions and 497 deletions

View File

@@ -43,7 +43,7 @@ use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Core\Exceptions\SPException;
use SP\Domain\Core\File\MimeType;
use SP\Domain\Core\File\MimeTypesInterface;
use SP\Domain\Core\File\MimeTypesService;
use SP\Domain\Crypt\Services\TemporaryMasterPassService;
use SP\Domain\Export\Services\BackupFiles;
use SP\Domain\Export\Services\XmlExportService;
@@ -77,8 +77,8 @@ final class IndexController extends ControllerBase
private UserServiceInterface $userService;
private UserGroupServiceInterface $userGroupService;
private UserProfileServiceInterface $userProfileService;
private MimeTypesInterface $mimeTypes;
private DatabaseUtil $databaseUtil;
private MimeTypesService $mimeTypes;
private DatabaseUtil $databaseUtil;
private ConfigService $configService;
private AccountServiceInterface $accountService;
private PluginManager $pluginManager;
@@ -90,9 +90,9 @@ final class IndexController extends ControllerBase
UserServiceInterface $userService,
UserGroupServiceInterface $userGroupService,
UserProfileServiceInterface $userProfileService,
MimeTypesInterface $mimeTypes,
MimeTypesService $mimeTypes,
DatabaseUtil $databaseUtil,
ConfigService $configService,
ConfigService $configService,
AccountServiceInterface $accountService,
PluginManager $pluginManager
) {

View File

@@ -29,7 +29,7 @@ use JsonException;
use SP\Core\Application;
use SP\Domain\Core\Exceptions\SPException;
use SP\Domain\Core\Exceptions\ValidationException;
use SP\Domain\Persistence\Ports\UpgradeDatabaseServiceInterface;
use SP\Domain\Persistence\Ports\UpgradeDatabaseService;
use SP\Domain\Upgrade\Services\UpgradeAppService;
use SP\Domain\Upgrade\Services\UpgradeDatabaseService;
use SP\Domain\Upgrade\Services\UpgradeException;
@@ -48,14 +48,14 @@ final class UpgradeController extends ControllerBase
{
use JsonTrait;
private UpgradeDatabaseServiceInterface $upgradeDatabaseService;
private UpgradeAppService $upgradeAppService;
private UpgradeDatabaseService $upgradeDatabaseService;
private UpgradeAppService $upgradeAppService;
public function __construct(
Application $application,
WebControllerHelper $webControllerHelper,
UpgradeDatabaseServiceInterface $upgradeDatabaseService,
UpgradeAppService $upgradeAppService
Application $application,
WebControllerHelper $webControllerHelper,
UpgradeDatabaseService $upgradeDatabaseService,
UpgradeAppService $upgradeAppService
) {
parent::__construct($application, $webControllerHelper);

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -47,6 +47,7 @@ use SP\Domain\Core\Exceptions\InitializationException;
use SP\Domain\Core\Exceptions\SPException;
use SP\Domain\Http\RequestInterface;
use SP\Domain\Upgrade\Services\UpgradeException;
use SP\Infrastructure\File\FileException;
use SP\Plugin\PluginManager;
use SP\Util\Checks;
use Symfony\Component\Debug\Debug;
@@ -286,7 +287,7 @@ abstract class BootstrapBase implements BootstrapInterface
* Cargar la configuración
*
* @throws ConfigException
* @throws UpgradeException
* @throws FileException
*/
private function initConfig(): void
{

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -26,21 +26,20 @@ namespace SP\Core\Bootstrap;
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\Config\Ports\UpgradeConfigServiceInterface;
use SP\Domain\Config\Services\UpgradeConfigService;
use SP\Domain\Upgrade\Services\UpgradeException;
use SP\Domain\Config\Ports\UpgradeConfigService;
use SP\Domain\Config\Services\UpgradeConfig;
use SP\Domain\Upgrade\Services\UpgradeUtil;
use SP\Util\VersionUtil;
use SP\Infrastructure\File\FileException;
/**
* Upgrade the config whenever is needed
*/
class UpgradeConfigChecker
{
private UpgradeConfigService $upgradeConfigService;
private ConfigDataInterface $configData;
private UpgradeConfig $upgradeConfigService;
private ConfigDataInterface $configData;
public function __construct(UpgradeConfigServiceInterface $upgradeConfigService, ConfigDataInterface $configData)
public function __construct(UpgradeConfigService $upgradeConfigService, ConfigDataInterface $configData)
{
$this->upgradeConfigService = $upgradeConfigService;
$this->configData = $configData;
@@ -49,24 +48,14 @@ class UpgradeConfigChecker
/**
* Comprobar la versión de configuración y actualizarla
*
* @throws UpgradeException
* @throws FileException
*/
public function checkConfigVersion(): void
{
// TODO: remove
// Do not check config version when testing
if (IS_TESTING) {
return;
}
if (file_exists(CONFIG_PATH . DS . 'config.php')) {
$this->upgradeConfigService->upgradeOldConfigFile(VersionUtil::getVersionStringNormalized());
}
$configVersion = UpgradeUtil::fixVersionNumber($this->configData->getConfigVersion());
if ($this->configData->isInstalled()
&& UpgradeConfigService::needsUpgrade($configVersion)
&& UpgradeConfig::needsUpgrade($configVersion)
) {
$this->upgradeConfigService->upgrade($configVersion, $this->configData);
}

View File

@@ -61,7 +61,7 @@ use SP\Domain\Core\Crypt\CryptInterface;
use SP\Domain\Core\Crypt\CryptPKIInterface;
use SP\Domain\Core\Crypt\RequestBasedPasswordInterface;
use SP\Domain\Core\Exceptions\SPException;
use SP\Domain\Core\File\MimeTypesInterface;
use SP\Domain\Core\File\MimeTypesService;
use SP\Domain\Core\LanguageInterface;
use SP\Domain\Core\UI\ThemeContextInterface;
use SP\Domain\Core\UI\ThemeIconsInterface;
@@ -147,7 +147,7 @@ final class CoreDefinitions
new FileCache(Actions::ACTIONS_CACHE_FILE),
new XmlHandler(new FileHandler(ACTIONS_FILE))
),
MimeTypesInterface::class =>
MimeTypesService::class =>
static fn() => new MimeTypes(
new FileCache(MimeTypes::MIME_CACHE_FILE),
new XmlHandler(new FileHandler(MIMETYPES_FILE))

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -32,16 +32,9 @@ use SP\Domain\Core\Exceptions\SPException;
*/
class Event
{
/**
* Event constructor.
*
* @param object $source
* @param EventMessage|null $eventMessage
*
*/
public function __construct(
readonly object $source,
readonly ?EventMessage $eventMessage = null
private readonly object $source,
private readonly ?EventMessage $eventMessage = null
) {
}
@@ -68,4 +61,5 @@ class Event
{
return $this->eventMessage;
}
}

View File

@@ -25,7 +25,7 @@
namespace SP\Core;
use SP\Domain\Core\File\MimeType;
use SP\Domain\Core\File\MimeTypesInterface;
use SP\Domain\Core\File\MimeTypesService;
use SP\Domain\Storage\Ports\FileCacheInterface;
use SP\Domain\Storage\Ports\FileCacheService;
use SP\Domain\Storage\Ports\XmlFileStorageService;
@@ -39,7 +39,7 @@ use function SP\processException;
*
* @package SP\Core
*/
final class MimeTypes implements MimeTypesInterface
final class MimeTypes implements MimeTypesService
{
/**
* Cache file name

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -24,19 +24,11 @@
namespace SP\Domain\Config\Ports;
use SP\Domain\Upgrade\Services\UpgradeInterface;
use SP\Domain\Upgrade\Ports\Upgrade;
/**
* Class UpgradeService
*
* @package SP\Domain\Upgrade\Services
* Interface UpgradeConfigService
*/
interface UpgradeConfigServiceInterface extends UpgradeInterface
interface UpgradeConfigService extends Upgrade
{
/**
* Actualizar el archivo de configuración a formato XML
*
* @throws \SP\Domain\Upgrade\Services\UpgradeException
*/
public function upgradeOldConfigFile(string $version): void;
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -28,6 +28,9 @@ use SP\Domain\Core\Exceptions\ConfigException;
use SP\Domain\Core\Exceptions\SPException;
use SP\Util\Checks;
use function SP\__;
use function SP\__u;
/**
* Class ConfigUtil
*
@@ -35,23 +38,6 @@ use SP\Util\Checks;
*/
final class ConfigUtil
{
/**
* Adaptador para convertir una cadena de extensiones a un array
*/
public static function filesExtsAdapter(string $filesAllowedExts): array
{
if (empty($filesAllowedExts)) {
return [];
}
return array_map(static function ($value) {
if (preg_match('/[^a-z0-9_-]+/i', $value)) {
return null;
}
return strtoupper($value);
}, explode(',', $filesAllowedExts));
}
/**
* Adaptador para convertir una cadena de direcciones de email a un array

View File

@@ -0,0 +1,252 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Domain\Config\Services;
use SP\Core\Application;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Domain\Common\Services\Service;
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\Config\Ports\UpgradeConfigService;
use SP\Domain\Core\File\MimeType;
use SP\Domain\Core\File\MimeTypesService;
use SP\Domain\Providers\FileLogHandlerProvider;
use SP\Infrastructure\File\FileException;
use SP\Providers\Auth\Ldap\LdapTypeEnum;
use SP\Util\VersionUtil;
use function SP\__u;
/**
* Class UpgradeService
*
* @package SP\Domain\Upgrade\Services
*/
final class UpgradeConfig extends Service implements UpgradeConfigService
{
/**
* @var array Versiones actualizables
*/
private const UPGRADES = [
'200.17011202',
'300.18111001',
'300.18112501',
'320.20062801',
];
private ?ConfigDataInterface $configData = null;
public function __construct(
Application $application,
FileLogHandlerProvider $fileLogHandlerProvider,
private readonly MimeTypesService $mimeTypes
) {
parent::__construct($application);
$this->eventDispatcher->attach($fileLogHandlerProvider);
}
public static function needsUpgrade(string $version): bool
{
return VersionUtil::checkVersion($version, self::UPGRADES);
}
/**
* Migrar valores de configuración.
* @throws FileException
*/
public function upgrade(string $version, ConfigDataInterface $configData): void
{
$this->configData = $configData;
$message = EventMessage::factory()->addDescription(__u('Update Configuration'));
$this->eventDispatcher->notify('upgrade.config.start', new Event($this, $message));
$upgradeable = array_filter(
self::UPGRADES,
static fn(string $upgradeVersion) => VersionUtil::checkVersion($version, $upgradeVersion)
);
foreach ($upgradeable as $upgradeVersion) {
$this->applyUpgrade($upgradeVersion);
}
$this->eventDispatcher->notify('upgrade.config.end', new Event($this, $message));
}
/**
* @throws FileException
*/
private function applyUpgrade(string $version): void
{
switch ($version) {
case '200.17011202':
$this->upgradeV200B17011202($version);
break;
case '300.18111001':
$this->upgradeV300B18111001($version);
break;
case '300.18112501':
$this->upgradeV300B18112501($version);
break;
case '320.20062801':
$this->upgradeV320B20062801($version);
break;
}
}
/**
* @throws FileException
*/
private function upgradeV200B17011202(string $version): void
{
$this->configData->setSiteTheme('material-blue');
$this->configData->setConfigVersion($version);
$this->config->save($this->configData, false);
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Update Configuration'))
->addDetail(__u('Version'), $version)
)
);
}
/**
* @throws FileException
*/
private function upgradeV300B18111001(string $version): void
{
$extensions = array_map('strtolower', $this->configData->getFilesAllowedExts());
$configMimeTypes = [];
foreach ($extensions as $extension) {
$match = array_filter(
$this->mimeTypes->getMimeTypes(),
static fn(MimeType $mimeType) => strcasecmp($mimeType->getExtension(), $extension) === 0
);
if (count($match) > 0) {
$mimeType = array_shift($match);
$configMimeTypes[] = $mimeType->getType();
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('MIME type set for this extension'))
->addDetail(__u('MIME type'), $mimeType->getType())
->addDetail(__u('Extension'), $extension)
)
);
} else {
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('MIME type not found for this extension'))
->addDetail(__u('Extension'), $extension)
)
);
}
}
$this->configData->setFilesAllowedMime($configMimeTypes);
$this->configData->setConfigVersion($version);
$this->config->save($this->configData, false);
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Update Configuration'))
->addDetail(__u('Version'), $version)
)
);
}
/**
* @throws FileException
*/
private function upgradeV300B18112501(string $version): void
{
if ($this->configData->isLdapEnabled()) {
$attributes = $this->configData->getAttributes();
if (isset($attributes['ldapAds']) && $attributes['ldapAds']) {
$this->configData->setLdapType(LdapTypeEnum::ADS->value);
} else {
$this->configData->setLdapType(LdapTypeEnum::STD->value);
}
$this->configData->setConfigVersion($version);
$this->config->save($this->configData, false);
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Update Configuration'))
->addDetail(__u('Version'), $version)
)
);
}
}
/**
* @throws FileException
*/
private function upgradeV320B20062801(string $version): void
{
if ($this->configData->isLdapEnabled()) {
if ($this->configData->getLdapType() === LdapTypeEnum::AZURE->value) {
$this->configData->setLdapType(LdapTypeEnum::ADS->value);
}
$this->configData->setConfigVersion($version);
$this->config->save($this->configData, false);
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Update Configuration'))
->addDetail(__u('Version'), $version)
)
);
}
}
}

View File

@@ -1,382 +0,0 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Domain\Config\Services;
use Exception;
use SP\Core\Application;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Domain\Common\Services\Service;
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\Config\Ports\UpgradeConfigServiceInterface;
use SP\Domain\Core\File\MimeTypesInterface;
use SP\Domain\Upgrade\Services\UpgradeException;
use SP\Infrastructure\File\FileException;
use SP\Providers\Auth\Ldap\LdapTypeEnum;
use SP\Providers\Log\FileLogHandler;
use SP\Util\VersionUtil;
use function SP\__u;
use function SP\processException;
/**
* Class UpgradeService
*
* @package SP\Domain\Upgrade\Services
*/
final class UpgradeConfigService extends Service implements UpgradeConfigServiceInterface
{
/**
* @var array Versiones actualizables
*/
private const UPGRADES = [
'112.4',
'130.16020501',
'200.17011202',
'300.18111001',
'300.18112501',
'320.20062801',
];
protected ?ConfigDataInterface $configData = null;
private MimeTypesInterface $mimeTypes;
public function __construct(Application $application, FileLogHandler $fileLogHandler, MimeTypesInterface $mimeTypes)
{
parent::__construct($application);
$this->mimeTypes = $mimeTypes;
$this->eventDispatcher->attach($fileLogHandler);
}
public static function needsUpgrade(string $version): bool
{
return VersionUtil::checkVersion($version, self::UPGRADES);
}
/**
* Actualizar el archivo de configuración a formato XML
*
* @throws UpgradeException
*/
public function upgradeOldConfigFile(string $version): void
{
$configData = $this->config->getConfigData();
$message = EventMessage::factory()->addDescription(__u('Update Configuration'));
$this->eventDispatcher->notify('upgrade.config.old.start', new Event($this, $message));
$oldConfigFile = CONFIG_PATH . DS . 'config.php';
// Include the file, save the data from $CONFIG
include $oldConfigFile;
$message = EventMessage::factory();
if (isset($CONFIG) && is_array($CONFIG)) {
$paramMapper = static function ($mapFrom, $mapTo) use ($CONFIG, $message, $configData) {
if (isset($CONFIG[$mapFrom])) {
$message->addDetail(__u('Parameter'), $mapFrom);
$configData->{$mapTo}($CONFIG[$mapFrom]);
}
};
foreach (self::getConfigParams() as $mapTo => $mapFrom) {
if (method_exists($configData, $mapTo)) {
if (is_array($mapFrom)) {
foreach ($mapFrom as $param) {
$paramMapper($mapFrom, $param);
}
} elseif (isset($CONFIG[$mapFrom])) {
$paramMapper($mapFrom, $mapTo);
}
}
}
}
$oldFile = $oldConfigFile . '.old.' . time();
try {
$configData->setSiteTheme('material-blue');
$configData->setConfigVersion($version);
$this->config->save($configData, false);
rename($oldConfigFile, $oldFile);
$message->addDetail(__u('Version'), $version);
$this->eventDispatcher->notify('upgrade.config.old.end', new Event($this, $message));
} catch (Exception $e) {
processException($e);
$this->eventDispatcher->notify(
'exception',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Error while updating the configuration'))
->addDetail(__u('File'), $oldFile)
)
);
throw new UpgradeException(__u('Error while updating the configuration'));
}
}
/**
* Devuelve array de métodos y parámetros de configuración
*/
private static function getConfigParams(): array
{
return [
'setAccountCount' => 'account_count',
'setAccountLink' => 'account_link',
'setCheckUpdates' => 'checkupdates',
'setCheckNotices' => 'checknotices',
'setDbHost' => 'dbhost',
'setDbName' => 'dbname',
'setDbPass' => 'dbpass',
'setDbUser' => 'dbuser',
'setDebug' => 'debug',
'setDemoEnabled' => 'demo_enabled',
'setGlobalSearch' => 'globalsearch',
'setInstalled' => 'installed',
'setMaintenance' => 'maintenance',
'setPasswordSalt' => 'passwordsalt',
'setSessionTimeout' => 'session_timeout',
'setSiteLang' => 'sitelang',
'setConfigVersion' => 'version',
'setConfigHash' => 'config_hash',
'setProxyEnabled' => 'proxy_enabled',
'setProxyPass' => 'proxy_pass',
'setProxyPort' => 'proxy_port',
'setProxyServer' => 'proxy_server',
'setProxyUser' => 'proxy_user',
'setResultsAsCards' => 'resultsascards',
'setSiteTheme' => 'sitetheme',
'setAccountPassToImage' => 'account_passtoimage',
'setFilesAllowedExts' => ['allowed_exts', 'files_allowed_exts'],
'setFilesAllowedSize' => ['allowed_size', 'files_allowed_size'],
'setFilesEnabled' => ['filesenabled', 'files_enabled'],
'setLdapBase' => ['ldapbase', 'ldap_base'],
'setLdapBindPass' => ['ldapbindpass', 'ldap_bindpass'],
'setLdapBindUser' => ['ldapbinduser', 'ldap_binduser'],
'setLdapEnabled' => ['ldapenabled', 'ldap_enabled'],
'setLdapGroup' => ['ldapgroup', 'ldap_group'],
'setLdapServer' => ['ldapserver', 'ldap_server'],
'setLdapAds' => 'ldap_ads',
'setLdapDefaultGroup' => 'ldap_defaultgroup',
'setLdapDefaultProfile' => 'ldap_defaultprofile',
'setLogEnabled' => ['logenabled', 'log_enabled'],
'setMailEnabled' => ['mailenabled', 'mail_enabled'],
'setMailFrom' => ['mailfrom', 'mail_from'],
'setMailPass' => ['mailpass', 'mail_pass'],
'setMailPort' => ['mailport', 'mail_port'],
'setMailRequestsEnabled' => ['mailrequestsenabled', 'mail_requestsenabled'],
'setMailAuthenabled' => 'mail_authenabled',
'setMailSecurity' => ['mailsecurity', 'mail_security'],
'setMailServer' => ['mailserver', 'mail_server'],
'setMailUser' => ['mailuser', 'mail_user'],
'setWikiEnabled' => ['wikienabled', 'wiki_enabled'],
'setWikiFilter' => ['wikifilter', 'wiki_filter'],
'setWikiPageUrl' => ['wikipageurl' . 'wiki_pageurl'],
'setWikiSearchUrl' => ['wikisearchurl', 'wiki_searchurl'],
];
}
/**
* Migrar valores de configuración.
*/
public function upgrade(string $version, ConfigDataInterface $configData): void
{
$this->configData = $configData;
$message = EventMessage::factory()->addDescription(__u('Update Configuration'));
$this->eventDispatcher->notify('upgrade.config.start', new Event($this, $message));
foreach (self::UPGRADES as $upgradeVersion) {
if (VersionUtil::checkVersion($version, $upgradeVersion)) {
$this->applyUpgrade($upgradeVersion);
}
}
$this->eventDispatcher->notify('upgrade.config.end', new Event($this, $message));
}
/**
* @throws FileException
*/
private function applyUpgrade(string $version): void
{
switch ($version) {
case '200.17011202':
$this->upgrade_200_17011202($version);
break;
case '300.18111001':
$this->upgrade_300_18111001($version);
break;
case '300.18112501':
$this->upgrade_300_18112501($version);
break;
case '320.20062801':
$this->upgrade_320_20062801($version);
break;
}
}
/**
* @throws FileException
*/
private function upgrade_200_17011202(string $version): void
{
$this->configData->setSiteTheme('material-blue');
$this->configData->setConfigVersion($version);
$this->config->save($this->configData, false);
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Update Configuration'))
->addDetail(__u('Version'), $version)
)
);
}
/**
* @throws FileException
*/
private function upgrade_300_18111001(string $version): void
{
$extensions = array_map('strtolower', $this->configData->getFilesAllowedExts());
$configMimeTypes = [];
foreach ($extensions as $extension) {
$exists = false;
foreach ($this->mimeTypes->getMimeTypes() as $mimeType) {
if (strtolower($mimeType->getExtension()) === $extension) {
$configMimeTypes[] = $mimeType->getType();
$exists = true;
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('MIME type set for this extension'))
->addDetail(__u('MIME type'), $mimeType->getType())
->addDetail(__u('Extension'), $extension)
)
);
}
}
if (!$exists) {
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('MIME type not found for this extension'))
->addDetail(__u('Extension'), $extension)
)
);
}
}
$this->configData->setFilesAllowedMime($configMimeTypes);
$this->configData->setConfigVersion($version);
$this->config->save($this->configData, false);
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Update Configuration'))
->addDetail(__u('Version'), $version)
)
);
}
/**
* @throws FileException
*/
private function upgrade_300_18112501(string $version): void
{
if ($this->configData->isLdapEnabled()) {
if ($this->configData->get('ldapAds')) {
$this->configData->setLdapType(LdapTypeEnum::ADS->value);
} else {
$this->configData->setLdapType(LdapTypeEnum::STD->value);
}
$this->configData->setConfigVersion($version);
$this->config->save($this->configData, false);
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Update Configuration'))
->addDetail(__u('Version'), $version)
)
);
}
}
/**
* @throws FileException
*/
private function upgrade_320_20062801(string $version): void
{
if ($this->configData->isLdapEnabled()) {
if ($this->configData->get('ldapType') === LdapTypeEnum::AZURE->value) {
$this->configData->setLdapType(LdapTypeEnum::ADS->value);
}
$this->configData->setConfigVersion($version);
$this->config->save($this->configData, false);
$this->eventDispatcher->notify(
'upgrade.config.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Update Configuration'))
->addDetail(__u('Version'), $version)
)
);
}
}
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -24,15 +24,12 @@
namespace SP\Domain\Core\File;
use SP\Infrastructure\File\FileException;
/**
* Class Mime
*
* @package SP\Core
* Interface MimeTypesService
*/
interface MimeTypesInterface
interface MimeTypesService
{
/**
* @throws FileException

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -24,13 +24,13 @@
namespace SP\Domain\Persistence\Ports;
use SP\Domain\Upgrade\Services\UpgradeInterface;
use SP\Domain\Upgrade\Ports\Upgrade;
/**
* Class UpgradeDatabaseService
*
* @package SP\Domain\Upgrade\Services
*/
interface UpgradeDatabaseServiceInterface extends UpgradeInterface
interface UpgradeDatabaseService extends Upgrade
{
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Domain\Providers;
use SP\Domain\Core\Events\EventReceiver;
/**
* Interface FileLogHandlerProvider
*/
interface FileLogHandlerProvider extends EventReceiver
{
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -22,16 +22,14 @@
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Domain\Upgrade\Services;
namespace SP\Domain\Upgrade\Ports;
use SP\Domain\Config\Ports\ConfigDataInterface;
/**
* Interface UpgradeInterface
*
* @package SP\Domain\Upgrade\Services
* Interface Upgrade
*/
interface UpgradeInterface
interface Upgrade
{
/**
* Check if it needs to be upgraded

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -24,13 +24,11 @@
namespace SP\Domain\Upgrade\Ports;
use SP\Domain\Upgrade\Services\UpgradeInterface;
/**
* Class UpgradeAppService
*
* @package SP\Domain\Upgrade\Services
*/
interface UpgradeAppServiceInterface extends UpgradeInterface
interface UpgradeAppService extends Upgrade
{
}

View File

@@ -40,7 +40,7 @@ use SP\Domain\CustomField\Ports\UpgradeCustomFieldDefinitionServiceInterface;
use SP\Domain\CustomField\Services\UpgradeCustomFieldDataService;
use SP\Domain\CustomField\Services\UpgradeCustomFieldDefinitionService;
use SP\Domain\Plugin\Ports\UpgradePluginServiceInterface;
use SP\Domain\Upgrade\Ports\UpgradeAppServiceInterface;
use SP\Domain\Upgrade\Ports\UpgradeAppService;
use SP\Infrastructure\File\FileException;
use SP\Providers\Log\FileLogHandler;
use SP\Util\VersionUtil;
@@ -50,7 +50,7 @@ use SP\Util\VersionUtil;
*
* @package SP\Domain\Upgrade\Services
*/
final class UpgradeAppService extends Service implements UpgradeAppServiceInterface
final class UpgradeAppService extends Service implements UpgradeAppService
{
private const UPGRADES = [
'300.18010101',

View File

@@ -31,7 +31,7 @@ use SP\Core\Events\EventMessage;
use SP\Domain\Common\Services\Service;
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\Core\Exceptions\SPException;
use SP\Domain\Persistence\Ports\UpgradeDatabaseServiceInterface;
use SP\Domain\Persistence\Ports\UpgradeDatabaseService;
use SP\Infrastructure\Database\DatabaseInterface;
use SP\Infrastructure\Database\MysqlFileParser;
use SP\Infrastructure\File\FileException;
@@ -44,7 +44,7 @@ use SP\Util\VersionUtil;
*
* @package SP\Domain\Upgrade\Services
*/
final class UpgradeDatabaseService extends Service implements UpgradeDatabaseServiceInterface
final class UpgradeDatabaseService extends Service implements UpgradeDatabaseService
{
/**
* @var array Versiones actualizables

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -25,6 +25,7 @@
namespace SP\Providers\Log;
use Monolog\Handler\StreamHandler;
use SP\Domain\Providers\FileLogHandlerProvider;
use SP\Providers\EventsTrait;
/**
@@ -32,7 +33,7 @@ use SP\Providers\EventsTrait;
*
* @package SP\Providers\Log
*/
final class FileLogHandler extends LoggerBase
final class FileLogHandler extends LoggerBase implements FileLogHandlerProvider
{
use EventsTrait;

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -38,14 +38,14 @@ final class VersionUtil
*/
public static function getVersionStringNormalized(): string
{
return implode('', InstallerService::VERSION).'.'.InstallerService::BUILD;
return implode('', InstallerService::VERSION) . '.' . InstallerService::BUILD;
}
/**
* Compare versions
*
* @param string $currentVersion
* @param array|string $upgradeableVersion
* @param string $currentVersion
* @param array|string $upgradeableVersion
*
* @return bool True if $currentVersion is lower than $upgradeableVersion
*/
@@ -66,19 +66,19 @@ final class VersionUtil
return version_compare($currentVersion, $upgradeableVersion) === -1;
}
[$currentVersion, $build] = explode('.', $currentVersion, 2);
[$currentVersion, $currentBuild] = explode('.', $currentVersion, 2);
[$upgradeVersion, $upgradeBuild] = explode('.', $upgradeableVersion, 2);
$versionRes = (int)$currentVersion < (int)$upgradeVersion;
$versionResult = (int)$currentVersion < (int)$upgradeVersion;
return (($versionRes && (int)$upgradeBuild === 0)
|| ($versionRes && (int)$build < (int)$upgradeBuild));
return (($versionResult && (int)$upgradeBuild === 0)
|| ($versionResult && (int)$currentBuild < (int)$upgradeBuild));
}
/**
* Return a normalized version string to be compared
*
* @param array|string $versionIn
* @param array|string $versionIn
*
* @return string
*/
@@ -100,14 +100,14 @@ final class VersionUtil
$nomalizedVersion += (int)$value * (10 ** (3 - $key));
}
return $nomalizedVersion.'.'.$build;
return $nomalizedVersion . '.' . $build;
}
return '';
}
/**
* @param string $version
* @param string $version
*
* @return float|int
*/
@@ -127,7 +127,7 @@ final class VersionUtil
/**
* Devuelve la versión de sysPass.
*
* @param bool $retBuild devolver el número de compilación
* @param bool $retBuild devolver el número de compilación
*
* @return array con el número de versión
*/

View File

@@ -0,0 +1,152 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SPT\Domain\Config\Services;
use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\MockObject\MockObject;
use SP\Core\Application;
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\Config\Ports\ConfigFileService;
use SP\Domain\Config\Services\UpgradeConfig;
use SP\Domain\Core\File\MimeType;
use SP\Domain\Core\File\MimeTypesService;
use SP\Domain\Providers\FileLogHandlerProvider;
use SP\Infrastructure\File\FileException;
use SP\Providers\Auth\Ldap\LdapTypeEnum;
use SPT\UnitaryTestCase;
/**
* Class UpgradeConfigTest
*
* @group unitary
*/
class UpgradeConfigTest extends UnitaryTestCase
{
private MimeTypesService|MockObject $mimeTypeService;
private FileLogHandlerProvider|MockObject $fileLogHandlerProvider;
public static function versionDataProvider(): array
{
return [
['200.00000000', true],
['300.00000000', true],
['320.20062801', false],
['340.00000000', false]
];
}
/**
* @throws Exception
* @throws FileException
*/
public function testUpgrade()
{
$version = '200.00000000';
$configData = $this->createMock(ConfigDataInterface::class);
$configFileService = $this->createMock(ConfigFileService::class);
$application = new Application(
$configFileService,
$this->application->getEventDispatcher(),
$this->application->getContext()
);
$this->checkUpgradeV200B17011202($configData);
$this->checkUpgradeV300B18111001($configData);
$this->checkUpgradeLdap($configData);
$configData->expects(self::exactly(4))
->method('setConfigVersion')
->with(self::anything());
$configFileService->expects(self::exactly(4))
->method('save')
->with($configData, false);
$upgradeConfig = new UpgradeConfig($application, $this->fileLogHandlerProvider, $this->mimeTypeService);
$upgradeConfig->upgrade($version, $configData);
}
private function checkUpgradeV200B17011202(ConfigDataInterface|MockObject $configData): void
{
$configData->expects(self::once())
->method('setSiteTheme')
->with('material-blue');
}
private function checkUpgradeV300B18111001(ConfigDataInterface|MockObject $configData): void
{
$configData->expects(self::once())
->method('getFilesAllowedExts')
->willReturn(['testA', 'testB']);
$this->mimeTypeService
->expects(self::exactly(2))
->method('getMimeTypes')
->willReturn([new MimeType('application/test', '', 'testA')]);
$configData->expects(self::once())
->method('setFilesAllowedMime')
->with(['application/test']);
}
private function checkUpgradeLdap(ConfigDataInterface|MockObject $configData): void
{
$configData->expects(self::exactly(2))
->method('isLdapEnabled')
->willReturn(true);
$configData->expects(self::once())
->method('getAttributes')
->willReturn(['ldapAds' => 'test']);
$configData->expects(self::exactly(2))
->method('setLdapType')
->with(LdapTypeEnum::ADS->value);
$configData->expects(self::once())
->method('getLdapType')
->willReturn(LdapTypeEnum::AZURE->value);
}
/**
* @dataProvider versionDataProvider
* @return void
*/
public function testNeedsUpgrade(string $version, bool $expected)
{
$this->assertEquals($expected, UpgradeConfig::needsUpgrade($version));
}
protected function setUp(): void
{
parent::setUp();
$this->fileLogHandlerProvider = $this->createMock(FileLogHandlerProvider::class);
$this->mimeTypeService = $this->createMock(MimeTypesService::class);
}
}