0byt3m1n1
Path:
/
data
/
applications
/
aps
/
typo3
/
12.4.7
/
standard
/
scripts
/
[
Home
]
File: PermissionsCheck.php
<?php declare(strict_types=1); /* * This file is part of the TYPO3 CMS project. * * It is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, either version 2 * of the License, or any later version. * * For the full copyright and license information, please read the * LICENSE.txt file that was distributed with this source code. * * The TYPO3 project - inspiring people to share! */ namespace TYPO3\CMS\Install\Database; use Doctrine\DBAL\Schema\AbstractSchemaManager; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Install\Configuration\Exception; /** * Check all required permissions within the install process. * @internal This is NOT an API class, it is for internal use in the install tool only. */ class PermissionsCheck { private $testTableName = 't3install_test_table'; private $messages = []; public function checkCreateAndDrop(): self { $tableCreated = $this->checkCreateTable($this->testTableName); if (!$tableCreated) { $this->messages[] = 'The database user needs CREATE permissions.'; } $tableDropped = $this->checkDropTable($this->testTableName); if (!$tableDropped) { $this->messages[] = 'The database user needs DROP permissions.'; } if ($tableCreated && !$tableDropped) { $this->messages[] = sprintf('Attention: A test table with name "%s" was created but could not be deleted, please remove the table manually!', $this->testTableName); } if (!$tableCreated || !$tableDropped) { throw new Exception('A test table could not be created or dropped, skipping all further checks now', 1590850369); } return $this; } public function checkAlter(): self { $this->checkCreateTable($this->testTableName); $connection = $this->getConnection(); $schemaCurrent = $this->createSchemaManager()->createSchema(); $schemaNew = $this->createSchemaManager()->createSchema(); $schemaCurrent ->getTable($this->testTableName) ->addColumn('index_test', 'integer', ['unsigned' => true]); $platform = $connection->getDatabasePlatform(); try { foreach ($schemaNew->getMigrateToSql($schemaCurrent, $platform) as $query) { $connection->executeQuery($query); } } catch (\Exception $e) { $this->messages[] = 'The database user needs ALTER permission'; } $this->checkDropTable($this->testTableName); return $this; } public function checkIndex(): self { if ($this->checkCreateTable($this->testTableName)) { $connection = $this->getConnection(); $schemaCurrent = $this->createSchemaManager()->createSchema(); $schemaNew = $this->createSchemaManager()->createSchema(); $testTable = $schemaCurrent->getTable($this->testTableName); $testTable->addColumn('index_test', 'integer', ['unsigned' => true]); $testTable->addIndex(['index_test'], 'test_index'); $platform = $connection->getDatabasePlatform(); try { foreach ($schemaNew->getMigrateToSql($schemaCurrent, $platform) as $query) { $connection->executeQuery($query); } } catch (\Exception $e) { $this->checkDropTable($this->testTableName); $this->messages[] = 'The database user needs INDEX permission'; } $this->checkDropTable($this->testTableName); } return $this; } public function checkCreateTemporaryTable(): self { $this->checkCreateTable($this->testTableName); $connection = $this->getConnection(); try { $sql = 'CREATE TEMPORARY TABLE %s AS (SELECT id FROM %s )'; $connection->exec(sprintf($sql, $this->testTableName . '_tmp', $this->testTableName)); } catch (\Exception $e) { $this->messages[] = 'The database user needs CREATE TEMPORARY TABLE permission'; } $this->checkDropTable($this->testTableName); return $this; } public function checkSelect(): self { $this->checkCreateTable($this->testTableName); $connection = $this->getConnection(); try { $connection->insert($this->testTableName, ['id' => 1]); $connection->select(['id'], $this->testTableName); } catch (\Exception $e) { $this->messages[] = 'The database user needs SELECT permission'; } $this->checkDropTable($this->testTableName); return $this; } public function checkInsert(): self { $this->checkCreateTable($this->testTableName); $connection = $this->getConnection(); try { $connection->insert($this->testTableName, ['id' => 1]); } catch (\Exception $e) { $this->messages[] = 'The database user needs INSERT permission'; } $this->checkDropTable($this->testTableName); return $this; } public function checkUpdate(): self { $this->checkCreateTable($this->testTableName); $connection = $this->getConnection(); try { $connection->insert($this->testTableName, ['id' => 1]); $connection->update($this->testTableName, ['id' => 2], ['id' => 1]); } catch (\Exception $e) { $this->messages[] = 'The database user needs UPDATE permission'; } $this->checkDropTable($this->testTableName); return $this; } public function checkDelete(): self { $this->checkCreateTable($this->testTableName); $connection = $this->getConnection(); try { $connection->insert($this->testTableName, ['id' => 1]); $connection->delete($this->testTableName, ['id' => 1]); } catch (\Exception $e) { $this->messages[] = 'The database user needs DELETE permission'; } $this->checkDropTable($this->testTableName); return $this; } public function getMessages(): array { return $this->messages; } private function checkCreateTable(string $tablename): bool { $connection = $this->getConnection(); $schema = $connection->createSchemaManager()->createSchema(); $testTable = $schema->createTable($tablename); $testTable->addColumn('id', 'integer', ['unsigned' => true]); $testTable->setPrimaryKey(['id']); $platform = $connection->getDatabasePlatform(); try { foreach ($schema->toSql($platform) as $query) { $connection->executeQuery($query); } } catch (\Exception $e) { $this->messages[] = 'The database user needs CREATE TABLE permission'; return false; } sleep(5); // Lets database to replicate return true; } private function checkDropTable(string $tablename): bool { $connection = $this->getConnection(); try { $schemaCurrent = $connection->createSchemaManager()->createSchema(); $schemaNew = $connection->createSchemaManager()->createSchema(); $schemaNew->dropTable($tablename); $platform = $connection->getDatabasePlatform(); foreach ($schemaCurrent->getMigrateToSql($schemaNew, $platform) as $query) { $connection->executeQuery($query); } } catch (\Exception $e) { $this->messages[] = 'The database user needs DROP TABLE permission'; return false; } sleep(5); // Lets datatabase to replicate return true; } private function getConnection(): Connection { return GeneralUtility::makeInstance(ConnectionPool::class) ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME); } private function createSchemaManager(): AbstractSchemaManager { return $this->getConnection()->createSchemaManager(); } }