fix: Use DI for Setup class and move away from deprecated methods

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
Côme Chilliet 2024-01-29 15:12:53 +01:00
parent c1e5ebaed5
commit ccc66e912b
No known key found for this signature in database
GPG Key ID: A3E2F658B28C760A
6 changed files with 124 additions and 184 deletions

View File

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@ -33,12 +36,9 @@ namespace OC\Core\Command\Maintenance;
use bantu\IniGetWrapper\IniGetWrapper;
use InvalidArgumentException;
use OC\Console\TimestampFormatter;
use OC\Installer;
use OC\Migration\ConsoleOutput;
use OC\Setup;
use OC\SystemConfig;
use OCP\Defaults;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
@ -56,7 +56,7 @@ class Install extends Command {
parent::__construct();
}
protected function configure() {
protected function configure(): void {
$this
->setName('maintenance:install')
->setDescription('install Nextcloud')
@ -76,15 +76,7 @@ class Install extends Command {
protected function execute(InputInterface $input, OutputInterface $output): int {
// validate the environment
$server = \OC::$server;
$setupHelper = new Setup(
$this->config,
$this->iniGetWrapper,
$server->getL10N('lib'),
$server->query(Defaults::class),
$server->get(LoggerInterface::class),
$server->getSecureRandom(),
\OC::$server->query(Installer::class)
);
$setupHelper = \OCP\Server::get(\OC\Setup::class);
$sysInfo = $setupHelper->getSystemInfo(true);
$errors = $sysInfo['errors'];
if (count($errors) > 0) {

View File

@ -988,17 +988,7 @@ class OC {
// Check if Nextcloud is installed or in maintenance (update) mode
if (!$systemConfig->getValue('installed', false)) {
\OC::$server->getSession()->clear();
$logger = Server::get(\Psr\Log\LoggerInterface::class);
$setupHelper = new OC\Setup(
$systemConfig,
Server::get(\bantu\IniGetWrapper\IniGetWrapper::class),
Server::get(\OCP\L10N\IFactory::class)->get('lib'),
Server::get(\OCP\Defaults::class),
$logger,
Server::get(\OCP\Security\ISecureRandom::class),
Server::get(\OC\Installer::class)
);
$controller = new OC\Core\Controller\SetupController($setupHelper, $logger);
$controller = Server::get(\OC\Core\Controller\SetupController::class);
$controller->run($_POST);
exit();
}

View File

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @copyright Copyright (c) 2016, Lukas Reschke <lukas@statuscode.ch>

View File

@ -1,4 +1,7 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@ -57,48 +60,37 @@ use OC\Log\Rotate;
use OC\Preview\BackgroundCleanupJob;
use OC\TextProcessing\RemoveOldTasksBackgroundJob;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\IJobList;
use OCP\Defaults;
use OCP\IConfig;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\L10N\IFactory as IL10NFactory;
use OCP\Migration\IOutput;
use OCP\Security\ISecureRandom;
use OCP\Server;
use Psr\Log\LoggerInterface;
class Setup {
/** @var SystemConfig */
protected $config;
/** @var IniGetWrapper */
protected $iniWrapper;
/** @var IL10N */
protected $l10n;
/** @var Defaults */
protected $defaults;
/** @var LoggerInterface */
protected $logger;
/** @var ISecureRandom */
protected $random;
/** @var Installer */
protected $installer;
protected IL10N $l10n;
public function __construct(
SystemConfig $config,
IniGetWrapper $iniWrapper,
IL10N $l10n,
Defaults $defaults,
LoggerInterface $logger,
ISecureRandom $random,
Installer $installer
protected SystemConfig $config,
protected IniGetWrapper $iniWrapper,
IL10NFactory $l10nFactory,
protected Defaults $defaults,
protected LoggerInterface $logger,
protected ISecureRandom $random,
protected Installer $installer
) {
$this->config = $config;
$this->iniWrapper = $iniWrapper;
$this->l10n = $l10n;
$this->defaults = $defaults;
$this->logger = $logger;
$this->random = $random;
$this->installer = $installer;
$this->l10n = $l10nFactory->get('lib');
}
protected static $dbSetupClasses = [
protected static array $dbSetupClasses = [
'mysql' => \OC\Setup\MySQL::class,
'pgsql' => \OC\Setup\PostgreSQL::class,
'oci' => \OC\Setup\OCI::class,
@ -108,30 +100,22 @@ class Setup {
/**
* Wrapper around the "class_exists" PHP function to be able to mock it
*
* @param string $name
* @return bool
*/
protected function class_exists($name) {
protected function class_exists(string $name): bool {
return class_exists($name);
}
/**
* Wrapper around the "is_callable" PHP function to be able to mock it
*
* @param string $name
* @return bool
*/
protected function is_callable($name) {
protected function is_callable(string $name): bool {
return is_callable($name);
}
/**
* Wrapper around \PDO::getAvailableDrivers
*
* @return array
*/
protected function getAvailableDbDriversForPdo() {
protected function getAvailableDbDriversForPdo(): array {
if (class_exists(\PDO::class)) {
return \PDO::getAvailableDrivers();
}
@ -141,11 +125,10 @@ class Setup {
/**
* Get the available and supported databases of this instance
*
* @param bool $allowAllDatabases
* @return array
* @throws Exception
*/
public function getSupportedDatabases($allowAllDatabases = false) {
public function getSupportedDatabases(bool $allowAllDatabases = false): array {
$availableDatabases = [
'sqlite' => [
'type' => 'pdo',
@ -207,7 +190,7 @@ class Setup {
* @return array of system info, including an "errors" value
* in case of errors/warnings
*/
public function getSystemInfo($allowAllDatabases = false) {
public function getSystemInfo(bool $allowAllDatabases = false): array {
$databases = $this->getSupportedDatabases($allowAllDatabases);
$dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT . '/data');
@ -227,7 +210,7 @@ class Setup {
try {
$util = new \OC_Util();
$htAccessWorking = $util->isHtaccessWorking(\OC::$server->getConfig());
$htAccessWorking = $util->isHtaccessWorking(Server::get(IConfig::class));
} catch (\OCP\HintException $e) {
$errors[] = [
'error' => $e->getMessage(),
@ -273,10 +256,9 @@ class Setup {
}
/**
* @param $options
* @return array
* @return array<string|array> errors
*/
public function install($options, ?IOutput $output = null) {
public function install(array $options, ?IOutput $output = null): array {
$l = $this->l10n;
$error = [];
@ -314,7 +296,7 @@ class Setup {
return $error;
}
$request = \OC::$server->getRequest();
$request = Server::get(IRequest::class);
//no errors, good
if (isset($options['trusted_domains'])
@ -387,78 +369,83 @@ class Setup {
//create the user and group
$user = null;
try {
$user = \OC::$server->getUserManager()->createUser($username, $password);
$user = Server::get(IUserManager::class)->createUser($username, $password);
if (!$user) {
$error[] = "User <$username> could not be created.";
return $error;
}
} catch (Exception $exception) {
$error[] = $exception->getMessage();
return $error;
}
if (empty($error)) {
$config = \OC::$server->getConfig();
$config->setAppValue('core', 'installedat', (string)microtime(true));
$config->setAppValue('core', 'lastupdatedat', (string)microtime(true));
$config = Server::get(IConfig::class);
$config->setAppValue('core', 'installedat', (string)microtime(true));
$config->setAppValue('core', 'lastupdatedat', (string)microtime(true));
$vendorData = $this->getVendorData();
$config->setAppValue('core', 'vendor', $vendorData['vendor']);
if ($vendorData['channel'] !== 'stable') {
$config->setSystemValue('updater.release.channel', $vendorData['channel']);
}
$vendorData = $this->getVendorData();
$config->setAppValue('core', 'vendor', $vendorData['vendor']);
if ($vendorData['channel'] !== 'stable') {
$config->setSystemValue('updater.release.channel', $vendorData['channel']);
}
$group = \OC::$server->getGroupManager()->createGroup('admin');
if ($group instanceof IGroup) {
$group->addUser($user);
}
$group = Server::get(IGroupManager::class)->createGroup('admin');
if ($group instanceof IGroup) {
$group->addUser($user);
}
// Install shipped apps and specified app bundles
$this->outputDebug($output, 'Install default apps');
Installer::installShippedApps(false, $output);
// Install shipped apps and specified app bundles
$this->outputDebug($output, 'Install default apps');
Installer::installShippedApps(false, $output);
// create empty file in data dir, so we can later find
// out that this is indeed an ownCloud data directory
$this->outputDebug($output, 'Setup data directory');
file_put_contents($config->getSystemValueString('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
// create empty file in data dir, so we can later find
// out that this is indeed an ownCloud data directory
$this->outputDebug($output, 'Setup data directory');
file_put_contents($config->getSystemValueString('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
// Update .htaccess files
self::updateHtaccess();
self::protectDataDirectory();
// Update .htaccess files
self::updateHtaccess();
self::protectDataDirectory();
$this->outputDebug($output, 'Install background jobs');
self::installBackgroundJobs();
$this->outputDebug($output, 'Install background jobs');
self::installBackgroundJobs();
//and we are done
$config->setSystemValue('installed', true);
if (self::shouldRemoveCanInstallFile()) {
unlink(\OC::$configDir.'/CAN_INSTALL');
}
//and we are done
$config->setSystemValue('installed', true);
if (self::shouldRemoveCanInstallFile()) {
unlink(\OC::$configDir.'/CAN_INSTALL');
}
$bootstrapCoordinator = \OCP\Server::get(\OC\AppFramework\Bootstrap\Coordinator::class);
$bootstrapCoordinator->runInitialRegistration();
$bootstrapCoordinator = \OCP\Server::get(\OC\AppFramework\Bootstrap\Coordinator::class);
$bootstrapCoordinator->runInitialRegistration();
// Create a session token for the newly created user
// The token provider requires a working db, so it's not injected on setup
/* @var $userSession User\Session */
$userSession = \OC::$server->getUserSession();
$provider = \OCP\Server::get(PublicKeyTokenProvider::class);
$userSession->setTokenProvider($provider);
$userSession->login($username, $password);
$userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
// Create a session token for the newly created user
// The token provider requires a working db, so it's not injected on setup
/** @var \OC\User\Session $userSession */
$userSession = Server::get(IUserSession::class);
$provider = Server::get(PublicKeyTokenProvider::class);
$userSession->setTokenProvider($provider);
$userSession->login($username, $password);
$user = $userSession->getUser();
if (!$user) {
$error[] = "No user found in session.";
return $error;
}
$userSession->createSessionToken($request, $user->getUID(), $username, $password);
$session = $userSession->getSession();
$session->set('last-password-confirm', \OCP\Server::get(ITimeFactory::class)->getTime());
$session = $userSession->getSession();
$session->set('last-password-confirm', Server::get(ITimeFactory::class)->getTime());
// Set email for admin
if (!empty($options['adminemail'])) {
$user->setSystemEMailAddress($options['adminemail']);
}
// Set email for admin
if (!empty($options['adminemail'])) {
$user->setSystemEMailAddress($options['adminemail']);
}
return $error;
}
public static function installBackgroundJobs() {
$jobList = \OC::$server->getJobList();
public static function installBackgroundJobs(): void {
$jobList = Server::get(IJobList::class);
$jobList->add(TokenCleanupJob::class);
$jobList->add(Rotate::class);
$jobList->add(BackgroundCleanupJob::class);
@ -468,15 +455,13 @@ class Setup {
/**
* @return string Absolute path to htaccess
*/
private function pathToHtaccess() {
private function pathToHtaccess(): string {
return \OC::$SERVERROOT . '/.htaccess';
}
/**
* Find webroot from config
*
* @param SystemConfig $config
* @return string
* @throws InvalidArgumentException when invalid value for overwrite.cli.url
*/
private static function findWebRoot(SystemConfig $config): string {
@ -503,8 +488,8 @@ class Setup {
* @return bool True when success, False otherwise
* @throws \OCP\AppFramework\QueryException
*/
public static function updateHtaccess() {
$config = \OC::$server->getSystemConfig();
public static function updateHtaccess(): bool {
$config = Server::get(SystemConfig::class);
try {
$webRoot = self::findWebRoot($config);
@ -512,15 +497,7 @@ class Setup {
return false;
}
$setupHelper = new \OC\Setup(
$config,
\OC::$server->get(IniGetWrapper::class),
\OC::$server->getL10N('lib'),
\OCP\Server::get(Defaults::class),
\OC::$server->get(LoggerInterface::class),
\OC::$server->getSecureRandom(),
\OCP\Server::get(Installer::class)
);
$setupHelper = Server::get(\OC\Setup::class);
if (!is_writable($setupHelper->pathToHtaccess())) {
return false;
@ -563,23 +540,19 @@ class Setup {
$content .= "\n</IfModule>";
}
if ($content !== '') {
// Never write file back if disk space should be too low
if (function_exists('disk_free_space')) {
$df = disk_free_space(\OC::$SERVERROOT);
$size = strlen($content) + 10240;
if ($df !== false && $df < (float)$size) {
throw new \Exception(\OC::$SERVERROOT . " does not have enough space for writing the htaccess file! Not writing it back!");
}
// Never write file back if disk space should be too low
if (function_exists('disk_free_space')) {
$df = disk_free_space(\OC::$SERVERROOT);
$size = strlen($content) + 10240;
if ($df !== false && $df < (float)$size) {
throw new \Exception(\OC::$SERVERROOT . " does not have enough space for writing the htaccess file! Not writing it back!");
}
//suppress errors in case we don't have permissions for it
return (bool)@file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent . $content . "\n");
}
return false;
//suppress errors in case we don't have permissions for it
return (bool)@file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent . $content . "\n");
}
public static function protectDataDirectory() {
public static function protectDataDirectory(): void {
//Require all denied
$now = date('Y-m-d H:i:s');
$content = "# Generated by Nextcloud on $now\n";
@ -607,7 +580,7 @@ class Setup {
$content .= " IndexIgnore *\n";
$content .= "</IfModule>";
$baseDir = \OC::$server->getConfig()->getSystemValueString('datadirectory', \OC::$SERVERROOT . '/data');
$baseDir = Server::get(IConfig::class)->getSystemValueString('datadirectory', \OC::$SERVERROOT . '/data');
file_put_contents($baseDir . '/.htaccess', $content);
file_put_contents($baseDir . '/index.html', '');
}
@ -623,17 +596,11 @@ class Setup {
];
}
/**
* @return bool
*/
public function shouldRemoveCanInstallFile() {
public function shouldRemoveCanInstallFile(): bool {
return \OC_Util::getChannel() !== 'git' && is_file(\OC::$configDir.'/CAN_INSTALL');
}
/**
* @return bool
*/
public function canInstallFileExists() {
public function canInstallFileExists(): bool {
return is_file(\OC::$configDir.'/CAN_INSTALL');
}

View File

@ -513,15 +513,7 @@ class OC_Util {
}
$webServerRestart = false;
$setup = new \OC\Setup(
$config,
\OC::$server->get(IniGetWrapper::class),
\OC::$server->getL10N('lib'),
\OC::$server->get(\OCP\Defaults::class),
\OC::$server->get(LoggerInterface::class),
\OC::$server->getSecureRandom(),
\OC::$server->get(\OC\Installer::class)
);
$setup = \OCP\Server::get(\OC\Setup::class);
$urlGenerator = \OC::$server->getURLGenerator();

View File

@ -14,27 +14,20 @@ use OC\Setup;
use OC\SystemConfig;
use OCP\Defaults;
use OCP\IL10N;
use OCP\L10N\IFactory as IL10NFactory;
use OCP\Security\ISecureRandom;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
class SetupTest extends \Test\TestCase {
/** @var SystemConfig|MockObject */
protected $config;
/** @var \bantu\IniGetWrapper\IniGetWrapper|MockObject */
private $iniWrapper;
/** @var \OCP\IL10N|MockObject */
private $l10n;
/** @var Defaults|MockObject */
private $defaults;
/** @var \OC\Setup|MockObject */
protected $setupClass;
/** @var LoggerInterface|MockObject */
protected $logger;
/** @var \OCP\Security\ISecureRandom|MockObject */
protected $random;
/** @var Installer|MockObject */
protected $installer;
protected SystemConfig $config;
private IniGetWrapper $iniWrapper;
private IL10N $l10n;
private IL10NFactory $l10nFactory;
private Defaults $defaults;
protected Setup $setupClass;
protected LoggerInterface $logger;
protected ISecureRandom $random;
protected Installer $installer;
protected function setUp(): void {
parent::setUp();
@ -42,13 +35,16 @@ class SetupTest extends \Test\TestCase {
$this->config = $this->createMock(SystemConfig::class);
$this->iniWrapper = $this->createMock(IniGetWrapper::class);
$this->l10n = $this->createMock(IL10N::class);
$this->l10nFactory = $this->createMock(IL10NFactory::class);
$this->l10nFactory->method('get')
->willReturn($this->l10n);
$this->defaults = $this->createMock(Defaults::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->random = $this->createMock(ISecureRandom::class);
$this->installer = $this->createMock(Installer::class);
$this->setupClass = $this->getMockBuilder(Setup::class)
->setMethods(['class_exists', 'is_callable', 'getAvailableDbDriversForPdo'])
->setConstructorArgs([$this->config, $this->iniWrapper, $this->l10n, $this->defaults, $this->logger, $this->random, $this->installer])
->setConstructorArgs([$this->config, $this->iniWrapper, $this->l10nFactory, $this->defaults, $this->logger, $this->random, $this->installer])
->getMock();
}