mirror of
https://github.com/nuxsmin/sysPass.git
synced 2026-02-20 01:41:27 +01:00
* [ADD] Install CLI command tests.
* [MOD] Install CLI command refactoring. * [MOD] Minor code tweaks. Signed-off-by: Rubén D <nuxsmin@syspass.org>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -61,7 +61,6 @@ doc/*
|
||||
build/*
|
||||
tests/_output/*
|
||||
|
||||
.phpstorm.meta.php
|
||||
composer.phar
|
||||
|
||||
.env
|
||||
|
||||
5
.phpstorm.meta.php
Normal file
5
.phpstorm.meta.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace PHPSTORM_META {
|
||||
override(\Psr\Container\ContainerInterface::get(0), type(0));
|
||||
}
|
||||
6
api.php
6
api.php
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2019, Rubén Domínguez nuxsmin@$syspass.org
|
||||
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
@@ -19,7 +19,7 @@
|
||||
* 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/>.
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define('APP_ROOT', __DIR__);
|
||||
|
||||
@@ -1,4 +1,26 @@
|
||||
<?php
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, 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\Modules\Cli\Commands;
|
||||
|
||||
@@ -6,12 +28,11 @@ use Psr\Log\LoggerInterface;
|
||||
use SP\Config\Config;
|
||||
use SP\Config\ConfigData;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
/**
|
||||
* Class CommandBase
|
||||
*
|
||||
* @package SPDecrypter\Commands
|
||||
* @package SP\Modules\Cli\Commands
|
||||
*/
|
||||
abstract class CommandBase extends Command
|
||||
{
|
||||
@@ -19,10 +40,7 @@ abstract class CommandBase extends Command
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
/**
|
||||
* @var SymfonyStyle
|
||||
*/
|
||||
protected $io;
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
@@ -36,19 +54,17 @@ abstract class CommandBase extends Command
|
||||
* CommandBase constructor.
|
||||
*
|
||||
* @param LoggerInterface $logger
|
||||
* @param SymfonyStyle $io
|
||||
* @param Config $config
|
||||
*/
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
SymfonyStyle $io,
|
||||
Config $config)
|
||||
Config $config
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->logger = $logger;
|
||||
$this->io = $io;
|
||||
$this->config = $config;
|
||||
$this->configData = $this->config->getConfigData();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
@@ -24,18 +24,22 @@
|
||||
|
||||
namespace SP\Modules\Cli\Commands;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use RuntimeException;
|
||||
use SP\Config\Config;
|
||||
use SP\Core\Exceptions\InstallError;
|
||||
use SP\Core\Exceptions\InvalidArgumentException;
|
||||
use SP\Core\Language;
|
||||
use SP\Services\Install\InstallData;
|
||||
use SP\Services\Install\Installer;
|
||||
use SP\Util\Util;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\StyleInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
/**
|
||||
@@ -45,6 +49,25 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
*/
|
||||
final class InstallCommand extends CommandBase
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public static $envVarsMapping = [
|
||||
'adminLogin' => 'ADMIN_LOGIN',
|
||||
'adminPassword' => 'ADMIN_PASSWORD',
|
||||
'databaseHost' => 'DATABASE_HOST',
|
||||
'databaseName' => 'DATABASE_NAME',
|
||||
'databaseUser' => 'DATABASE_USER',
|
||||
'databasePassword' => 'DATABASE_PASSWORD',
|
||||
'masterPassword' => 'MASTER_PASSWORD',
|
||||
'hostingMode' => 'HOSTING_MODE',
|
||||
'language' => 'LANGUAGE',
|
||||
'forceInstall' => 'FORCE_INSTALL',
|
||||
'install' => 'INSTALL'
|
||||
];
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $defaultName = 'sp:install';
|
||||
/**
|
||||
* @var Installer
|
||||
@@ -52,30 +75,29 @@ final class InstallCommand extends CommandBase
|
||||
private $installer;
|
||||
|
||||
public function __construct(LoggerInterface $logger,
|
||||
SymfonyStyle $io,
|
||||
Config $config,
|
||||
Installer $installer)
|
||||
Config $config,
|
||||
Installer $installer)
|
||||
{
|
||||
parent::__construct($logger, $io, $config);
|
||||
parent::__construct($logger, $config);
|
||||
|
||||
$this->installer = $installer;
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->setDescription(__('Install sysPass.'))
|
||||
->setHelp(__('This command installs sysPass.'))
|
||||
$this->setDescription(__('Install sysPass'))
|
||||
->setHelp(__('This command installs sysPass'))
|
||||
->addArgument('adminLogin',
|
||||
InputArgument::REQUIRED,
|
||||
InputArgument::OPTIONAL,
|
||||
__('Admin user to log into the application'))
|
||||
->addArgument('databaseHost',
|
||||
InputArgument::REQUIRED,
|
||||
InputArgument::OPTIONAL,
|
||||
__('Server name to install sysPass database'))
|
||||
->addArgument('databaseName',
|
||||
InputArgument::REQUIRED,
|
||||
InputArgument::OPTIONAL,
|
||||
__('Application database name. eg. syspass'))
|
||||
->addArgument('databaseUser',
|
||||
InputArgument::REQUIRED,
|
||||
InputArgument::OPTIONAL,
|
||||
__('An user with database administrative rights'))
|
||||
->addOption('databasePassword',
|
||||
null,
|
||||
@@ -91,41 +113,79 @@ final class InstallCommand extends CommandBase
|
||||
__('Master password to encrypt the passwords'))
|
||||
->addOption('hostingMode',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
__('It does not create or verify the user\'s permissions on the DB'),
|
||||
false)
|
||||
InputOption::VALUE_NONE,
|
||||
__('It does not create or verify the user\'s permissions on the DB'))
|
||||
->addOption('language',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
__('Sets the global app language. You can set a per user language on preferences.'))
|
||||
->addOption('force',
|
||||
__('Sets the global app language. You can set a per user language on preferences'))
|
||||
->addOption('forceInstall',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
__('Force sysPass installation.'),
|
||||
false);
|
||||
InputOption::VALUE_NONE,
|
||||
__('Force sysPass installation'))
|
||||
->addOption('install',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
__('Skip asking to confirm the installation'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|void
|
||||
* @return int
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$force = (bool)$input->getOption('force');
|
||||
$style = new SymfonyStyle($input, $output);
|
||||
|
||||
if ($this->configData->isInstalled() && $force === false) {
|
||||
$this->logger->warning(__u('sysPass is already installed'));
|
||||
try {
|
||||
$installData = $this->getInstallData($input, $style);
|
||||
|
||||
$this->io->warning(__('sysPass is already installed. Use \'--force\' to install it again.'));
|
||||
$forceInstall = $this->getForceInstall($input);
|
||||
|
||||
return self::FAILURE;
|
||||
if (!$forceInstall || !$this->getInstall($input, $style)) {
|
||||
$this->logger->debug(__u('Installation aborted'));
|
||||
$style->info(__('Installation aborted'));
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->installer->run($installData);
|
||||
|
||||
$this->logger->info(__('Installation finished'));
|
||||
|
||||
$style->success(__('Installation finished'));
|
||||
|
||||
return self::SUCCESS;
|
||||
} catch (InstallError $e) {
|
||||
$this->logger->error($e->getMessage());
|
||||
|
||||
$style->error(__($e->getMessage()));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$this->logger->warning($e->getMessage());
|
||||
|
||||
$style->warning(__($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error($e->getTraceAsString());
|
||||
$this->logger->error($e->getMessage());
|
||||
|
||||
$style->error(__($e->getMessage()));
|
||||
}
|
||||
|
||||
$adminPassword = $input->getOption('adminPassword');
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$passNonEmptyValidator = function ($value) {
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param StyleInterface $style
|
||||
*
|
||||
* @return InstallData
|
||||
* @throws InstallError
|
||||
*/
|
||||
private function getInstallData(InputInterface $input, StyleInterface $style): InstallData
|
||||
{
|
||||
$passNotEmptyValidator = function ($value) {
|
||||
if (empty($value)) {
|
||||
throw new RuntimeException(__('Password cannot be blank'));
|
||||
}
|
||||
@@ -133,83 +193,258 @@ final class InstallCommand extends CommandBase
|
||||
return $value;
|
||||
};
|
||||
|
||||
if (empty($adminPassword)) {
|
||||
$adminPassword = $this->getAdminPassword($input, $style, $passNotEmptyValidator);
|
||||
$masterPassword = $this->getMasterPassword($input, $style, $passNotEmptyValidator);
|
||||
$databasePassword = $this->getDatabasePassword($input, $style);
|
||||
$language = $this->getLanguage($input, $style);
|
||||
$hostingMode = $this->isHostingMode($input);
|
||||
$adminLogin = self::getEnvVarOrArgument('adminLogin', $input);
|
||||
$databaseUser = self::getEnvVarOrArgument('databaseUser', $input);
|
||||
$databaseName = self::getEnvVarOrArgument('databaseName', $input);
|
||||
$databaseHost = self::getEnvVarOrArgument('databaseHost', $input);
|
||||
|
||||
$installData = new InstallData();
|
||||
$installData->setSiteLang($language);
|
||||
$installData->setAdminLogin($adminLogin);
|
||||
$installData->setAdminPass($adminPassword);
|
||||
$installData->setMasterPassword($masterPassword);
|
||||
$installData->setDbAdminUser($databaseUser);
|
||||
$installData->setDbAdminPass($databasePassword);
|
||||
$installData->setDbName($databaseName);
|
||||
$installData->setDbHost($databaseHost);
|
||||
$installData->setHostingMode($hostingMode);
|
||||
|
||||
return $installData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param StyleInterface $style
|
||||
* @param Closure $passNotEmptyValidator
|
||||
*
|
||||
* @return array|false|mixed|string
|
||||
* @throws InstallError
|
||||
*/
|
||||
private function getAdminPassword(
|
||||
InputInterface $input,
|
||||
StyleInterface $style,
|
||||
Closure $passNotEmptyValidator
|
||||
)
|
||||
{
|
||||
$option = 'adminPassword';
|
||||
|
||||
$password =
|
||||
self::getEnvVarForOption($option)
|
||||
?: $input->getOption($option);
|
||||
|
||||
if (empty($password)) {
|
||||
$this->logger->debug(__u('Ask for admin password'));
|
||||
|
||||
$adminPassword = $this->io->askHidden(__('Please provide sysPass admin\'s password'), $passNonEmptyValidator);
|
||||
$adminPasswordRepeat = $this->io->askHidden(__('Please provide sysPass admin\'s password again'), $passNonEmptyValidator);
|
||||
$password = $style->askHidden(
|
||||
__('Please provide sysPass admin\'s password'),
|
||||
$passNotEmptyValidator
|
||||
);
|
||||
|
||||
if ($adminPassword !== $adminPasswordRepeat) {
|
||||
$this->io->warning(__('Passwords do not match'));
|
||||
$passwordRepeat = $style->askHidden(
|
||||
__('Please provide sysPass admin\'s password again'),
|
||||
$passNotEmptyValidator
|
||||
);
|
||||
|
||||
return self::FAILURE;
|
||||
if ($password !== $passwordRepeat) {
|
||||
throw new InstallError(__u('Passwords do not match'));
|
||||
} elseif (null === $password || null === $passwordRepeat) {
|
||||
throw new InstallError(sprintf(__u('%s cannot be blank'), 'Admin password'));
|
||||
}
|
||||
}
|
||||
|
||||
$masterPassword = $input->getOption('masterPassword');
|
||||
return $password;
|
||||
}
|
||||
|
||||
if (empty($masterPassword)) {
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param StyleInterface $style
|
||||
* @param Closure $passNotEmptyValidator
|
||||
*
|
||||
* @return array|false|mixed|string
|
||||
* @throws InstallError
|
||||
*/
|
||||
private function getMasterPassword(
|
||||
InputInterface $input,
|
||||
StyleInterface $style,
|
||||
Closure $passNotEmptyValidator
|
||||
)
|
||||
{
|
||||
$password = self::getEnvVarOrOption('masterPassword', $input);
|
||||
|
||||
if (empty($password)) {
|
||||
$this->logger->debug(__u('Ask for master password'));
|
||||
|
||||
$masterPassword = $this->io->askHidden(__('Please provide sysPass master password'), $passNonEmptyValidator);
|
||||
$masterPasswordRepeat = $this->io->askHidden(__('Please provide sysPass master password again'), $passNonEmptyValidator);
|
||||
$password = $style->askHidden(
|
||||
__('Please provide sysPass master password'),
|
||||
$passNotEmptyValidator
|
||||
);
|
||||
$passwordRepeat = $style->askHidden(
|
||||
__('Please provide sysPass master password again'),
|
||||
$passNotEmptyValidator
|
||||
);
|
||||
|
||||
if ($masterPassword !== $masterPasswordRepeat) {
|
||||
$this->io->warning(__('Passwords do not match'));
|
||||
|
||||
return self::FAILURE;
|
||||
if ($password !== $passwordRepeat) {
|
||||
throw new InstallError(__u('Passwords do not match'));
|
||||
} elseif (null === $password || null === $passwordRepeat) {
|
||||
throw new InstallError(sprintf(__u('%s cannot be blank'), 'Master password'));
|
||||
}
|
||||
}
|
||||
|
||||
$databasePassword = $input->getOption('databasePassword');
|
||||
return $password;
|
||||
}
|
||||
|
||||
if (empty($databasePassword)) {
|
||||
/**
|
||||
* @param string $option
|
||||
* @param InputInterface $input
|
||||
*
|
||||
* @return array|false|mixed|string
|
||||
*/
|
||||
private static function getEnvVarOrOption(
|
||||
string $option,
|
||||
InputInterface $input
|
||||
)
|
||||
{
|
||||
return self::getEnvVarForOption($option)
|
||||
?: $input->getOption($option);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $option
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
public static function getEnvVarForOption(string $option)
|
||||
{
|
||||
return getenv(self::$envVarsMapping[$option]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param StyleInterface $style
|
||||
*
|
||||
* @return array|false|mixed|string
|
||||
*/
|
||||
private function getDatabasePassword(
|
||||
InputInterface $input,
|
||||
StyleInterface $style
|
||||
)
|
||||
{
|
||||
$password = self::getEnvVarOrOption('databasePassword', $input);
|
||||
|
||||
if (empty($password)) {
|
||||
$this->logger->debug(__u('Ask for database password'));
|
||||
|
||||
$databasePassword = $this->io->askHidden(__('Please provide database admin password'));
|
||||
$password = $style->askHidden(__('Please provide database admin password'));
|
||||
}
|
||||
|
||||
$language = $input->getOption('language');
|
||||
return $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param StyleInterface $style
|
||||
*
|
||||
* @return array|false|mixed|string
|
||||
*/
|
||||
private function getLanguage(
|
||||
InputInterface $input,
|
||||
StyleInterface $style
|
||||
)
|
||||
{
|
||||
$language = self::getEnvVarOrOption('language', $input);
|
||||
|
||||
if (empty($language)) {
|
||||
$this->logger->debug(__u('Ask for language'));
|
||||
|
||||
$language = $this->io->choice(__('Language'), array_keys(Language::getAvailableLanguages()), 'en_US');
|
||||
$language = $style->choice(
|
||||
__('Language'),
|
||||
array_keys(Language::getAvailableLanguages()),
|
||||
'en_US'
|
||||
);
|
||||
}
|
||||
|
||||
$install = $this->io->confirm(__('Install sysPass?'), false);
|
||||
return $language;
|
||||
}
|
||||
|
||||
if (!$install) {
|
||||
$this->logger->debug(__u('Installation aborted'));
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isHostingMode(InputInterface $input): bool
|
||||
{
|
||||
$option = 'hostingMode';
|
||||
|
||||
return self::SUCCESS;
|
||||
$envHostingMode = self::getEnvVarForOption($option);
|
||||
|
||||
return $envHostingMode !== false
|
||||
? Util::boolval($envHostingMode)
|
||||
: $input->getOption($option);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $argument
|
||||
* @param InputInterface $input
|
||||
*
|
||||
* @return array|false|mixed|string
|
||||
*/
|
||||
private static function getEnvVarOrArgument(
|
||||
string $argument,
|
||||
InputInterface $input
|
||||
)
|
||||
{
|
||||
return self::getEnvVarForOption($argument)
|
||||
?: $input->getArgument($argument);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
*
|
||||
* @return bool
|
||||
* @throws InstallError
|
||||
*/
|
||||
private function getForceInstall(InputInterface $input): bool
|
||||
{
|
||||
$option = 'forceInstall';
|
||||
|
||||
$envForceInstall = self::getEnvVarForOption($option);
|
||||
|
||||
$force = $envForceInstall !== false
|
||||
? Util::boolval($envForceInstall)
|
||||
: $input->getOption($option);
|
||||
|
||||
if ($force === false && $this->configData->isInstalled()) {
|
||||
throw new InstallError(__u('sysPass is already installed. Use \'--forceInstall\' to install it again.'));
|
||||
}
|
||||
|
||||
$installData = new InstallData();
|
||||
$installData->setSiteLang($language);
|
||||
$installData->setAdminLogin($input->getArgument('adminLogin'));
|
||||
$installData->setAdminPass($adminPassword);
|
||||
$installData->setMasterPassword($masterPassword);
|
||||
$installData->setDbAdminUser($input->getArgument('databaseUser'));
|
||||
$installData->setDbAdminPass($databasePassword);
|
||||
$installData->setDbName($input->getArgument('databaseName'));
|
||||
$installData->setDbHost($input->getArgument('databaseHost'));
|
||||
$installData->setHostingMode((bool)$input->getOption('hostingMode'));
|
||||
return $force;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->installer->run($installData);
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param StyleInterface $style
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function getInstall(InputInterface $input, StyleInterface $style): bool
|
||||
{
|
||||
$option = 'install';
|
||||
|
||||
$this->io->success(__('Installation finished'));
|
||||
$envInstall = self::getEnvVarForOption($option);
|
||||
|
||||
$this->logger->info(__u('Installation finished'));
|
||||
return self::SUCCESS;
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$this->io->error(__($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error($e->getTraceAsString());
|
||||
$this->logger->error($e->getMessage());
|
||||
$install = $envInstall !== false
|
||||
? Util::boolval($envInstall)
|
||||
: $input->getOption($option);
|
||||
|
||||
if ($install === false) {
|
||||
return $style->confirm(__('Install sysPass?'), false);
|
||||
}
|
||||
|
||||
return self::FAILURE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -24,20 +24,15 @@
|
||||
|
||||
namespace SP\Modules\Cli;
|
||||
|
||||
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
|
||||
use DI\DependencyException;
|
||||
use DI\NotFoundException;
|
||||
use Exception;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use SP\Core\Context\ContextException;
|
||||
use SP\Core\Context\StatelessContext;
|
||||
use SP\Core\Exceptions\InitializationException;
|
||||
use SP\Core\Language;
|
||||
use SP\Core\ModuleBase;
|
||||
use SP\Modules\Cli\Commands\InstallCommand;
|
||||
use SP\Services\Upgrade\UpgradeAppService;
|
||||
use SP\Services\Upgrade\UpgradeDatabaseService;
|
||||
use SP\Services\Upgrade\UpgradeUtil;
|
||||
use SP\Storage\File\FileException;
|
||||
use SP\Util\VersionUtil;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
@@ -62,7 +57,7 @@ final class Init extends ModuleBase
|
||||
*/
|
||||
protected $language;
|
||||
/**
|
||||
* @var mixed|Application
|
||||
* @var Application
|
||||
*/
|
||||
protected $application;
|
||||
|
||||
@@ -106,8 +101,9 @@ final class Init extends ModuleBase
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function initCli()
|
||||
private function initCli(): void
|
||||
{
|
||||
$this->application->setName('sysPass CLI');
|
||||
$this->application->setVersion(implode('.', VersionUtil::getVersionArray()));
|
||||
@@ -121,38 +117,4 @@ final class Init extends ModuleBase
|
||||
$this->container->get(OutputInterface::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Comprueba que la aplicación esté instalada
|
||||
* Esta función comprueba si la aplicación está instalada. Si no lo está, redirige al instalador.
|
||||
*
|
||||
* @throws InitializationException
|
||||
*/
|
||||
private function checkInstalled()
|
||||
{
|
||||
if (!$this->configData->isInstalled()) {
|
||||
throw new InitializationException('Not installed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comprobar si es necesario actualizar componentes
|
||||
*
|
||||
* @throws EnvironmentIsBrokenException
|
||||
* @throws FileException
|
||||
* @throws InitializationException
|
||||
*/
|
||||
private function checkUpgrade()
|
||||
{
|
||||
UpgradeUtil::fixAppUpgrade($this->configData, $this->config);
|
||||
|
||||
if ($this->configData->getUpgradeKey()
|
||||
|| (UpgradeDatabaseService::needsUpgrade($this->configData->getDatabaseVersion()) ||
|
||||
UpgradeAppService::needsUpgrade($this->configData->getAppVersion()))
|
||||
) {
|
||||
$this->config->generateUpgradeKey();
|
||||
|
||||
throw new InitializationException(__u('Updating needed'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,13 +32,11 @@ use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use function DI\autowire;
|
||||
use function DI\create;
|
||||
use function DI\factory;
|
||||
|
||||
return [
|
||||
LoggerInterface::class => function (ContainerInterface $c) {
|
||||
LoggerInterface::class => static function (ContainerInterface $c) {
|
||||
$logger = $c->get(Logger::class);
|
||||
$logger->pushHandler(new StreamHandler(LOG_FILE));
|
||||
|
||||
@@ -46,13 +44,7 @@ return [
|
||||
},
|
||||
Application::class => create(Application::class),
|
||||
OutputInterface::class => create(ConsoleOutput::class)
|
||||
->constructor(ConsoleOutput::VERBOSITY_NORMAL, true),
|
||||
->constructor(OutputInterface::VERBOSITY_NORMAL, true),
|
||||
InputInterface::class => create(ArgvInput::class),
|
||||
SymfonyStyle::class => factory(function (ContainerInterface $c) {
|
||||
return new SymfonyStyle(
|
||||
$c->get(InputInterface::class),
|
||||
$c->get(OutputInterface::class)
|
||||
);
|
||||
}),
|
||||
InstallCommand::class => autowire()
|
||||
];
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
},
|
||||
"require": {
|
||||
"roave/security-advisories": "dev-master",
|
||||
"php": "~7.3 || ~7.4",
|
||||
"php": "~7.3 || ~7.4 || ~8.0",
|
||||
"defuse/php-encryption": "^2.1",
|
||||
"phpmailer/phpmailer": "^6.0",
|
||||
"ademarre/binary-to-text-php": "dev-master",
|
||||
|
||||
892
composer.lock
generated
892
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -54,12 +54,11 @@ return [
|
||||
Request::class => create(Request::class)
|
||||
->constructor(\Klein\Request::createFromGlobals()),
|
||||
ContextInterface::class => function (ContainerInterface $c) {
|
||||
switch (APP_MODULE) {
|
||||
case 'web':
|
||||
return $c->get(SessionContext::class);
|
||||
default:
|
||||
return $c->get(StatelessContext::class);
|
||||
if (APP_MODULE === 'web') {
|
||||
return $c->get(SessionContext::class);
|
||||
}
|
||||
|
||||
return $c->get(StatelessContext::class);
|
||||
},
|
||||
Config::class => function (ContainerInterface $c) {
|
||||
return new Config(
|
||||
|
||||
@@ -46,7 +46,7 @@ final class Config
|
||||
/**
|
||||
* Cache file name
|
||||
*/
|
||||
const CONFIG_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'config.cache';
|
||||
public const CONFIG_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'config.cache';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
||||
35
lib/SP/Core/Exceptions/InstallError.php
Normal file
35
lib/SP/Core/Exceptions/InstallError.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, 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\Core\Exceptions;
|
||||
|
||||
/**
|
||||
* Class InstallError
|
||||
*
|
||||
* @package SP\Core\Exceptions
|
||||
*/
|
||||
final class InstallError extends SPException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -71,7 +71,7 @@ class ItemPresetData extends DataModelBase implements HydratableInterface
|
||||
*/
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id !== null ? (int)$this->id : null;
|
||||
return $this->id ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
namespace SP\Services\Install;
|
||||
|
||||
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
|
||||
use Exception;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
@@ -60,9 +59,9 @@ final class Installer extends Service
|
||||
/**
|
||||
* sysPass' version and build number
|
||||
*/
|
||||
const VERSION = [3, 2, 0];
|
||||
const VERSION_TEXT = '3.2';
|
||||
const BUILD = 20062901;
|
||||
public const VERSION = [3, 2, 0];
|
||||
public const VERSION_TEXT = '3.2';
|
||||
public const BUILD = 20062901;
|
||||
|
||||
/**
|
||||
* @var DatabaseSetupInterface
|
||||
@@ -203,7 +202,11 @@ final class Installer extends Service
|
||||
*/
|
||||
private function setupDbHost()
|
||||
{
|
||||
if (preg_match('/^(?:(?P<host>.*):(?P<port>\d{1,5}))|^(?:unix:(?P<socket>.*))/', $this->installData->getDbHost(), $match)) {
|
||||
if (preg_match(
|
||||
'/^(?:(?P<host>.*):(?P<port>\d{1,5}))|^(?:unix:(?P<socket>.*))/',
|
||||
$this->installData->getDbHost(),
|
||||
$match)
|
||||
) {
|
||||
if (!empty($match['socket'])) {
|
||||
$this->installData->setDbSocket($match['socket']);
|
||||
} else {
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace SP\Storage\Database;
|
||||
|
||||
use Exception;
|
||||
use PDO;
|
||||
use SP\Core\Exceptions\SPException;
|
||||
|
||||
defined('APP_ROOT') || die();
|
||||
|
||||
@@ -36,9 +37,9 @@ defined('APP_ROOT') || die();
|
||||
*/
|
||||
final class MySQLHandler implements DBStorageInterface
|
||||
{
|
||||
const STATUS_OK = 0;
|
||||
const STATUS_KO = 1;
|
||||
const PDO_OPTS = [
|
||||
public const STATUS_OK = 0;
|
||||
public const STATUS_KO = 1;
|
||||
public const PDO_OPTS = [
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::MYSQL_ATTR_FOUND_ROWS => true,
|
||||
@@ -97,7 +98,7 @@ final class MySQLHandler implements DBStorageInterface
|
||||
) {
|
||||
throw new DatabaseException(
|
||||
__u('Unable to connect to DB'),
|
||||
DatabaseException::CRITICAL,
|
||||
SPException::CRITICAL,
|
||||
__u('Please, check the connection parameters'));
|
||||
}
|
||||
|
||||
@@ -117,7 +118,7 @@ final class MySQLHandler implements DBStorageInterface
|
||||
} catch (Exception $e) {
|
||||
throw new DatabaseException(
|
||||
__u('Unable to connect to DB'),
|
||||
DatabaseException::CRITICAL,
|
||||
SPException::CRITICAL,
|
||||
sprintf('Error %s: %s', $e->getCode(), $e->getMessage()),
|
||||
$e->getCode(),
|
||||
$e
|
||||
@@ -161,22 +162,29 @@ final class MySQLHandler implements DBStorageInterface
|
||||
public function getConnectionSimple(): PDO
|
||||
{
|
||||
if (!$this->db) {
|
||||
if (null === $this->connectionData->getDbHost() && null === $this->connectionData->getDbSocket()) {
|
||||
if (null === $this->connectionData->getDbHost()
|
||||
&& null === $this->connectionData->getDbSocket()
|
||||
) {
|
||||
throw new DatabaseException(
|
||||
__u('Unable to connect to DB'),
|
||||
DatabaseException::CRITICAL,
|
||||
SPException::CRITICAL,
|
||||
__u('Please, check the connection parameters'));
|
||||
}
|
||||
|
||||
try {
|
||||
$opts = [PDO::ATTR_EMULATE_PREPARES => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION];
|
||||
|
||||
$this->db = new PDO($this->getConnectionUri(), $this->connectionData->getDbUser(), $this->connectionData->getDbPass(), $opts);
|
||||
$this->db = new PDO(
|
||||
$this->getConnectionUri(),
|
||||
$this->connectionData->getDbUser(),
|
||||
$this->connectionData->getDbPass(),
|
||||
$opts
|
||||
);
|
||||
$this->dbStatus = self::STATUS_OK;
|
||||
} catch (Exception $e) {
|
||||
throw new DatabaseException(
|
||||
__u('Unable to connect to DB'),
|
||||
DatabaseException::CRITICAL,
|
||||
SPException::CRITICAL,
|
||||
sprintf('Error %s: %s', $e->getCode(), $e->getMessage()),
|
||||
$e->getCode(),
|
||||
$e
|
||||
|
||||
@@ -139,7 +139,7 @@ final class Util
|
||||
|
||||
// not strict? let the regular php bool check figure it out (will
|
||||
// largely default to true)
|
||||
return ($in ? true : false);
|
||||
return (bool)$in;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
@@ -19,7 +19,7 @@
|
||||
* 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/>.
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Tests;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
@@ -19,7 +19,7 @@
|
||||
* 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/>.
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Tests;
|
||||
@@ -44,26 +44,31 @@ class DatabaseUtil
|
||||
*
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public static function createUser($user, $pass, $database, $host)
|
||||
public static function createUser(
|
||||
string $user,
|
||||
string $pass,
|
||||
string $database,
|
||||
string $host
|
||||
): void
|
||||
{
|
||||
$query = 'GRANT ALL PRIVILEGES ON `%s`.* TO \'%s\'@\'%s\' IDENTIFIED BY \'%s\'';
|
||||
|
||||
$conn = self::getConnection();
|
||||
$conn->query(sprintf($query, $database, $user, SELF_IP_ADDRESS, $pass));
|
||||
$conn->exec(sprintf($query, $database, $user, SELF_IP_ADDRESS, $pass));
|
||||
|
||||
// Long hostname returned on Travis CI
|
||||
if (getenv('TRAVIS') === false) {
|
||||
$conn->query(sprintf($query, $database, $user, SELF_HOSTNAME, $pass));
|
||||
$conn->exec(sprintf($query, $database, $user, SELF_HOSTNAME, $pass));
|
||||
}
|
||||
|
||||
$conn->query(sprintf($query, $database, $user, $host, $pass));
|
||||
$conn->exec(sprintf($query, $database, $user, $host, $pass));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PDO
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public static function getConnection()
|
||||
public static function getConnection(): PDO
|
||||
{
|
||||
$data = (new DatabaseConnectionData())
|
||||
->setDbHost(getenv('DB_SERVER'))
|
||||
@@ -77,11 +82,11 @@ class DatabaseUtil
|
||||
* @param string $user
|
||||
* @param string $host
|
||||
*/
|
||||
public static function dropUser($user, $host)
|
||||
public static function dropUser(string $user, string $host): void
|
||||
{
|
||||
try {
|
||||
self::getConnection()
|
||||
->query(sprintf('DROP USER \'%s\'@\'%s\'', $user, $host));
|
||||
->exec(sprintf('DROP USER \'%s\'@\'%s\'', $user, $host));
|
||||
} catch (Exception $e) {
|
||||
processException($e);
|
||||
}
|
||||
@@ -92,10 +97,10 @@ class DatabaseUtil
|
||||
*
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public static function dropDatabase($database)
|
||||
public static function dropDatabase(string $database): void
|
||||
{
|
||||
self::getConnection()
|
||||
->query(sprintf('DROP DATABASE IF EXISTS `%s`', $database));
|
||||
->exec(sprintf('DROP DATABASE IF EXISTS `%s`', $database));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,9 +108,9 @@ class DatabaseUtil
|
||||
*
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public static function createDatabase($database)
|
||||
public static function createDatabase(string $database): void
|
||||
{
|
||||
self::getConnection()
|
||||
->query(sprintf('CREATE DATABASE `%s`', $database));
|
||||
->exec(sprintf('CREATE DATABASE `%s`', $database));
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
|
||||
61
tests/SP/Modules/Cli/CliTestCase.php
Normal file
61
tests/SP/Modules/Cli/CliTestCase.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, 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\Tests\Modules\Cli;
|
||||
|
||||
use DI\ContainerBuilder;
|
||||
use Exception;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class CliTestCase
|
||||
*
|
||||
* @package SP\Tests\Modules\Cli
|
||||
*/
|
||||
abstract class CliTestCase extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected static $dic;
|
||||
|
||||
/**
|
||||
* This method is called before the first test of this test class is run.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
$builder = new ContainerBuilder();
|
||||
$builder->addDefinitions(
|
||||
APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'Definitions.php',
|
||||
MODULES_PATH . DIRECTORY_SEPARATOR . 'cli' . DIRECTORY_SEPARATOR . 'definitions.php'
|
||||
);
|
||||
|
||||
self::$dic = $builder->build();
|
||||
}
|
||||
}
|
||||
382
tests/SP/Modules/Cli/Commands/InstallCommandTest.php
Normal file
382
tests/SP/Modules/Cli/Commands/InstallCommandTest.php
Normal file
@@ -0,0 +1,382 @@
|
||||
<?php
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, 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\Tests\Modules\Cli\Commands;
|
||||
|
||||
use DI\DependencyException;
|
||||
use DI\NotFoundException;
|
||||
use Exception;
|
||||
use SP\Config\Config;
|
||||
use SP\Modules\Cli\Commands\InstallCommand;
|
||||
use SP\Storage\Database\DatabaseException;
|
||||
use SP\Tests\DatabaseUtil;
|
||||
use SP\Tests\Modules\Cli\CliTestCase;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
use function SP\Tests\getResource;
|
||||
use function SP\Tests\recreateDir;
|
||||
use function SP\Tests\saveResource;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class InstallCommandTest extends CliTestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $currentConfig;
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private static $commandInputData = [
|
||||
'adminLogin' => 'Admin',
|
||||
'databaseHost' => 'localhost',
|
||||
'databaseName' => 'syspass-test-install',
|
||||
'databaseUser' => 'syspass_user',
|
||||
'--databasePassword' => 'test123',
|
||||
'--adminPassword' => 'admin123',
|
||||
'--masterPassword' => '12345678900',
|
||||
'--install' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* This method is called before the first test of this test class is run.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
// Backup current config file content in a variable
|
||||
self::$currentConfig = getResource('config', 'config.xml');
|
||||
|
||||
parent::setUpBeforeClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called after the last test of this test class is run.
|
||||
*/
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
// Replace config file with previously saved data
|
||||
saveResource('config', 'config.xml', self::$currentConfig);
|
||||
// Recreate cache directory to avoid unwanted behavior
|
||||
recreateDir(CACHE_PATH);
|
||||
|
||||
parent::tearDownAfterClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function testInstallationIsAborted(): void
|
||||
{
|
||||
$commandTester = $this->executeCommandTest();
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Installation aborted', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $inputData
|
||||
* @param bool $useInputData
|
||||
*
|
||||
* @return CommandTester
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
private function executeCommandTest(
|
||||
?array $inputData = null,
|
||||
bool $useInputData = true
|
||||
): CommandTester
|
||||
{
|
||||
$installCommand = self::$dic->get(InstallCommand::class);
|
||||
|
||||
if (null === $inputData && $useInputData) {
|
||||
$inputData = self::$commandInputData;
|
||||
}
|
||||
|
||||
$commandTester = new CommandTester($installCommand);
|
||||
$commandTester->execute(
|
||||
$inputData ?? [],
|
||||
['interactive' => false]
|
||||
);
|
||||
|
||||
return $commandTester;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function testNoDatabaseConnection(): void
|
||||
{
|
||||
$inputData = array_merge(
|
||||
self::$commandInputData,
|
||||
['--forceInstall' => null]
|
||||
);
|
||||
|
||||
$commandTester = $this->executeCommandTest($inputData);
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Unable to connect to DB', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function testEmptyAdminPassword(): void
|
||||
{
|
||||
$inputData = array_merge(
|
||||
self::$commandInputData,
|
||||
['--adminPassword' => '']
|
||||
);
|
||||
|
||||
$commandTester = $this->executeCommandTest($inputData);
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Admin password cannot be blank', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function testEmptyMasterPassword(): void
|
||||
{
|
||||
$inputData = array_merge(
|
||||
self::$commandInputData,
|
||||
['--masterPassword' => '']
|
||||
);
|
||||
|
||||
$commandTester = $this->executeCommandTest($inputData);
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Master password cannot be blank', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function testInstallIsSuccessful(): void
|
||||
{
|
||||
$inputData = array_merge(
|
||||
self::$commandInputData,
|
||||
[
|
||||
'databaseHost' => getenv('DB_SERVER'),
|
||||
'databaseUser' => getenv('DB_USER'),
|
||||
'--databasePassword' => getenv('DB_PASS'),
|
||||
'--forceInstall' => null
|
||||
]
|
||||
);
|
||||
|
||||
$commandTester = $this->executeCommandTest($inputData);
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Installation finished', $output);
|
||||
|
||||
$configData = self::$dic->get(Config::class)->getConfigData();
|
||||
|
||||
// Cleanup database
|
||||
DatabaseUtil::dropDatabase(self::$commandInputData['databaseName']);
|
||||
DatabaseUtil::dropUser($configData->getDbUser(), SELF_IP_ADDRESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function testInstallAndLanguageIsSet(): void
|
||||
{
|
||||
$inputData = array_merge(
|
||||
self::$commandInputData,
|
||||
[
|
||||
'databaseHost' => getenv('DB_SERVER'),
|
||||
'databaseUser' => getenv('DB_USER'),
|
||||
'--databasePassword' => getenv('DB_PASS'),
|
||||
'--language' => 'es_ES',
|
||||
'--forceInstall' => null
|
||||
]
|
||||
);
|
||||
|
||||
$commandTester = $this->executeCommandTest($inputData);
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Installation finished', $output);
|
||||
|
||||
$configData = self::$dic->get(Config::class)->getConfigData();
|
||||
|
||||
$this->assertEquals($configData->getSiteLang(), $inputData['--language']);
|
||||
|
||||
// Cleanup database
|
||||
DatabaseUtil::dropDatabase(self::$commandInputData['databaseName']);
|
||||
DatabaseUtil::dropUser($configData->getDbUser(), SELF_IP_ADDRESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function testInstallAndHostingModeIsUsed(): void
|
||||
{
|
||||
$databaseUser = 'syspass';
|
||||
$databasePassword = 'syspass123';
|
||||
|
||||
DatabaseUtil::createDatabase(self::$commandInputData['databaseName']);
|
||||
DatabaseUtil::createUser(
|
||||
$databaseUser,
|
||||
$databasePassword,
|
||||
self::$commandInputData['databaseName'],
|
||||
getenv('DB_SERVER')
|
||||
);
|
||||
|
||||
$inputData = array_merge(
|
||||
self::$commandInputData,
|
||||
[
|
||||
'databaseHost' => getenv('DB_SERVER'),
|
||||
'databaseUser' => $databaseUser,
|
||||
'--databasePassword' => $databasePassword,
|
||||
'--hostingMode' => null,
|
||||
'--forceInstall' => null
|
||||
]
|
||||
);
|
||||
|
||||
$commandTester = $this->executeCommandTest($inputData);
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Installation finished', $output);
|
||||
|
||||
$configData = self::$dic->get(Config::class)->getConfigData();
|
||||
|
||||
$this->assertEquals($configData->getDbUser(), $databaseUser);
|
||||
$this->assertEquals($configData->getDbPass(), $databasePassword);
|
||||
|
||||
// Cleanup database
|
||||
DatabaseUtil::dropDatabase(self::$commandInputData['databaseName']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function testInstallFromEnvironmentVarIsAbort(): void
|
||||
{
|
||||
$this->setEnvironmentVariables();
|
||||
|
||||
$commandTester = $this->executeCommandTest(null, false);
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Installation aborted', $output);
|
||||
}
|
||||
|
||||
private function setEnvironmentVariables(): void
|
||||
{
|
||||
putenv(sprintf('%s=%s',
|
||||
InstallCommand::$envVarsMapping['databaseHost'],
|
||||
getenv('DB_SERVER'))
|
||||
);
|
||||
putenv(sprintf('%s=%s',
|
||||
InstallCommand::$envVarsMapping['databaseUser'],
|
||||
getenv('DB_USER'))
|
||||
);
|
||||
putenv(sprintf('%s=%s',
|
||||
InstallCommand::$envVarsMapping['databasePassword'],
|
||||
getenv('DB_PASS'))
|
||||
);
|
||||
putenv(sprintf('%s=%s',
|
||||
InstallCommand::$envVarsMapping['databaseName'],
|
||||
self::$commandInputData['databaseName'])
|
||||
);
|
||||
putenv(sprintf('%s=%s',
|
||||
InstallCommand::$envVarsMapping['adminLogin'],
|
||||
self::$commandInputData['adminLogin'])
|
||||
);
|
||||
putenv(sprintf('%s=%s',
|
||||
InstallCommand::$envVarsMapping['adminPassword'],
|
||||
self::$commandInputData['--adminPassword'])
|
||||
);
|
||||
putenv(sprintf('%s=%s',
|
||||
InstallCommand::$envVarsMapping['masterPassword'],
|
||||
self::$commandInputData['--masterPassword'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function testInstallFromEnvironmentVarIsAbortedWithForce(): void
|
||||
{
|
||||
putenv(sprintf('%s=true',
|
||||
InstallCommand::$envVarsMapping['forceInstall'])
|
||||
);
|
||||
|
||||
$this->setEnvironmentVariables();
|
||||
|
||||
$commandTester = $this->executeCommandTest(null, false);
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Installation aborted', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DatabaseException
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function testInstallFromEnvironmentVarIsSuccessful(): void
|
||||
{
|
||||
putenv(sprintf('%s=true',
|
||||
InstallCommand::$envVarsMapping['forceInstall'])
|
||||
);
|
||||
putenv(sprintf('%s=true',
|
||||
InstallCommand::$envVarsMapping['install'])
|
||||
);
|
||||
|
||||
$this->setEnvironmentVariables();
|
||||
|
||||
$commandTester = $this->executeCommandTest(null, false);
|
||||
|
||||
// the output of the command in the console
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Installation finished', $output);
|
||||
|
||||
// Cleanup database
|
||||
DatabaseUtil::dropDatabase(self::$commandInputData['databaseName']);
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class AccountFileServiceTest extends DatabaseTestCase
|
||||
*/
|
||||
public function testCreate()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'imgs' . DIRECTORY_SEPARATOR . 'add.png';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'imgs' . DIRECTORY_SEPARATOR . 'add.png';
|
||||
$image = file_get_contents($file);
|
||||
|
||||
$data = new FileData();
|
||||
|
||||
@@ -67,7 +67,7 @@ class XmlVerifyServiceTest extends TestCase
|
||||
*/
|
||||
public function testVerifyEncrypted()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass_encrypted.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass_encrypted.xml';
|
||||
|
||||
$result = self::$xmlVerifyService->verifyEncrypted($file, 'test_encrypt');
|
||||
|
||||
@@ -90,7 +90,7 @@ class XmlVerifyServiceTest extends TestCase
|
||||
*/
|
||||
public function testVerify()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass.xml';
|
||||
|
||||
$result = self::$xmlVerifyService->verify($file);
|
||||
|
||||
@@ -109,17 +109,17 @@ class XmlVerifyServiceTest extends TestCase
|
||||
public function testCheckXmlHash()
|
||||
{
|
||||
$dom = new DOMDocument();
|
||||
$dom->load(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass_encrypted.xml');
|
||||
$dom->load(RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass_encrypted.xml');
|
||||
|
||||
$this->assertTrue(XmlVerifyService::checkXmlHash($dom, 'test_encrypt'));
|
||||
|
||||
$dom->load(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass_invalid.xml');
|
||||
$dom->load(RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass_invalid.xml');
|
||||
|
||||
$this->assertFalse(XmlVerifyService::checkXmlHash($dom, 'test_encrypt'));
|
||||
|
||||
$key = sha1('d5851082a3914a647a336d8910e24eb64b8f8adef24d27329040ebd0d4c1');
|
||||
|
||||
$dom->load(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass_valid_hash.xml');
|
||||
$dom->load(RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass_valid_hash.xml');
|
||||
|
||||
$this->assertTrue(XmlVerifyService::checkXmlHash($dom, $key));
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class CsvImportTest extends DatabaseTestCase
|
||||
*/
|
||||
public function testDoImport()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data.csv';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data.csv';
|
||||
|
||||
$params = new ImportParams();
|
||||
$params->setDefaultUser(1);
|
||||
@@ -170,7 +170,7 @@ class CsvImportTest extends DatabaseTestCase
|
||||
*/
|
||||
public function testDoImportInvalidData()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_invalid.csv';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_invalid.csv';
|
||||
|
||||
$params = new ImportParams();
|
||||
$params->setDefaultUser(1);
|
||||
|
||||
@@ -83,7 +83,7 @@ class KeepassImportTest extends DatabaseTestCase
|
||||
*/
|
||||
public function testDoImport()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_keepass.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_keepass.xml';
|
||||
|
||||
$params = new ImportParams();
|
||||
$params->setDefaultUser(1);
|
||||
|
||||
@@ -79,7 +79,7 @@ class SyspassImportTest extends DatabaseTestCase
|
||||
*/
|
||||
public function testDoImport()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass.xml';
|
||||
|
||||
$params = new ImportParams();
|
||||
$params->setDefaultUser(1);
|
||||
|
||||
@@ -44,13 +44,13 @@ class XmlFileImportTest extends TestCase
|
||||
*/
|
||||
public function testDetectXMLFormat()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass.xml';
|
||||
|
||||
$import = new XmlFileImport(FileImport::fromFilesystem($file));
|
||||
|
||||
$this->assertEquals('syspass', $import->detectXMLFormat());
|
||||
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_keepass.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_keepass.xml';
|
||||
|
||||
$import = new XmlFileImport(FileImport::fromFilesystem($file));
|
||||
|
||||
@@ -63,7 +63,7 @@ class XmlFileImportTest extends TestCase
|
||||
*/
|
||||
public function testInvalidFile()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data.csv';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data.csv';
|
||||
|
||||
$this->expectException(ImportException::class);
|
||||
|
||||
@@ -76,7 +76,7 @@ class XmlFileImportTest extends TestCase
|
||||
*/
|
||||
public function testEmptyFile()
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_empty.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_empty.xml';
|
||||
|
||||
$import = new XmlFileImport(FileImport::fromFilesystem($file));
|
||||
|
||||
|
||||
@@ -69,13 +69,13 @@ class XmlImportTest extends DatabaseTestCase
|
||||
$params->setDefaultUser(1);
|
||||
$params->setDefaultGroup(1);
|
||||
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass.xml';
|
||||
|
||||
$import = new XmlImport(self::$dic, new XmlFileImport(FileImport::fromFilesystem($file)), $params);
|
||||
|
||||
$this->assertEquals(5, $import->doImport()->getCounter());
|
||||
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_keepass.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_keepass.xml';
|
||||
|
||||
$import = new XmlImport(self::$dic, new XmlFileImport(FileImport::fromFilesystem($file)), $params);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class ArchiveHandlerTest extends TestCase
|
||||
$archive = TMP_PATH . DIRECTORY_SEPARATOR . 'test_archive_file';
|
||||
|
||||
$handler = new ArchiveHandler($archive, new PhpExtensionChecker());
|
||||
$handler->compressFile(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.xml');
|
||||
$handler->compressFile(RESOURCE_PATH . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.xml');
|
||||
|
||||
$this->assertFileExists($archive . ArchiveHandler::COMPRESS_EXTENSION);
|
||||
}
|
||||
@@ -66,7 +66,7 @@ class ArchiveHandlerTest extends TestCase
|
||||
$archive = TMP_PATH . DIRECTORY_SEPARATOR . 'test_archive_file';
|
||||
|
||||
$handler = new ArchiveHandler($archive, new PhpExtensionChecker());
|
||||
$handler->compressFile(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'non_existant_file');
|
||||
$handler->compressFile(RESOURCE_PATH . DIRECTORY_SEPARATOR . 'non_existant_file');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +78,7 @@ class ArchiveHandlerTest extends TestCase
|
||||
$archive = TMP_PATH . DIRECTORY_SEPARATOR . 'test_archive_dir';
|
||||
|
||||
$handler = new ArchiveHandler($archive, new PhpExtensionChecker());
|
||||
$handler->compressDirectory(RESOURCE_DIR);
|
||||
$handler->compressDirectory(RESOURCE_PATH);
|
||||
|
||||
$this->assertFileExists($archive . ArchiveHandler::COMPRESS_EXTENSION);
|
||||
}
|
||||
@@ -94,7 +94,7 @@ class ArchiveHandlerTest extends TestCase
|
||||
$archive = TMP_PATH . DIRECTORY_SEPARATOR . 'test_archive_dir';
|
||||
|
||||
$handler = new ArchiveHandler($archive, new PhpExtensionChecker());
|
||||
$handler->compressDirectory(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'non_existant_dir');
|
||||
$handler->compressDirectory(RESOURCE_PATH . DIRECTORY_SEPARATOR . 'non_existant_dir');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,15 +40,15 @@ class FileHandlerTest extends TestCase
|
||||
/**
|
||||
* @var string Archvivo de prueba válido
|
||||
*/
|
||||
protected static $validFile = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'valid_file.test';
|
||||
protected static $validFile = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'valid_file.test';
|
||||
/**
|
||||
* @var string Archvivo de prueba inmutable
|
||||
*/
|
||||
protected static $immutableFile = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'immutable_file.test';
|
||||
protected static $immutableFile = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'immutable_file.test';
|
||||
/**
|
||||
* @var string Archivo de prueba no existente
|
||||
*/
|
||||
protected static $missingFile = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'missing_file.test';
|
||||
protected static $missingFile = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'missing_file.test';
|
||||
|
||||
/**
|
||||
* Comprobar la escritura de texto en un archivo
|
||||
|
||||
@@ -55,7 +55,7 @@ class XmlHandlerTest extends TestCase
|
||||
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
$file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'config.xml';
|
||||
$file = RESOURCE_PATH . DIRECTORY_SEPARATOR . 'config.xml';
|
||||
self::$xmlHandler = new XmlHandler(new FileHandler($file));
|
||||
|
||||
self::$itemsData = new stdClass();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
@@ -19,7 +19,7 @@
|
||||
* 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/>.
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Tests;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
|
||||
* @author nuxsmin
|
||||
* @link https://syspass.org
|
||||
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
@@ -19,7 +19,7 @@
|
||||
* 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/>.
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace SP\Tests;
|
||||
@@ -41,21 +41,23 @@ define('APP_MODULE', 'tests');
|
||||
|
||||
define('APP_ROOT', dirname(__DIR__, 2));
|
||||
define('TEST_ROOT', dirname(__DIR__));
|
||||
define('RESOURCE_DIR', TEST_ROOT . DIRECTORY_SEPARATOR . 'res');
|
||||
define('CONFIG_PATH', RESOURCE_DIR . DIRECTORY_SEPARATOR . 'config');
|
||||
define('RESOURCE_PATH', TEST_ROOT . DIRECTORY_SEPARATOR . 'res');
|
||||
define('CONFIG_PATH', RESOURCE_PATH . DIRECTORY_SEPARATOR . 'config');
|
||||
define('CONFIG_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'config.xml');
|
||||
define('ACTIONS_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'actions.xml');
|
||||
|
||||
define('MODULES_PATH', APP_ROOT. DIRECTORY_SEPARATOR. 'app' . DIRECTORY_SEPARATOR . 'modules');
|
||||
define('SQL_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'schemas');
|
||||
define('CACHE_PATH', RESOURCE_DIR . DIRECTORY_SEPARATOR . 'cache');
|
||||
define('CACHE_PATH', RESOURCE_PATH . DIRECTORY_SEPARATOR . 'cache');
|
||||
define('TMP_PATH', TEST_ROOT . DIRECTORY_SEPARATOR . 'tmp');
|
||||
|
||||
|
||||
define('XML_SCHEMA', APP_ROOT . DIRECTORY_SEPARATOR . 'schemas' . DIRECTORY_SEPARATOR . 'syspass.xsd');
|
||||
|
||||
define('LOG_FILE', TMP_PATH . DIRECTORY_SEPARATOR . 'test.log');
|
||||
define('FIXTURE_FILES', [
|
||||
RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'truncate.sql',
|
||||
RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass.sql'
|
||||
RESOURCE_PATH . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'truncate.sql',
|
||||
RESOURCE_PATH . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass.sql'
|
||||
]);
|
||||
define('SELF_IP_ADDRESS', getRealIpAddress());
|
||||
define('SELF_HOSTNAME', gethostbyaddr(SELF_IP_ADDRESS));
|
||||
@@ -170,7 +172,7 @@ function getDbHandler(DatabaseConnectionData $connectionData = null): MySQLHandl
|
||||
*/
|
||||
function getResource($dir, $file): string
|
||||
{
|
||||
return file_get_contents(RESOURCE_DIR . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $file) ?: '';
|
||||
return file_get_contents(RESOURCE_PATH . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $file) ?: '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +184,7 @@ function getResource($dir, $file): string
|
||||
*/
|
||||
function saveResource($dir, $file, $data): string
|
||||
{
|
||||
return file_put_contents(RESOURCE_DIR . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $file, $data);
|
||||
return file_put_contents(RESOURCE_PATH . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $file, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,7 +195,9 @@ function recreateDir($dir)
|
||||
if (!is_dir($dir)) {
|
||||
print 'Creating ' . $dir . PHP_EOL;
|
||||
|
||||
mkdir($dir);
|
||||
if (!mkdir($dir) && !is_dir($dir)) {
|
||||
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
|
||||
}
|
||||
} else {
|
||||
print 'Deleting ' . $dir . PHP_EOL;
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
<testsuite name="Modules">
|
||||
<directory suffix=".php">./SP/Modules</directory>
|
||||
</testsuite>
|
||||
<testsuite name="cli">
|
||||
<directory suffix=".php">./SP/Modules/Cli</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
|
||||
Reference in New Issue
Block a user