migrate therinaldos.com data
Build & Deploy to DigitalOcean Space / build (push) Failing after 2m38s

This commit is contained in:
2024-05-05 15:50:45 -04:00
commit ef1ff240d4
23182 changed files with 3801898 additions and 0 deletions
@@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class AppDirsWithDifferentOwner implements ISetupCheck {
public function __construct(
private IL10N $l10n,
) {
}
public function getName(): string {
return $this->l10n->t('App directories owner');
}
public function getCategory(): string {
return 'security';
}
/**
* Iterates through the configured app roots and
* tests if the subdirectories are owned by the same user than the current user.
*
* @return string[]
*/
private function getAppDirsWithDifferentOwner(int $currentUser): array {
$appDirsWithDifferentOwner = [[]];
foreach (\OC::$APPSROOTS as $appRoot) {
if ($appRoot['writable'] === true) {
$appDirsWithDifferentOwner[] = $this->getAppDirsWithDifferentOwnerForAppRoot($currentUser, $appRoot);
}
}
$appDirsWithDifferentOwner = array_merge(...$appDirsWithDifferentOwner);
sort($appDirsWithDifferentOwner);
return $appDirsWithDifferentOwner;
}
/**
* Tests if the directories for one apps directory are writable by the current user.
*
* @param int $currentUser The current user
* @param array $appRoot The app root config
* @return string[] The none writable directory paths inside the app root
*/
private function getAppDirsWithDifferentOwnerForAppRoot(int $currentUser, array $appRoot): array {
$appDirsWithDifferentOwner = [];
$appsPath = $appRoot['path'];
$appsDir = new \DirectoryIterator($appRoot['path']);
foreach ($appsDir as $fileInfo) {
if ($fileInfo->isDir() && !$fileInfo->isDot()) {
$absAppPath = $appsPath . DIRECTORY_SEPARATOR . $fileInfo->getFilename();
$appDirUser = fileowner($absAppPath);
if ($appDirUser !== $currentUser) {
$appDirsWithDifferentOwner[] = $absAppPath;
}
}
}
return $appDirsWithDifferentOwner;
}
public function run(): SetupResult {
$currentUser = posix_getuid();
$currentUserInfos = posix_getpwuid($currentUser) ?: [];
$appDirsWithDifferentOwner = $this->getAppDirsWithDifferentOwner($currentUser);
if (count($appDirsWithDifferentOwner) > 0) {
return SetupResult::warning(
$this->l10n->t("Some app directories are owned by a different user than the web server one. This may be the case if apps have been installed manually. Check the permissions of the following app directories:\n%s", implode("\n", $appDirsWithDifferentOwner))
);
} else {
return SetupResult::success($this->l10n->t('App directories have the correct owner "%s"', [$currentUserInfos['name'] ?? '']));
}
}
}
@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\Security\Bruteforce\IThrottler;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class BruteForceThrottler implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
private IRequest $request,
private IThrottler $throttler,
) {
}
public function getCategory(): string {
return 'system';
}
public function getName(): string {
return $this->l10n->t('Brute-force Throttle');
}
public function run(): SetupResult {
$address = $this->request->getRemoteAddress();
if ($address === '') {
if (\OC::$CLI) {
/* We were called from CLI */
return SetupResult::info($this->l10n->t('Your remote address could not be determined.'));
} else {
/* Should never happen */
return SetupResult::error($this->l10n->t('Your remote address could not be determined.'));
}
} elseif ($this->throttler->showBruteforceWarning($address)) {
return SetupResult::error(
$this->l10n->t('Your remote address was identified as "%s" and is brute-force throttled at the moment slowing down the performance of various requests. If the remote address is not your address this can be an indication that a proxy is not configured correctly.', [$address]),
$this->urlGenerator->linkToDocs('admin-reverse-proxy')
);
} else {
return SetupResult::success(
$this->l10n->t('Your remote address "%s" is not brute-force throttled.', [$address])
);
}
}
}
@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2020 Morris Jobke <hey@morrisjobke.de>
* @copyright Copyright (c) 2022 Carl Schwan <carl@carlschwan.eu>
*
* @author Morris Jobke <hey@morrisjobke.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class CheckUserCertificates implements ISetupCheck {
private string $configValue;
public function __construct(
private IL10N $l10n,
IConfig $config,
) {
$this->configValue = $config->getAppValue('files_external', 'user_certificate_scan', '');
}
public function getCategory(): string {
return 'security';
}
public function getName(): string {
return $this->l10n->t('Old user imported certificates');
}
public function run(): SetupResult {
// all fine if neither "not-run-yet" nor a result
if ($this->configValue === '') {
return SetupResult::success();
}
if ($this->configValue === 'not-run-yet') {
return SetupResult::info($this->l10n->t('A background job is pending that checks for user imported SSL certificates. Please check back later.'));
}
return SetupResult::error($this->l10n->t('There are some user imported SSL certificates present, that are not used anymore with Nextcloud 21. They can be imported on the command line via "occ security:certificates:import" command. Their paths inside the data directory are shown below.'));
}
}
@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OC\IntegrityCheck\Checker;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class CodeIntegrity implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
private Checker $checker,
) {
}
public function getName(): string {
return $this->l10n->t('Code integrity');
}
public function getCategory(): string {
return 'security';
}
public function run(): SetupResult {
if (!$this->checker->isCodeCheckEnforced()) {
return SetupResult::info($this->l10n->t('Integrity checker has been disabled. Integrity cannot be verified.'));
} elseif ($this->checker->hasPassedCheck()) {
return SetupResult::success($this->l10n->t('No altered files'));
} else {
return SetupResult::error(
$this->l10n->t('Some files have not passed the integrity check. {link1} {link2}'),
$this->urlGenerator->linkToDocs('admin-code-integrity'),
[
'link1' => [
'type' => 'highlight',
'id' => 'getFailedIntegrityCheckFiles',
'name' => 'List of invalid files…',
'link' => $this->urlGenerator->linkToRoute('settings.CheckSetup.getFailedIntegrityCheckFiles'),
],
'link2' => [
'type' => 'highlight',
'id' => 'rescanFailedIntegrityCheck',
'name' => 'Rescan…',
'link' => $this->urlGenerator->linkToRoute('settings.CheckSetup.rescanFailedIntegrityCheck'),
],
],
);
}
}
}
@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class CronErrors implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
) {
}
public function getCategory(): string {
return 'system';
}
public function getName(): string {
return $this->l10n->t('Cron errors');
}
public function run(): SetupResult {
$errors = json_decode($this->config->getAppValue('core', 'cronErrors', ''), true);
if (is_array($errors) && count($errors) > 0) {
return SetupResult::error(
$this->l10n->t(
"It was not possible to execute the cron job via CLI. The following technical errors have appeared:\n%s",
implode("\n", array_map(fn (array $error) => '- '.$error['error'].' '.$error['hint'], $errors))
)
);
} else {
return SetupResult::success($this->l10n->t('The last cron job ran without errors.'));
}
}
}
@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IDateTimeFormatter;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class CronInfo implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
private IURLGenerator $urlGenerator,
private IDateTimeFormatter $dateTimeFormatter,
) {
}
public function getCategory(): string {
return 'system';
}
public function getName(): string {
return $this->l10n->t('Cron last run');
}
public function run(): SetupResult {
$lastCronRun = (int)$this->config->getAppValue('core', 'lastcron', '0');
$relativeTime = $this->dateTimeFormatter->formatTimeSpan($lastCronRun);
if ((time() - $lastCronRun) > 3600) {
return SetupResult::error(
$this->l10n->t(
'Last background job execution ran %s. Something seems wrong. {link}.',
[$relativeTime]
),
descriptionParameters:[
'link' => [
'type' => 'highlight',
'id' => 'backgroundjobs',
'name' => 'Check the background job settings',
'link' => $this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'server']) . '#backgroundjobs',
],
],
);
} else {
return SetupResult::success(
$this->l10n->t(
'Last background job execution ran %s.',
[$relativeTime]
)
);
}
}
}
@@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OC\DB\Connection;
use OC\DB\MissingColumnInformation;
use OC\DB\SchemaWrapper;
use OCP\DB\Events\AddMissingColumnsEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class DatabaseHasMissingColumns implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private Connection $connection,
private IEventDispatcher $dispatcher,
) {
}
public function getCategory(): string {
return 'database';
}
public function getName(): string {
return $this->l10n->t('Database missing columns');
}
private function getMissingColumns(): array {
$columnInfo = new MissingColumnInformation();
// Dispatch event so apps can also hint for pending column updates if needed
$event = new AddMissingColumnsEvent();
$this->dispatcher->dispatchTyped($event);
$missingColumns = $event->getMissingColumns();
if (!empty($missingColumns)) {
$schema = new SchemaWrapper($this->connection);
foreach ($missingColumns as $missingColumn) {
if ($schema->hasTable($missingColumn['tableName'])) {
$table = $schema->getTable($missingColumn['tableName']);
if (!$table->hasColumn($missingColumn['columnName'])) {
$columnInfo->addHintForMissingColumn($missingColumn['tableName'], $missingColumn['columnName']);
}
}
}
}
return $columnInfo->getListOfMissingColumns();
}
public function run(): SetupResult {
$missingColumns = $this->getMissingColumns();
if (empty($missingColumns)) {
return SetupResult::success('None');
} else {
$list = '';
foreach ($missingColumns as $missingColumn) {
$list .= "\n".$this->l10n->t('Missing optional column "%s" in table "%s".', [$missingColumn['columnName'], $missingColumn['tableName']]);
}
return SetupResult::warning(
$this->l10n->t('The database is missing some optional columns. Due to the fact that adding columns on big tables could take some time they were not added automatically when they can be optional. By running "occ db:add-missing-columns" those missing columns could be added manually while the instance keeps running. Once the columns are added some features might improve responsiveness or usability.').$list
);
}
}
}
@@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OC\DB\Connection;
use OC\DB\MissingIndexInformation;
use OC\DB\SchemaWrapper;
use OCP\DB\Events\AddMissingIndicesEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class DatabaseHasMissingIndices implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private Connection $connection,
private IEventDispatcher $dispatcher,
) {
}
public function getCategory(): string {
return 'database';
}
public function getName(): string {
return $this->l10n->t('Database missing indices');
}
private function getMissingIndices(): array {
$indexInfo = new MissingIndexInformation();
// Dispatch event so apps can also hint for pending index updates if needed
$event = new AddMissingIndicesEvent();
$this->dispatcher->dispatchTyped($event);
$missingIndices = $event->getMissingIndices();
if (!empty($missingIndices)) {
$schema = new SchemaWrapper($this->connection);
foreach ($missingIndices as $missingIndex) {
if ($schema->hasTable($missingIndex['tableName'])) {
$table = $schema->getTable($missingIndex['tableName']);
if (!$table->hasIndex($missingIndex['indexName'])) {
$indexInfo->addHintForMissingIndex($missingIndex['tableName'], $missingIndex['indexName']);
}
}
}
}
return $indexInfo->getListOfMissingIndices();
}
public function run(): SetupResult {
$missingIndices = $this->getMissingIndices();
if (empty($missingIndices)) {
return SetupResult::success('None');
} else {
$list = '';
foreach ($missingIndices as $missingIndex) {
$list .= "\n".$this->l10n->t('Missing optional index "%s" in table "%s".', [$missingIndex['indexName'], $missingIndex['tableName']]);
}
return SetupResult::warning(
$this->l10n->t('The database is missing some indexes. Due to the fact that adding indexes on big tables could take some time they were not added automatically. By running "occ db:add-missing-indices" those missing indexes could be added manually while the instance keeps running. Once the indexes are added queries to those tables are usually much faster.').$list
);
}
}
}
@@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OC\DB\Connection;
use OC\DB\MissingPrimaryKeyInformation;
use OC\DB\SchemaWrapper;
use OCP\DB\Events\AddMissingPrimaryKeyEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class DatabaseHasMissingPrimaryKeys implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private Connection $connection,
private IEventDispatcher $dispatcher,
) {
}
public function getCategory(): string {
return 'database';
}
public function getName(): string {
return $this->l10n->t('Database missing primary keys');
}
private function getMissingPrimaryKeys(): array {
$primaryKeyInfo = new MissingPrimaryKeyInformation();
// Dispatch event so apps can also hint for pending primary key updates if needed
$event = new AddMissingPrimaryKeyEvent();
$this->dispatcher->dispatchTyped($event);
$missingPrimaryKeys = $event->getMissingPrimaryKeys();
if (!empty($missingPrimaryKeys)) {
$schema = new SchemaWrapper($this->connection);
foreach ($missingPrimaryKeys as $missingPrimaryKey) {
if ($schema->hasTable($missingPrimaryKey['tableName'])) {
$table = $schema->getTable($missingPrimaryKey['tableName']);
if ($table->getPrimaryKey() === null) {
$primaryKeyInfo->addHintForMissingPrimaryKey($missingPrimaryKey['tableName']);
}
}
}
}
return $primaryKeyInfo->getListOfMissingPrimaryKeys();
}
public function run(): SetupResult {
$missingPrimaryKeys = $this->getMissingPrimaryKeys();
if (empty($missingPrimaryKeys)) {
return SetupResult::success('None');
} else {
$list = '';
foreach ($missingPrimaryKeys as $missingPrimaryKey) {
$list .= "\n".$this->l10n->t('Missing primary key on table "%s".', [$missingPrimaryKey['tableName']]);
}
return SetupResult::warning(
$this->l10n->t('The database is missing some primary keys. Due to the fact that adding primary keys on big tables could take some time they were not added automatically. By running "occ db:add-missing-primary-keys" those missing primary keys could be added manually while the instance keeps running.').$list
);
}
}
}
@@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use Doctrine\DBAL\Types\BigIntType;
use OC\Core\Command\Db\ConvertFilecacheBigInt;
use OC\DB\Connection;
use OC\DB\SchemaWrapper;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class DatabasePendingBigIntConversions implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
private Connection $db,
private IEventDispatcher $dispatcher,
private IDBConnection $connection,
) {
}
public function getCategory(): string {
return 'database';
}
public function getName(): string {
return $this->l10n->t('Database pending bigint migrations');
}
protected function getBigIntConversionPendingColumns(): array {
$tables = ConvertFilecacheBigInt::getColumnsByTable();
$schema = new SchemaWrapper($this->db);
$isSqlite = $this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE;
$pendingColumns = [];
foreach ($tables as $tableName => $columns) {
if (!$schema->hasTable($tableName)) {
continue;
}
$table = $schema->getTable($tableName);
foreach ($columns as $columnName) {
$column = $table->getColumn($columnName);
$isAutoIncrement = $column->getAutoincrement();
$isAutoIncrementOnSqlite = $isSqlite && $isAutoIncrement;
if (!($column->getType() instanceof BigIntType) && !$isAutoIncrementOnSqlite) {
$pendingColumns[] = $tableName . '.' . $columnName;
}
}
}
return $pendingColumns;
}
public function run(): SetupResult {
$pendingColumns = $this->getBigIntConversionPendingColumns();
if (empty($pendingColumns)) {
return SetupResult::success('None');
} else {
$list = '';
foreach ($pendingColumns as $pendingColumn) {
$list .= "\n$pendingColumn";
}
$list .= "\n";
return SetupResult::info(
$this->l10n->t('Some columns in the database are missing a conversion to big int. Due to the fact that changing column types on big tables could take some time they were not changed automatically. By running "occ db:convert-filecache-bigint" those pending changes could be applied manually. This operation needs to be made while the instance is offline.').$list,
$this->urlGenerator->linkToDocs('admin-bigint-conversion')
);
}
}
}
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class DefaultPhoneRegionSet implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
) {
}
public function getName(): string {
return $this->l10n->t('Default phone region');
}
public function getCategory(): string {
return 'config';
}
public function run(): SetupResult {
if ($this->config->getSystemValueString('default_phone_region', '') !== '') {
return SetupResult::success($this->config->getSystemValueString('default_phone_region', ''));
} else {
return SetupResult::info(
$this->l10n->t('Your installation has no default phone region set. This is required to validate phone numbers in the profile settings without a country code. To allow numbers without a country code, please add "default_phone_region" with the respective ISO 3166-1 code of the region to your config file.'),
'https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements'
);
}
}
}
@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class EmailTestSuccessful implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
private IURLGenerator $urlGenerator,
) {
}
public function getName(): string {
return $this->l10n->t('Email test');
}
public function getCategory(): string {
return 'config';
}
protected function wasEmailTestSuccessful(): bool {
// Handle the case that the configuration was set before the check was introduced or it was only set via command line and not from the UI
if ($this->config->getAppValue('core', 'emailTestSuccessful', '') === '' && $this->config->getSystemValue('mail_domain', '') === '') {
return false;
}
// The mail test was unsuccessful or the config was changed using the UI without verifying with a testmail, hence return false
if ($this->config->getAppValue('core', 'emailTestSuccessful', '') === '0') {
return false;
}
return true;
}
public function run(): SetupResult {
if ($this->wasEmailTestSuccessful()) {
return SetupResult::success($this->l10n->t('Email test was successfully sent'));
} else {
// If setup check could link to settings pages, this one should link to OC.generateUrl('/settings/admin')
return SetupResult::info(
$this->l10n->t('You have not set or verified your email server configuration, yet. Please head over to the "Basic settings" in order to set them. Afterwards, use the "Send email" button below the form to verify your settings.'),
$this->urlGenerator->linkToDocs('admin-email')
);
}
}
}
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OC\Lock\DBLockingProvider;
use OC\Lock\NoopLockingProvider;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\Lock\ILockingProvider;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class FileLocking implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
private ILockingProvider $lockingProvider,
) {
}
public function getName(): string {
return $this->l10n->t('File locking');
}
public function getCategory(): string {
return 'system';
}
protected function hasWorkingFileLocking(): bool {
return !($this->lockingProvider instanceof NoopLockingProvider);
}
protected function hasDBFileLocking(): bool {
return ($this->lockingProvider instanceof DBLockingProvider);
}
public function run(): SetupResult {
if (!$this->hasWorkingFileLocking()) {
return SetupResult::warning(
$this->l10n->t('Transactional file locking is disabled, this might lead to issues with race conditions. Enable "filelocking.enabled" in config.php to avoid these problems.'),
$this->urlGenerator->linkToDocs('admin-transactional-locking')
);
}
if ($this->hasDBFileLocking()) {
return SetupResult::info(
$this->l10n->t('The database is used for transactional file locking. To enhance performance, please configure memcache, if available.'),
$this->urlGenerator->linkToDocs('admin-transactional-locking')
);
}
return SetupResult::success();
}
}
@@ -0,0 +1,94 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class ForwardedForHeaders implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
private IURLGenerator $urlGenerator,
private IRequest $request,
) {
}
public function getCategory(): string {
return 'security';
}
public function getName(): string {
return $this->l10n->t('Forwarded for headers');
}
public function run(): SetupResult {
$trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
$remoteAddress = $this->request->getHeader('REMOTE_ADDR');
$detectedRemoteAddress = $this->request->getRemoteAddress();
if (!\is_array($trustedProxies)) {
return SetupResult::error($this->l10n->t('Your "trusted_proxies" setting is not correctly set, it should be an array.'));
}
if (($remoteAddress === '') && ($detectedRemoteAddress === '')) {
if (\OC::$CLI) {
/* We were called from CLI */
return SetupResult::info($this->l10n->t('Your remote address could not be determined.'));
} else {
/* Should never happen */
return SetupResult::error($this->l10n->t('Your remote address could not be determined.'));
}
}
if (empty($trustedProxies) && $this->request->getHeader('X-Forwarded-Host') !== '') {
return SetupResult::error(
$this->l10n->t('The reverse proxy header configuration is incorrect. This is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud.'),
$this->urlGenerator->linkToDocs('admin-reverse-proxy')
);
}
if (\in_array($remoteAddress, $trustedProxies, true) && ($remoteAddress !== '127.0.0.1')) {
if ($remoteAddress !== $detectedRemoteAddress) {
/* Remote address was successfuly fixed */
return SetupResult::success($this->l10n->t('Your IP address was resolved as %s', [$detectedRemoteAddress]));
} else {
return SetupResult::warning(
$this->l10n->t('The reverse proxy header configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If not, this is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud.'),
$this->urlGenerator->linkToDocs('admin-reverse-proxy')
);
}
}
/* Either not enabled or working correctly */
return SetupResult::success();
}
}
@@ -0,0 +1,100 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Côme Chilliet <come.chilliet@nextcloud.com>
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
use Psr\Log\LoggerInterface;
/**
* Checks if the server can connect to the internet using HTTPS and HTTP
*/
class InternetConnectivity implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
private IClientService $clientService,
private LoggerInterface $logger,
) {
}
public function getCategory(): string {
return 'network';
}
public function getName(): string {
return $this->l10n->t('Internet connectivity');
}
public function run(): SetupResult {
if ($this->config->getSystemValue('has_internet_connection', true) === false) {
return SetupResult::success($this->l10n->t('Internet connectivity is disabled in configuration file.'));
}
$siteArray = $this->config->getSystemValue('connectivity_check_domains', [
'www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org'
]);
foreach ($siteArray as $site) {
if ($this->isSiteReachable($site)) {
return SetupResult::success();
}
}
return SetupResult::warning($this->l10n->t('This server has no working internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the internet to enjoy all features.'));
}
/**
* Checks if the Nextcloud server can connect to a specific URL
* @param string $site site domain or full URL with http/https protocol
*/
private function isSiteReachable(string $site): bool {
try {
$client = $this->clientService->newClient();
// if there is no protocol, test http:// AND https://
if (preg_match('/^https?:\/\//', $site) !== 1) {
$httpSite = 'http://' . $site . '/';
$client->get($httpSite);
$httpsSite = 'https://' . $site . '/';
$client->get($httpsSite);
} else {
$client->get($site);
}
} catch (\Exception $e) {
$this->logger->error('Cannot connect to: ' . $site, [
'app' => 'internet_connection_check',
'exception' => $e,
]);
return false;
}
return true;
}
}
@@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
use Psr\Log\LoggerInterface;
/**
* Checks if the webserver serves '.mjs' files using the correct MIME type
*/
class JavaScriptModules implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
private IURLGenerator $urlGenerator,
private IClientService $clientService,
private LoggerInterface $logger,
) {
}
public function getCategory(): string {
return 'network';
}
public function getName(): string {
return $this->l10n->t('JavaScript modules support');
}
public function run(): SetupResult {
$testFile = $this->urlGenerator->linkTo('settings', 'js/esm-test.mjs');
$testURLs = array_merge(
[$this->urlGenerator->getAbsoluteURL($testFile)],
array_map(fn (string $host): string => $host . $testFile, $this->config->getSystemValue('trusted_domains', []))
);
foreach ($testURLs as $testURL) {
try {
$client = $this->clientService->newClient();
$response = $client->head($testURL, [
'connect_timeout' => 10,
// Disable SSL certificate checks to allow self signed certs
'verify' => false,
// Allow to connect to local server
'nextcloud' => [
'allow_local_address' => true,
],
]);
if (preg_match('/(text|application)\/javascript/i', $response->getHeader('Content-Type'))) {
return SetupResult::success();
}
} catch (\Throwable $e) {
$this->logger->debug('Can not connect to local server for checking JavaScript modules support', ['exception' => $e, 'url' => $testURL]);
return SetupResult::warning($this->l10n->t('Could not check for JavaScript support. Please check manually if your webserver serves `.mjs` files using the JavaScript MIME type.'));
}
}
return SetupResult::error($this->l10n->t('Your webserver does not serve `.mjs` files using the JavaScript MIME type. This will break some apps by preventing browsers from executing the JavaScript files. You should configure your webserver to serve `.mjs` files with either the `text/javascript` or `application/javascript` MIME type.'));
}
}
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2020 Morris Jobke <hey@morrisjobke.de>
*
* @author Morris Jobke <hey@morrisjobke.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class LegacySSEKeyFormat implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
private IURLGenerator $urlGenerator,
) {
}
public function getCategory(): string {
return 'security';
}
public function getName(): string {
return $this->l10n->t('Old server-side-encryption');
}
public function run(): SetupResult {
if ($this->config->getSystemValueBool('encryption.legacy_format_support', false) === false) {
return SetupResult::success($this->l10n->t('Disabled'));
}
return SetupResult::warning($this->l10n->t('The old server-side-encryption format is enabled. We recommend disabling this.'), $this->urlGenerator->linkToDocs('admin-sse-legacy-format'));
}
}
@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com>
*
* @author Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class MaintenanceWindowStart implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
private IConfig $config,
) {
}
public function getCategory(): string {
return 'system';
}
public function getName(): string {
return $this->l10n->t('Maintenance window start');
}
public function run(): SetupResult {
$configValue = $this->config->getSystemValue('maintenance_window_start', null);
if ($configValue === null) {
return SetupResult::warning(
$this->l10n->t('Server has no maintenance window start time configured. This means resource intensive daily background jobs will also be executed during your main usage time. We recommend to set it to a time of low usage, so users are less impacted by the load caused from these heavy tasks.'),
$this->urlGenerator->linkToDocs('admin-background-jobs')
);
}
$startValue = (int) $configValue;
$endValue = ($startValue + 6) % 24;
return SetupResult::success(
str_replace(
['{start}', '{end}'],
[$startValue, $endValue],
$this->l10n->t('Maintenance window to execute heavy background jobs is between {start}:00 UTC and {end}:00 UTC')
)
);
}
}
@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class MemcacheConfigured implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
private IURLGenerator $urlGenerator,
) {
}
public function getName(): string {
return $this->l10n->t('Memcache');
}
public function getCategory(): string {
return 'system';
}
public function run(): SetupResult {
if ($this->config->getSystemValue('memcache.local', null) !== null) {
return SetupResult::success($this->l10n->t('Configured'));
} else {
return SetupResult::info(
$this->l10n->t('No memory cache has been configured. To enhance performance, please configure a memcache, if available.'),
$this->urlGenerator->linkToDocs('admin-performance')
);
}
}
}
@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IRequest;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class OverwriteCliUrl implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
private IRequest $request,
) {
}
public function getCategory(): string {
return 'config';
}
public function getName(): string {
return $this->l10n->t('Overwrite cli URL');
}
public function run(): SetupResult {
$currentOverwriteCliUrl = $this->config->getSystemValue('overwrite.cli.url', '');
$suggestedOverwriteCliUrl = $this->request->getServerProtocol() . '://' . $this->request->getInsecureServerHost() . \OC::$WEBROOT;
// Check correctness by checking if it is a valid URL
if (filter_var($currentOverwriteCliUrl, FILTER_VALIDATE_URL)) {
if ($currentOverwriteCliUrl == $suggestedOverwriteCliUrl) {
return SetupResult::success(
$this->l10n->t(
'The "overwrite.cli.url" option in your config.php is correctly set to "%s".',
[$currentOverwriteCliUrl]
)
);
} else {
return SetupResult::success(
$this->l10n->t(
'The "overwrite.cli.url" option in your config.php is set to "%s" which is a correct URL. Suggested URL is "%s".',
[$currentOverwriteCliUrl, $suggestedOverwriteCliUrl]
)
);
}
} else {
return SetupResult::warning(
$this->l10n->t(
'Please make sure to set the "overwrite.cli.url" option in your config.php file to the URL that your users mainly use to access this Nextcloud. Suggestion: "%s". Otherwise there might be problems with the URL generation via cron. (It is possible though that the suggested URL is not the URL that your users mainly use to access this Nextcloud. Best is to double check this in any case.)',
[$suggestedOverwriteCliUrl]
)
);
}
}
}
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2020 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class PhpDefaultCharset implements ISetupCheck {
public function __construct(
private IL10N $l10n,
) {
}
public function getName(): string {
return $this->l10n->t('PHP default charset');
}
public function getCategory(): string {
return 'php';
}
public function run(): SetupResult {
if (strtoupper(trim(ini_get('default_charset'))) === 'UTF-8') {
return SetupResult::success('UTF-8');
} else {
return SetupResult::warning($this->l10n->t('PHP configuration option "default_charset" should be UTF-8'));
}
}
}
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class PhpFreetypeSupport implements ISetupCheck {
public function __construct(
private IL10N $l10n,
) {
}
public function getName(): string {
return $this->l10n->t('Freetype');
}
public function getCategory(): string {
return 'php';
}
/**
* Check if the required FreeType functions are present
*/
protected function hasFreeTypeSupport(): bool {
return function_exists('imagettfbbox') && function_exists('imagettftext');
}
public function run(): SetupResult {
if ($this->hasFreeTypeSupport()) {
return SetupResult::success($this->l10n->t('Supported'));
} else {
return SetupResult::info(
$this->l10n->t('Your PHP does not have FreeType support, resulting in breakage of profile pictures and the settings interface.'),
);
}
}
}
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2020 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class PhpGetEnv implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
) {
}
public function getName(): string {
return $this->l10n->t('PHP getenv');
}
public function getCategory(): string {
return 'php';
}
public function run(): SetupResult {
if (!empty(getenv('PATH'))) {
return SetupResult::success();
} else {
return SetupResult::warning($this->l10n->t('PHP does not seem to be setup properly to query system environment variables. The test with getenv("PATH") only returns an empty response.'), $this->urlGenerator->linkToDocs('admin-php-fpm'));
}
}
}
@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OC\MemoryInfo;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
use OCP\Util;
class PhpMemoryLimit implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private MemoryInfo $memoryInfo,
) {
}
public function getCategory(): string {
return 'php';
}
public function getName(): string {
return $this->l10n->t('PHP memory limit');
}
public function run(): SetupResult {
if ($this->memoryInfo->isMemoryLimitSufficient()) {
return SetupResult::success(Util::humanFileSize($this->memoryInfo->getMemoryLimit()));
} else {
return SetupResult::error($this->l10n->t('The PHP memory limit is below the recommended value of %s.', Util::humanFileSize(MemoryInfo::RECOMMENDED_MEMORY_LIMIT)));
}
}
}
@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class PhpModules implements ISetupCheck {
protected const REQUIRED_MODULES = [
'ctype',
'curl',
'dom',
'fileinfo',
'gd',
'json',
'mbstring',
'openssl',
'posix',
'session',
'xml',
'xmlreader',
'xmlwriter',
'zip',
'zlib',
];
protected const RECOMMENDED_MODULES = [
'exif',
'intl',
'sodium',
'sysvsem',
];
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
) {
}
public function getName(): string {
return $this->l10n->t('PHP modules');
}
public function getCategory(): string {
return 'system';
}
public function run(): SetupResult {
$missingRecommendedModules = $this->getMissingModules(self::RECOMMENDED_MODULES);
$missingRequiredModules = $this->getMissingModules(self::REQUIRED_MODULES);
if (!empty($missingRequiredModules)) {
return SetupResult::error(
$this->l10n->t('This instance is missing some required PHP modules. It is required to install them: %s.', implode(', ', $missingRequiredModules)),
$this->urlGenerator->linkToDocs('admin-php-modules')
);
} elseif (!empty($missingRecommendedModules)) {
return SetupResult::info(
$this->l10n->t('This instance is missing some recommended PHP modules. For improved performance and better compatibility it is highly recommended to install them: %s.', implode(', ', $missingRecommendedModules)),
$this->urlGenerator->linkToDocs('admin-php-modules')
);
} else {
return SetupResult::success();
}
}
/**
* Checks for potential PHP modules that would improve the instance
*
* @param string[] $modules modules to test
* @return string[] A list of PHP modules which are missing
*/
protected function getMissingModules(array $modules): array {
return array_values(array_filter(
$modules,
fn (string $module) => !extension_loaded($module),
));
}
}
@@ -0,0 +1,148 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use bantu\IniGetWrapper\IniGetWrapper;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class PhpOpcacheSetup implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
private IniGetWrapper $iniGetWrapper,
) {
}
public function getName(): string {
return $this->l10n->t('PHP opcache');
}
public function getCategory(): string {
return 'php';
}
/**
* Checks whether a PHP OPcache is properly set up
* @return array{'warning'|'error',list<string>} The level and the list of OPcache setup recommendations
*/
protected function getOpcacheSetupRecommendations(): array {
$level = 'warning';
// If the module is not loaded, return directly to skip inapplicable checks
if (!extension_loaded('Zend OPcache')) {
return ['error',[$this->l10n->t('The PHP OPcache module is not loaded. For better performance it is recommended to load it into your PHP installation.')]];
}
$recommendations = [];
// Check whether Nextcloud is allowed to use the OPcache API
$isPermitted = true;
$permittedPath = (string)$this->iniGetWrapper->getString('opcache.restrict_api');
if ($permittedPath !== '' && !str_starts_with(\OC::$SERVERROOT, rtrim($permittedPath, '/'))) {
$isPermitted = false;
}
if (!$this->iniGetWrapper->getBool('opcache.enable')) {
$recommendations[] = $this->l10n->t('OPcache is disabled. For better performance, it is recommended to apply "opcache.enable=1" to your PHP configuration.');
$level = 'error';
} elseif ($this->iniGetWrapper->getBool('opcache.file_cache_only')) {
$recommendations[] = $this->l10n->t('The shared memory based OPcache is disabled. For better performance, it is recommended to apply "opcache.file_cache_only=0" to your PHP configuration and use the file cache as second level cache only.');
} else {
// Check whether opcache_get_status has been explicitly disabled an in case skip usage based checks
$disabledFunctions = $this->iniGetWrapper->getString('disable_functions');
if (isset($disabledFunctions) && str_contains($disabledFunctions, 'opcache_get_status')) {
return [$level, $recommendations];
}
$status = opcache_get_status(false);
if ($status === false) {
$recommendations[] = $this->l10n->t('OPcache is not working as it should, opcache_get_status() returns false, please check configuration.');
$level = 'error';
}
// Recommend to raise value, if more than 90% of max value is reached
if (
empty($status['opcache_statistics']['max_cached_keys']) ||
($status['opcache_statistics']['num_cached_keys'] / $status['opcache_statistics']['max_cached_keys'] > 0.9)
) {
$recommendations[] = $this->l10n->t('The maximum number of OPcache keys is nearly exceeded. To assure that all scripts can be kept in the cache, it is recommended to apply "opcache.max_accelerated_files" to your PHP configuration with a value higher than "%s".', [($this->iniGetWrapper->getNumeric('opcache.max_accelerated_files') ?: 'currently')]);
}
if (
empty($status['memory_usage']['free_memory']) ||
($status['memory_usage']['used_memory'] / $status['memory_usage']['free_memory'] > 9)
) {
$recommendations[] = $this->l10n->t('The OPcache buffer is nearly full. To assure that all scripts can be hold in cache, it is recommended to apply "opcache.memory_consumption" to your PHP configuration with a value higher than "%s".', [($this->iniGetWrapper->getNumeric('opcache.memory_consumption') ?: 'currently')]);
}
if (
// Do not recommend to raise the interned strings buffer size above a quarter of the total OPcache size
($this->iniGetWrapper->getNumeric('opcache.interned_strings_buffer') ?? 0 < $this->iniGetWrapper->getNumeric('opcache.memory_consumption') ?? 0 / 4) &&
(
empty($status['interned_strings_usage']['free_memory']) ||
($status['interned_strings_usage']['used_memory'] / $status['interned_strings_usage']['free_memory'] > 9)
)
) {
$recommendations[] = $this->l10n->t('The OPcache interned strings buffer is nearly full. To assure that repeating strings can be effectively cached, it is recommended to apply "opcache.interned_strings_buffer" to your PHP configuration with a value higher than "%s".', [($this->iniGetWrapper->getNumeric('opcache.interned_strings_buffer') ?: 'currently')]);
}
}
// Check for saved comments only when OPcache is currently disabled. If it was enabled, opcache.save_comments=0 would break Nextcloud in the first place.
if (!$this->iniGetWrapper->getBool('opcache.save_comments')) {
$recommendations[] = $this->l10n->t('OPcache is configured to remove code comments. With OPcache enabled, "opcache.save_comments=1" must be set for Nextcloud to function.');
$level = 'error';
}
if (!$isPermitted) {
$recommendations[] = $this->l10n->t('Nextcloud is not allowed to use the OPcache API. With OPcache enabled, it is highly recommended to include all Nextcloud directories with "opcache.restrict_api" or unset this setting to disable OPcache API restrictions, to prevent errors during Nextcloud core or app upgrades.');
$level = 'error';
}
return [$level, $recommendations];
}
public function run(): SetupResult {
[$level,$recommendations] = $this->getOpcacheSetupRecommendations();
if (!empty($recommendations)) {
return match($level) {
'error' => SetupResult::error(
$this->l10n->t('The PHP OPcache module is not properly configured. %s.', implode("\n", $recommendations)),
$this->urlGenerator->linkToDocs('admin-php-opcache')
),
default => SetupResult::warning(
$this->l10n->t('The PHP OPcache module is not properly configured. %s.', implode("\n", $recommendations)),
$this->urlGenerator->linkToDocs('admin-php-opcache')
),
};
} else {
return SetupResult::success($this->l10n->t('Correctly configured'));
}
}
}
@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2022 Carl Schwan <carl@carlschwan.eu>
*
* @author Carl Schwan <carl@carlschwan.eu>
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class PhpOutdated implements ISetupCheck {
public function __construct(
private IL10N $l10n,
) {
}
public function getCategory(): string {
return 'security';
}
public function getName(): string {
return $this->l10n->t('PHP version');
}
public function run(): SetupResult {
if (PHP_VERSION_ID < 80100) {
return SetupResult::warning($this->l10n->t('You are currently running PHP %s. PHP 8.0 is now deprecated in Nextcloud 27. Nextcloud 28 may require at least PHP 8.1. Please upgrade to one of the officially supported PHP versions provided by the PHP Group as soon as possible.', [PHP_VERSION]), 'https://secure.php.net/supported-versions.php');
}
return SetupResult::success($this->l10n->t('You are currently running PHP %s.', [PHP_VERSION]));
}
}
@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2020 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class PhpOutputBuffering implements ISetupCheck {
public function __construct(
private IL10N $l10n,
) {
}
public function getCategory(): string {
return 'php';
}
public function getName(): string {
return $this->l10n->t('PHP "output_buffering" option');
}
public function run(): SetupResult {
$value = trim(ini_get('output_buffering'));
if ($value === '' || $value === '0') {
return SetupResult::success($this->l10n->t('Disabled'));
} else {
return SetupResult::error($this->l10n->t('PHP configuration option "output_buffering" must be disabled'));
}
}
}
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\Security\ISecureRandom;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class RandomnessSecure implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
private IURLGenerator $urlGenerator,
private ISecureRandom $secureRandom,
) {
}
public function getName(): string {
return $this->l10n->t('Random generator');
}
public function getCategory(): string {
return 'security';
}
public function run(): SetupResult {
try {
$this->secureRandom->generate(1);
} catch (\Exception $ex) {
return SetupResult::error(
$this->l10n->t('No suitable source for randomness found by PHP which is highly discouraged for security reasons.'),
$this->urlGenerator->linkToDocs('admin-security')
);
}
return SetupResult::success($this->l10n->t('Secure'));
}
}
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IConfig;
use OCP\IL10N;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class ReadOnlyConfig implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IConfig $config,
) {
}
public function getName(): string {
return $this->l10n->t('Configuration file access rights');
}
public function getCategory(): string {
return 'config';
}
public function run(): SetupResult {
if ($this->config->getSystemValueBool('config_is_read_only', false)) {
return SetupResult::info($this->l10n->t('The read-only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update.'));
} else {
return SetupResult::success($this->l10n->t('Nextcloud configuration file is writable'));
}
}
}
@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2021 Morris Jobke <hey@morrisjobke.de>
*
* @author Claas Augner <github@caugner.de>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Vincent Petry <vincent@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class SupportedDatabase implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
private IDBConnection $connection,
) {
}
public function getCategory(): string {
return 'database';
}
public function getName(): string {
return $this->l10n->t('Database version');
}
public function run(): SetupResult {
$version = null;
$databasePlatform = $this->connection->getDatabasePlatform();
if ($databasePlatform instanceof MySQLPlatform) {
$result = $this->connection->prepare("SHOW VARIABLES LIKE 'version';");
$result->execute();
$row = $result->fetch();
$version = $row['Value'];
$versionlc = strtolower($version);
if (str_contains($versionlc, 'mariadb')) {
if (version_compare($versionlc, '10.2', '<')) {
return SetupResult::warning($this->l10n->t('MariaDB version "%s" is used. Nextcloud 21 and higher do not support this version and require MariaDB 10.2 or higher.', $version));
}
} else {
if (version_compare($versionlc, '8', '<')) {
return SetupResult::warning($this->l10n->t('MySQL version "%s" is used. Nextcloud 21 and higher do not support this version and require MySQL 8.0 or MariaDB 10.2 or higher.', $version));
}
}
} elseif ($databasePlatform instanceof PostgreSQLPlatform) {
$result = $this->connection->prepare('SHOW server_version;');
$result->execute();
$row = $result->fetch();
$version = $row['server_version'];
if (version_compare(strtolower($version), '9.6', '<')) {
return SetupResult::warning($this->l10n->t('PostgreSQL version "%s" is used. Nextcloud 21 and higher do not support this version and require PostgreSQL 9.6 or higher.', $version));
}
} elseif ($databasePlatform instanceof OraclePlatform) {
$version = 'Oracle';
} elseif ($databasePlatform instanceof SqlitePlatform) {
return SetupResult::warning(
$this->l10n->t('SQLite is currently being used as the backend database. For larger installations we recommend that you switch to a different database backend. This is particularly recommended when using the desktop client for file synchronisation. To migrate to another database use the command line tool: "occ db:convert-type".'),
$this->urlGenerator->linkToDocs('admin-db-conversion')
);
} else {
return SetupResult::error($this->l10n->t('Unknown database platform'));
}
return SetupResult::success($version);
}
}
@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class SystemIs64bit implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
) {
}
public function getName(): string {
return $this->l10n->t('Architecture');
}
public function getCategory(): string {
return 'system';
}
protected function is64bit(): bool {
if (PHP_INT_SIZE < 8) {
return false;
} else {
return true;
}
}
public function run(): SetupResult {
if ($this->is64bit()) {
return SetupResult::success($this->l10n->t('64-bit'));
} else {
return SetupResult::warning(
$this->l10n->t('It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!'),
$this->urlGenerator->linkToDocs('admin-system-requirements')
);
}
}
}
@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
*
* @author Côme Chilliet <come.chilliet@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Settings\SetupChecks;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\TransactionIsolationLevel;
use OC\DB\Connection;
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\SetupCheck\ISetupCheck;
use OCP\SetupCheck\SetupResult;
class TransactionIsolation implements ISetupCheck {
public function __construct(
private IL10N $l10n,
private IURLGenerator $urlGenerator,
private IDBConnection $connection,
private Connection $db,
) {
}
public function getName(): string {
return $this->l10n->t('Database transaction isolation level');
}
public function getCategory(): string {
return 'database';
}
public function run(): SetupResult {
try {
if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE) {
return SetupResult::success();
}
if ($this->db->getTransactionIsolation() === TransactionIsolationLevel::READ_COMMITTED) {
return SetupResult::success('Read committed');
} else {
return SetupResult::error(
$this->l10n->t('Your database does not run with "READ COMMITTED" transaction isolation level. This can cause problems when multiple actions are executed in parallel.'),
$this->urlGenerator->linkToDocs('admin-db-transaction')
);
}
} catch (Exception $e) {
return SetupResult::warning(
$this->l10n->t('Was not able to get transaction isolation level: %s', $e->getMessage())
);
}
}
}