diff --git a/app/modules/web/Controllers/ConfigManagerController.php b/app/modules/web/Controllers/ConfigManagerController.php index 4d6beda3..5e81c481 100644 --- a/app/modules/web/Controllers/ConfigManagerController.php +++ b/app/modules/web/Controllers/ConfigManagerController.php @@ -43,7 +43,7 @@ use SP\Services\User\UserService; use SP\Services\UserGroup\UserGroupService; use SP\Services\UserProfile\UserProfileService; use SP\Storage\Database\DatabaseUtil; -use SP\Storage\Database\MySQLHandler; +use SP\Storage\Database\DBStorageInterface; use SP\Util\Checks; use SP\Util\Util; @@ -331,7 +331,7 @@ final class ConfigManagerController extends ControllerBase $template->setBase('config'); $template->addTemplate('info'); - $template->assign('dbInfo', DatabaseUtil::getDBinfo($this->dic->get(MySQLHandler::class))); + $template->assign('dbInfo', DatabaseUtil::getDBinfo($this->dic->get(DBStorageInterface::class))); $template->assign('dbName', $this->configData->getDbName() . '@' . $this->configData->getDbHost()); $template->assign('configBackupDate', date('r', $this->dic->get(ConfigService::class)->getByParam('config_backup_date', 0))); $template->assign('plugins', $this->dic->get(PluginManager::class)->getLoadedPlugins()); diff --git a/lib/Base.php b/lib/Base.php index 158c716e..51332126 100644 --- a/lib/Base.php +++ b/lib/Base.php @@ -23,7 +23,6 @@ */ use DI\ContainerBuilder; -use Doctrine\Common\Cache\ArrayCache; use SP\Bootstrap; require __DIR__ . DIRECTORY_SEPARATOR . 'BaseFunctions.php'; @@ -67,7 +66,6 @@ initModule(APP_MODULE); try { $builder = new ContainerBuilder(); - $builder->setDefinitionCache(new ArrayCache()); $builder->writeProxiesToFile(true, CACHE_PATH . DIRECTORY_SEPARATOR . 'proxies'); $builder->addDefinitions(BASE_PATH . DIRECTORY_SEPARATOR . 'Definitions.php'); diff --git a/lib/Definitions.php b/lib/Definitions.php index 44b14f3b..4b5ae86d 100644 --- a/lib/Definitions.php +++ b/lib/Definitions.php @@ -22,13 +22,29 @@ * along with sysPass. If not, see . */ +use Monolog\Logger; +use PHPMailer\PHPMailer\PHPMailer; +use Psr\Container\ContainerInterface; +use SP\Config\Config; +use SP\Config\ConfigData; +use SP\Core\Acl\Acl; +use SP\Core\Acl\Actions; +use SP\Core\Context\ContextInterface; +use SP\Core\UI\Theme; +use SP\Http\Request; +use SP\Services\Account\AccountAclService; +use SP\Storage\Database\DatabaseConnectionData; +use SP\Storage\Database\DBStorageInterface; +use SP\Storage\Database\MySQLHandler; +use SP\Storage\File\FileCache; +use SP\Storage\File\FileHandler; +use SP\Storage\File\XmlHandler; use function DI\get; -use function DI\object; return [ - \Klein\Klein::class => object(\Klein\Klein::class), - \SP\Http\Request::class => object(\SP\Http\Request::class)->constructor(\Klein\Request::createFromGlobals()), - \SP\Core\Context\ContextInterface::class => function (\Interop\Container\ContainerInterface $c) { + Request::class => \DI\create(Request::class) + ->constructor(\Klein\Request::createFromGlobals()), + ContextInterface::class => function (ContainerInterface $c) { switch (APP_MODULE) { case 'web': return $c->get(\SP\Core\Context\SessionContext::class); @@ -36,34 +52,24 @@ return [ return $c->get(\SP\Core\Context\StatelessContext::class); } }, - \SP\Config\Config::class => object(\SP\Config\Config::class) - ->constructor(object(\SP\Storage\File\XmlHandler::class) - ->constructor(object(\SP\Storage\File\FileHandler::class) - ->constructor(CONFIG_FILE)), get(\SP\Core\Context\ContextInterface::class)), - \SP\Core\Language::class => object(\SP\Core\Language::class), - \SP\Config\ConfigData::class => function (\SP\Config\Config $config) { + Config::class => function (ContainerInterface $c) { + return new Config(new XmlHandler(new FileHandler(CONFIG_FILE)), $c->get(ContextInterface::class), $c); + }, + ConfigData::class => function (Config $config) { return $config->getConfigData(); }, - \SP\Storage\Database\DatabaseConnectionData::class => function (\SP\Config\ConfigData $configData) { - return \SP\Storage\Database\DatabaseConnectionData::getFromConfig($configData); + DBStorageInterface::class => \DI\create(MySQLHandler::class) + ->constructor(\DI\factory([DatabaseConnectionData::class, 'getFromConfig'])), + Actions::class => function (ContainerInterface $c) { + return new Actions($c->get(FileCache::class), new XmlHandler(new FileHandler(ACTIONS_FILE))); }, - \SP\Storage\Database\Database::class => object(\SP\Storage\Database\Database::class) - ->constructor(object(\SP\Storage\Database\MySQLHandler::class) - ->constructor(get(\SP\Storage\Database\DatabaseConnectionData::class))), - \SP\Core\Acl\Actions::class => object(\SP\Core\Acl\Actions::class) - ->constructor(object(\SP\Storage\File\FileCache::class), object(\SP\Storage\File\XmlHandler::class) - ->constructor(object(\SP\Storage\File\FileHandler::class) - ->constructor(ACTIONS_FILE))), - \SP\Core\Events\EventDispatcher::class => object(\SP\Core\Events\EventDispatcher::class), - \SP\Core\Acl\Acl::class => object(\SP\Core\Acl\Acl::class) - ->constructor(get(\SP\Core\Context\ContextInterface::class), get(\SP\Core\Events\EventDispatcher::class), get(\SP\Core\Acl\Actions::class)), - \SP\Core\UI\Theme::class => object(\SP\Core\UI\Theme::class) - ->constructor(APP_MODULE, get(\SP\Config\Config::class), get(\SP\Core\Context\ContextInterface::class)), - \PHPMailer\PHPMailer\PHPMailer::class => object(\PHPMailer\PHPMailer\PHPMailer::class) + Acl::class => \DI\autowire(Acl::class) + ->constructorParameter('action', get(Actions::class)), + Theme::class => \DI\autowire(Theme::class) + ->constructorParameter('module', APP_MODULE), + PHPMailer::class => \DI\create(PHPMailer::class) ->constructor(true), - \Monolog\Logger::class => object(\Monolog\Logger::class) + Logger::class => \DI\create(Logger::class) ->constructor('syspass'), - \SP\Services\Account\AccountAclService::class => function (\Interop\Container\ContainerInterface $c) { - return new \SP\Services\Account\AccountAclService($c); - } + AccountAclService::class => \DI\autowire(AccountAclService::class) ]; \ No newline at end of file diff --git a/lib/SP/Services/Install/DatabaseSetupInterface.php b/lib/SP/Services/Install/DatabaseSetupInterface.php index e5f385de..6192cba0 100644 --- a/lib/SP/Services/Install/DatabaseSetupInterface.php +++ b/lib/SP/Services/Install/DatabaseSetupInterface.php @@ -24,6 +24,8 @@ namespace SP\Services\Install; +use SP\Storage\Database\DBStorageInterface; + /** * Interface DatabaseInterface * @@ -79,4 +81,14 @@ interface DatabaseSetupInterface * Comprobar la conexión a la BBDD */ public function checkConnection(); + + /** + * @return DBStorageInterface + */ + public function getDbHandler(): DBStorageInterface; + + /** + * @return DBStorageInterface + */ + public function createDbHandlerFromInstaller(): DBStorageInterface; } \ No newline at end of file diff --git a/lib/SP/Services/Install/Installer.php b/lib/SP/Services/Install/Installer.php index 71368e9c..46c7b208 100644 --- a/lib/SP/Services/Install/Installer.php +++ b/lib/SP/Services/Install/Installer.php @@ -39,7 +39,7 @@ use SP\Services\Service; use SP\Services\User\UserService; use SP\Services\UserGroup\UserGroupService; use SP\Services\UserProfile\UserProfileService; -use SP\Storage\Database\DatabaseConnectionData; +use SP\Storage\Database\DBStorageInterface; use SP\Util\Util; defined('APP_ROOT') || die(); @@ -56,14 +56,10 @@ final class Installer extends Service const VERSION_TEXT = '3.0-beta'; const BUILD = 18072902; - /** - * @var ConfigService - */ - protected $configService; /** * @var DatabaseSetupInterface */ - protected $dbs; + private $dbs; /** * @var Request */ @@ -182,13 +178,14 @@ final class Installer extends Service $this->setupConfig(); $this->setupDb(); - $this->setupDBConnectionData(); + $this->updateConnectionData(); $this->saveMasterPassword(); $this->createAdminAccount(); $version = Util::getVersionStringNormalized(); - $this->configService->create(new \SP\DataModel\ConfigData('version', $version)); + $this->dic->get(ConfigService::class) + ->create(new \SP\DataModel\ConfigData('version', $version)); $this->configData->setInstalled(true); @@ -282,13 +279,13 @@ final class Installer extends Service } /** - * Setup database connection for sysPass + * Setup database connection for sysPass. + * + * Updates the database storage interface in the dependency container */ - private function setupDBConnectionData() + private function updateConnectionData() { - // FIXME: ugly!! - $this->dic->get(DatabaseConnectionData::class) - ->refreshFromConfig($this->configData); + $this->dic->set(DBStorageInterface::class, $this->dbs->createDbHandlerFromInstaller()); } /** @@ -299,8 +296,13 @@ final class Installer extends Service private function saveMasterPassword() { try { - $this->configService->create(new \SP\DataModel\ConfigData('masterPwd', Hash::hashKey($this->installData->getMasterPassword()))); - $this->configService->create(new \SP\DataModel\ConfigData('lastupdatempass', time())); + // This service needs to be called after a successful database setup, since + // DI container stores the definition on its first call, so it would contain + // an incomplete database setup + $configService = $this->dic->get(ConfigService::class); + + $configService->create(new \SP\DataModel\ConfigData('masterPwd', Hash::hashKey($this->installData->getMasterPassword()))); + $configService->create(new \SP\DataModel\ConfigData('lastupdatempass', time())); } catch (\Exception $e) { processException($e); @@ -373,7 +375,6 @@ final class Installer extends Service protected function initialize() { $this->configData = $this->config->getConfigData(); - $this->configService = $this->dic->get(ConfigService::class); $this->request = $this->dic->get(Request::class); } } \ No newline at end of file diff --git a/lib/SP/Services/Install/MySQL.php b/lib/SP/Services/Install/MySQL.php index 16e6a51a..010b2b7e 100644 --- a/lib/SP/Services/Install/MySQL.php +++ b/lib/SP/Services/Install/MySQL.php @@ -29,6 +29,7 @@ use SP\Config\ConfigData; use SP\Core\Exceptions\SPException; use SP\Storage\Database\DatabaseConnectionData; use SP\Storage\Database\DatabaseUtil; +use SP\Storage\Database\DBStorageInterface; use SP\Storage\Database\MySQLFileParser; use SP\Storage\Database\MySQLHandler; use SP\Storage\File\FileHandler; @@ -48,7 +49,7 @@ final class MySQL implements DatabaseSetupInterface /** * @var \SP\Storage\Database\MySQLHandler */ - protected $dbs; + protected $mysqlHandler; /** * @var ConfigData */ @@ -88,8 +89,8 @@ final class MySQL implements DatabaseSetupInterface ->setDbUser($this->installData->getDbAdminUser()) ->setDbPass($this->installData->getDbAdminPass()); - $this->dbs = new MySQLHandler($dbc); - $this->dbs->getConnectionSimple(); + $this->mysqlHandler = new MySQLHandler($dbc); + $this->mysqlHandler->getConnectionSimple(); } catch (SPException $e) { processException($e); @@ -113,7 +114,7 @@ final class MySQL implements DatabaseSetupInterface try { // Comprobar si el usuario proporcionado existe - $sth = $this->dbs->getConnectionSimple() + $sth = $this->mysqlHandler->getConnectionSimple() ->prepare('SELECT COUNT(*) FROM mysql.user WHERE `user` = ? AND (`host` = ? OR `host` = ?)'); $sth->execute([ @@ -163,7 +164,7 @@ final class MySQL implements DatabaseSetupInterface try { $query = 'CREATE USER %s@`%s` IDENTIFIED BY %s'; - $dbc = $this->dbs->getConnectionSimple(); + $dbc = $this->mysqlHandler->getConnectionSimple(); $dbc->exec(sprintf($query, $dbc->quote($user), $this->installData->getDbAuthHost(), $dbc->quote($pass))); @@ -203,7 +204,7 @@ final class MySQL implements DatabaseSetupInterface } try { - $dbc = $this->dbs->getConnectionSimple(); + $dbc = $this->mysqlHandler->getConnectionSimple(); $dbc->exec('CREATE SCHEMA `' . $this->installData->getDbName() . '` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci'); } catch (PDOException $e) { @@ -242,7 +243,7 @@ final class MySQL implements DatabaseSetupInterface } else { try { // Commprobar si existe al seleccionarla - $this->dbs->getConnectionSimple() + $this->mysqlHandler->getConnectionSimple() ->exec('USE `' . $this->installData->getDbName() . '`'); } catch (PDOException $e) { throw new SPException( @@ -262,7 +263,7 @@ final class MySQL implements DatabaseSetupInterface */ public function checkDatabaseExist() { - $sth = $this->dbs->getConnectionSimple() + $sth = $this->mysqlHandler->getConnectionSimple() ->prepare('SELECT COUNT(*) FROM information_schema.schemata WHERE `schema_name` = ? LIMIT 1'); $sth->execute([$this->installData->getDbName()]); @@ -274,7 +275,7 @@ final class MySQL implements DatabaseSetupInterface */ public function rollback() { - $dbc = $this->dbs->getConnectionSimple(); + $dbc = $this->mysqlHandler->getConnectionSimple(); if ($this->installData->isHostingMode()) { foreach (DatabaseUtil::$tables as $table) { @@ -308,7 +309,7 @@ final class MySQL implements DatabaseSetupInterface } try { - $dbc = $this->dbs->getConnectionSimple(); + $dbc = $this->mysqlHandler->getConnectionSimple(); // Usar la base de datos de sysPass $dbc->exec('USE `' . $this->installData->getDbName() . '`'); @@ -352,7 +353,7 @@ final class MySQL implements DatabaseSetupInterface */ public function checkConnection() { - if (!DatabaseUtil::checkDatabaseExist($this->dbs, $this->installData->getDbName())) { + if (!DatabaseUtil::checkDatabaseExist($this->mysqlHandler, $this->installData->getDbName())) { $this->rollback(); throw new SPException( @@ -364,10 +365,18 @@ final class MySQL implements DatabaseSetupInterface } /** - * @return MySQLHandler + * @return DBStorageInterface */ - public function getDbs(): MySQLHandler + public function getDbHandler(): DBStorageInterface { - return $this->dbs; + return $this->mysqlHandler; + } + + /** + * @return DBStorageInterface + */ + public function createDbHandlerFromInstaller(): DBStorageInterface + { + return new MySQLHandler(DatabaseConnectionData::getFromConfig($this->configData)); } } \ No newline at end of file diff --git a/test/SP/DatabaseTestCase.php b/test/SP/DatabaseTestCase.php index 5a06fdc1..dae13f78 100644 --- a/test/SP/DatabaseTestCase.php +++ b/test/SP/DatabaseTestCase.php @@ -29,7 +29,6 @@ use PHPUnit\DbUnit\DataSet\IDataSet; use PHPUnit\DbUnit\TestCaseTrait; use PHPUnit\Framework\TestCase; use SP\Storage\Database\DatabaseConnectionData; -use SP\Storage\Database\MySQLHandler; /** * Class DatabaseBaseTest @@ -69,7 +68,7 @@ abstract class DatabaseTestCase extends TestCase { if ($this->conn === null) { if (self::$pdo === null) { - self::$pdo = (new MySQLHandler(self::$databaseConnectionData))->getConnection(); + self::$pdo = getDbHandler()->getConnection(); } $this->conn = $this->createDefaultDBConnection(self::$pdo, 'syspass'); diff --git a/test/SP/Services/Install/DbTestUtilTrait.php b/test/SP/Services/Install/DbTestUtilTrait.php index 7e663ff8..eb677690 100644 --- a/test/SP/Services/Install/DbTestUtilTrait.php +++ b/test/SP/Services/Install/DbTestUtilTrait.php @@ -25,7 +25,7 @@ namespace SP\Tests\Services\Install; use SP\Storage\Database\DatabaseConnectionData; -use SP\Storage\Database\MySQLHandler; +use function SP\Test\getDbHandler; /** * Trait DbTestUtilTrait @@ -56,7 +56,7 @@ trait DbTestUtilTrait ->setDbUser(getenv('DB_USER')) ->setDbPass(getenv('DB_PASS')); - return (new MySQLHandler($data))->getConnectionSimple(); + return getDbHandler($data)->getConnectionSimple(); } /** diff --git a/test/SP/Services/Install/InstallerTest.php b/test/SP/Services/Install/InstallerTest.php index 6eb978b1..e0854ebd 100644 --- a/test/SP/Services/Install/InstallerTest.php +++ b/test/SP/Services/Install/InstallerTest.php @@ -32,7 +32,7 @@ use SP\Services\Crypt\MasterPassService; use SP\Services\Install\InstallData; use SP\Services\Install\Installer; use SP\Storage\Database\DatabaseUtil; -use SP\Storage\Database\MySQLHandler; +use SP\Storage\Database\DBStorageInterface; use SP\Util\Util; use function SP\Test\getResource; use function SP\Test\saveResource; @@ -285,7 +285,7 @@ class InstallerTest extends TestCase $installer = self::$dic->get(Installer::class); $installer->run($params); - $this->assertTrue(DatabaseUtil::checkDatabaseExist(self::$dic->get(MySQLHandler::class), self::DB_NAME)); + $this->assertTrue(DatabaseUtil::checkDatabaseExist(self::$dic->get(DBStorageInterface::class), self::DB_NAME)); $configData = self::$dic->get(Config::class)->getConfigData(); diff --git a/test/SP/Services/Install/MySQLTest.php b/test/SP/Services/Install/MySQLTest.php index 2a708dd9..18bb76d2 100644 --- a/test/SP/Services/Install/MySQLTest.php +++ b/test/SP/Services/Install/MySQLTest.php @@ -155,19 +155,18 @@ class MySQLTest extends TestCase $mysql = new MySQL($this->getParams(), new ConfigData()); $mysql->connectDatabase(); - $this->assertInstanceOf(MySQLHandler::class, $mysql->getDbs()); + $this->assertInstanceOf(MySQLHandler::class, $mysql->getDbHandler()); } /** * @throws \SP\Core\Exceptions\SPException - * @throws \SP\Storage\Database\DatabaseException */ public function testCreateDBUser() { $mysql = new MySQL($this->getParams(), new ConfigData()); $mysql->createDBUser('test', Util::randomPassword()); - $num = (int)$mysql->getDbs() + $num = (int)$mysql->getDbHandler() ->getConnectionSimple() ->query('SELECT COUNT(*) FROM mysql.user WHERE `User` = \'test\'') ->fetchColumn(0); diff --git a/test/SP/bootstrap.php b/test/SP/bootstrap.php index c10aeacd..34ecff33 100644 --- a/test/SP/bootstrap.php +++ b/test/SP/bootstrap.php @@ -30,6 +30,8 @@ use SP\Core\Context\ContextInterface; use SP\DataModel\ProfileData; use SP\Services\User\UserLoginResponse; use SP\Storage\Database\DatabaseConnectionData; +use SP\Storage\Database\DBStorageInterface; +use SP\Storage\Database\MySQLHandler; define('DEBUG', true); @@ -106,6 +108,7 @@ function getRealIpAddress() * @throws \DI\NotFoundException * @throws \SP\Core\Context\ContextException * @return \DI\Container + * @throws \Exception */ function setupContext() { @@ -136,22 +139,34 @@ function setupContext() $context->setUserProfile(new ProfileData()); - // Establecer configuración de conexión con la BBDD - $connectionData = (new DatabaseConnectionData()) - ->setDbHost(getenv('DB_SERVER')) - ->setDbName(getenv('DB_NAME')) - ->setDbUser(getenv('DB_USER')) - ->setDbPass(getenv('DB_PASS')); - // Inicializar la configuración // $dic->set(ConfigData::class, $configData); // Inicializar los datos de conexión a la BBDD - $dic->set(DatabaseConnectionData::class, $connectionData); + $dic->set(DBStorageInterface::class, getDbHandler()); return $dic; } +/** + * @param DatabaseConnectionData|null $connectionData + * + * @return MySQLHandler + */ +function getDbHandler(DatabaseConnectionData $connectionData = null) +{ + if ($connectionData === null) { + // Establecer configuración de conexión con la BBDD + $connectionData = (new DatabaseConnectionData()) + ->setDbHost(getenv('DB_SERVER')) + ->setDbName(getenv('DB_NAME')) + ->setDbUser(getenv('DB_USER')) + ->setDbPass(getenv('DB_PASS')); + } + + return new MySQLHandler($connectionData); +} + /** * @param $dir * @param $file diff --git a/test/res/config/config.xml b/test/res/config/config.xml index 6d7bb5ba..479fbde6 100644 --- a/test/res/config/config.xml +++ b/test/res/config/config.xml @@ -9,11 +9,11 @@ 1 1 - 65c8e31affc8e8f2820c5fc94eead8350fcc7a56 + 33bb2a2d4b6c9bf4ebbfdaee0c4ca06d3a5a92b2 0 0 - 1532898640 - f747bcab91559dc32cfcfd7c244eeff5ef44a73d + 1532978841 + e88b62370abe8f1624ec99ef3b6d232069c66abc @@ -32,7 +32,7 @@ 0 - fb471cf4837588a15f094a50a230cc7cdf9ea01c + d83589349e88e7b236e58adc41187ac8370c9fb4 PDF JPG