Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable28] Setup check migrations to new API #42918

Merged
merged 13 commits into from Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/settings/composer/composer/autoload_classmap.php
Expand Up @@ -79,6 +79,9 @@
'OCA\\Settings\\SetupChecks\\AppDirsWithDifferentOwner' => $baseDir . '/../lib/SetupChecks/AppDirsWithDifferentOwner.php',
'OCA\\Settings\\SetupChecks\\BruteForceThrottler' => $baseDir . '/../lib/SetupChecks/BruteForceThrottler.php',
'OCA\\Settings\\SetupChecks\\CheckUserCertificates' => $baseDir . '/../lib/SetupChecks/CheckUserCertificates.php',
'OCA\\Settings\\SetupChecks\\CodeIntegrity' => $baseDir . '/../lib/SetupChecks/CodeIntegrity.php',
'OCA\\Settings\\SetupChecks\\CronErrors' => $baseDir . '/../lib/SetupChecks/CronErrors.php',
'OCA\\Settings\\SetupChecks\\CronInfo' => $baseDir . '/../lib/SetupChecks/CronInfo.php',
'OCA\\Settings\\SetupChecks\\DatabaseHasMissingColumns' => $baseDir . '/../lib/SetupChecks/DatabaseHasMissingColumns.php',
'OCA\\Settings\\SetupChecks\\DatabaseHasMissingIndices' => $baseDir . '/../lib/SetupChecks/DatabaseHasMissingIndices.php',
'OCA\\Settings\\SetupChecks\\DatabaseHasMissingPrimaryKeys' => $baseDir . '/../lib/SetupChecks/DatabaseHasMissingPrimaryKeys.php',
Expand All @@ -92,6 +95,7 @@
'OCA\\Settings\\SetupChecks\\LegacySSEKeyFormat' => $baseDir . '/../lib/SetupChecks/LegacySSEKeyFormat.php',
'OCA\\Settings\\SetupChecks\\MaintenanceWindowStart' => $baseDir . '/../lib/SetupChecks/MaintenanceWindowStart.php',
'OCA\\Settings\\SetupChecks\\MemcacheConfigured' => $baseDir . '/../lib/SetupChecks/MemcacheConfigured.php',
'OCA\\Settings\\SetupChecks\\OverwriteCliUrl' => $baseDir . '/../lib/SetupChecks/OverwriteCliUrl.php',
'OCA\\Settings\\SetupChecks\\PhpDefaultCharset' => $baseDir . '/../lib/SetupChecks/PhpDefaultCharset.php',
'OCA\\Settings\\SetupChecks\\PhpFreetypeSupport' => $baseDir . '/../lib/SetupChecks/PhpFreetypeSupport.php',
'OCA\\Settings\\SetupChecks\\PhpGetEnv' => $baseDir . '/../lib/SetupChecks/PhpGetEnv.php',
Expand Down
4 changes: 4 additions & 0 deletions apps/settings/composer/composer/autoload_static.php
Expand Up @@ -94,6 +94,9 @@ class ComposerStaticInitSettings
'OCA\\Settings\\SetupChecks\\AppDirsWithDifferentOwner' => __DIR__ . '/..' . '/../lib/SetupChecks/AppDirsWithDifferentOwner.php',
'OCA\\Settings\\SetupChecks\\BruteForceThrottler' => __DIR__ . '/..' . '/../lib/SetupChecks/BruteForceThrottler.php',
'OCA\\Settings\\SetupChecks\\CheckUserCertificates' => __DIR__ . '/..' . '/../lib/SetupChecks/CheckUserCertificates.php',
'OCA\\Settings\\SetupChecks\\CodeIntegrity' => __DIR__ . '/..' . '/../lib/SetupChecks/CodeIntegrity.php',
'OCA\\Settings\\SetupChecks\\CronErrors' => __DIR__ . '/..' . '/../lib/SetupChecks/CronErrors.php',
'OCA\\Settings\\SetupChecks\\CronInfo' => __DIR__ . '/..' . '/../lib/SetupChecks/CronInfo.php',
'OCA\\Settings\\SetupChecks\\DatabaseHasMissingColumns' => __DIR__ . '/..' . '/../lib/SetupChecks/DatabaseHasMissingColumns.php',
'OCA\\Settings\\SetupChecks\\DatabaseHasMissingIndices' => __DIR__ . '/..' . '/../lib/SetupChecks/DatabaseHasMissingIndices.php',
'OCA\\Settings\\SetupChecks\\DatabaseHasMissingPrimaryKeys' => __DIR__ . '/..' . '/../lib/SetupChecks/DatabaseHasMissingPrimaryKeys.php',
Expand All @@ -107,6 +110,7 @@ class ComposerStaticInitSettings
'OCA\\Settings\\SetupChecks\\LegacySSEKeyFormat' => __DIR__ . '/..' . '/../lib/SetupChecks/LegacySSEKeyFormat.php',
'OCA\\Settings\\SetupChecks\\MaintenanceWindowStart' => __DIR__ . '/..' . '/../lib/SetupChecks/MaintenanceWindowStart.php',
'OCA\\Settings\\SetupChecks\\MemcacheConfigured' => __DIR__ . '/..' . '/../lib/SetupChecks/MemcacheConfigured.php',
'OCA\\Settings\\SetupChecks\\OverwriteCliUrl' => __DIR__ . '/..' . '/../lib/SetupChecks/OverwriteCliUrl.php',
'OCA\\Settings\\SetupChecks\\PhpDefaultCharset' => __DIR__ . '/..' . '/../lib/SetupChecks/PhpDefaultCharset.php',
'OCA\\Settings\\SetupChecks\\PhpFreetypeSupport' => __DIR__ . '/..' . '/../lib/SetupChecks/PhpFreetypeSupport.php',
'OCA\\Settings\\SetupChecks\\PhpGetEnv' => __DIR__ . '/..' . '/../lib/SetupChecks/PhpGetEnv.php',
Expand Down
8 changes: 8 additions & 0 deletions apps/settings/lib/AppInfo/Application.php
Expand Up @@ -51,6 +51,9 @@
use OCA\Settings\SetupChecks\AppDirsWithDifferentOwner;
use OCA\Settings\SetupChecks\BruteForceThrottler;
use OCA\Settings\SetupChecks\CheckUserCertificates;
use OCA\Settings\SetupChecks\CodeIntegrity;
use OCA\Settings\SetupChecks\CronErrors;
use OCA\Settings\SetupChecks\CronInfo;
use OCA\Settings\SetupChecks\DatabaseHasMissingColumns;
use OCA\Settings\SetupChecks\DatabaseHasMissingIndices;
use OCA\Settings\SetupChecks\DatabaseHasMissingPrimaryKeys;
Expand All @@ -64,6 +67,7 @@
use OCA\Settings\SetupChecks\LegacySSEKeyFormat;
use OCA\Settings\SetupChecks\MaintenanceWindowStart;
use OCA\Settings\SetupChecks\MemcacheConfigured;
use OCA\Settings\SetupChecks\OverwriteCliUrl;
use OCA\Settings\SetupChecks\PhpDefaultCharset;
use OCA\Settings\SetupChecks\PhpFreetypeSupport;
use OCA\Settings\SetupChecks\PhpGetEnv;
Expand Down Expand Up @@ -169,6 +173,9 @@ public function register(IRegistrationContext $context): void {
$context->registerSetupCheck(AppDirsWithDifferentOwner::class);
$context->registerSetupCheck(BruteForceThrottler::class);
$context->registerSetupCheck(CheckUserCertificates::class);
$context->registerSetupCheck(CodeIntegrity::class);
$context->registerSetupCheck(CronErrors::class);
$context->registerSetupCheck(CronInfo::class);
$context->registerSetupCheck(DatabaseHasMissingColumns::class);
$context->registerSetupCheck(DatabaseHasMissingIndices::class);
$context->registerSetupCheck(DatabaseHasMissingPrimaryKeys::class);
Expand All @@ -182,6 +189,7 @@ public function register(IRegistrationContext $context): void {
$context->registerSetupCheck(LegacySSEKeyFormat::class);
$context->registerSetupCheck(MaintenanceWindowStart::class);
$context->registerSetupCheck(MemcacheConfigured::class);
$context->registerSetupCheck(OverwriteCliUrl::class);
$context->registerSetupCheck(PhpDefaultCharset::class);
$context->registerSetupCheck(PhpFreetypeSupport::class);
$context->registerSetupCheck(PhpGetEnv::class);
Expand Down
116 changes: 1 addition & 115 deletions apps/settings/lib/Controller/CheckSetupController.php
Expand Up @@ -45,17 +45,14 @@
*/
namespace OCA\Settings\Controller;

use GuzzleHttp\Exception\ClientException;
use OC\AppFramework\Http;
use OC\IntegrityCheck\Checker;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI;
use OCP\AppFramework\Http\DataDisplayResponse;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
use OCP\IDateTimeFormatter;
use OCP\IL10N;
use OCP\IRequest;
use OCP\ITempManager;
Expand All @@ -68,8 +65,6 @@
class CheckSetupController extends Controller {
/** @var IConfig */
private $config;
/** @var IClientService */
private $clientService;
/** @var IURLGenerator */
private $urlGenerator;
/** @var IL10N */
Expand All @@ -78,8 +73,6 @@ class CheckSetupController extends Controller {
private $checker;
/** @var LoggerInterface */
private $logger;
/** @var IDateTimeFormatter */
private $dateTimeFormatter;
/** @var ITempManager */
private $tempManager;
/** @var IManager */
Expand All @@ -89,24 +82,20 @@ class CheckSetupController extends Controller {
public function __construct($AppName,
IRequest $request,
IConfig $config,
IClientService $clientService,
IURLGenerator $urlGenerator,
IL10N $l10n,
Checker $checker,
LoggerInterface $logger,
IDateTimeFormatter $dateTimeFormatter,
ITempManager $tempManager,
IManager $manager,
ISetupCheckManager $setupCheckManager,
) {
parent::__construct($AppName, $request);
$this->config = $config;
$this->clientService = $clientService;
$this->urlGenerator = $urlGenerator;
$this->l10n = $l10n;
$this->checker = $checker;
$this->logger = $logger;
$this->dateTimeFormatter = $dateTimeFormatter;
$this->tempManager = $tempManager;
$this->manager = $manager;
$this->setupCheckManager = $setupCheckManager;
Expand Down Expand Up @@ -134,73 +123,6 @@ private function isFairUseOfFreePushService(): bool {
return $this->manager->isFairUseOfFreePushService();
}

/**
* Public for the sake of unit-testing
*
* @return array
*/
protected function getCurlVersion() {
return curl_version();
}

/**
* Check if the used SSL lib is outdated. Older OpenSSL and NSS versions do
* have multiple bugs which likely lead to problems in combination with
* functionality required by ownCloud such as SNI.
*
* @link https://github.com/owncloud/core/issues/17446#issuecomment-122877546
* @link https://bugzilla.redhat.com/show_bug.cgi?id=1241172
* @return string
*/
private function isUsedTlsLibOutdated() {
// Don't run check when:
// 1. Server has `has_internet_connection` set to false
// 2. AppStore AND S2S is disabled
if (!$this->config->getSystemValue('has_internet_connection', true)) {
return '';
}
if (!$this->config->getSystemValue('appstoreenabled', true)
&& $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'no'
&& $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'no') {
return '';
}

$versionString = $this->getCurlVersion();
if (isset($versionString['ssl_version'])) {
$versionString = $versionString['ssl_version'];
} else {
return '';
}

$features = $this->l10n->t('installing and updating apps via the App Store or Federated Cloud Sharing');
if (!$this->config->getSystemValue('appstoreenabled', true)) {
$features = $this->l10n->t('Federated Cloud Sharing');
}

// Check if NSS and perform heuristic check
if (str_starts_with($versionString, 'NSS/')) {
try {
$firstClient = $this->clientService->newClient();
$firstClient->get('https://nextcloud.com/');

$secondClient = $this->clientService->newClient();
$secondClient->get('https://nextcloud.com/');
} catch (ClientException $e) {
if ($e->getResponse()->getStatusCode() === 400) {
return $this->l10n->t('cURL is using an outdated %1$s version (%2$s). Please update your operating system or features such as %3$s will not work reliably.', ['NSS', $versionString, $features]);
}
} catch (\Exception $e) {
$this->logger->warning('error checking curl', [
'app' => 'settings',
'exception' => $e,
]);
return $this->l10n->t('Could not determine if TLS version of cURL is outdated or not because an error happened during the HTTPS request against https://nextcloud.com. Please check the Nextcloud log file for more details.');
}
}

return '';
}

/**
* Checks if the correct memcache module for PHP is installed. Only
* fails if memcached is configured and the working module is not installed.
Expand Down Expand Up @@ -234,6 +156,7 @@ private function isSettimelimitAvailable() {
}

/**
* @NoCSRFRequired
* @return RedirectResponse
* @AuthorizedAdminSetting(settings=OCA\Settings\Settings\Admin\Overview)
*/
Expand Down Expand Up @@ -301,37 +224,6 @@ public function getFailedIntegrityCheckFiles(): DataDisplayResponse {
);
}

protected function getSuggestedOverwriteCliURL(): string {
$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)) {
$suggestedOverwriteCliUrl = '';
}

return $suggestedOverwriteCliUrl;
}

protected function getLastCronInfo(): array {
$lastCronRun = (int)$this->config->getAppValue('core', 'lastcron', '0');
return [
'diffInSeconds' => time() - $lastCronRun,
'relativeTime' => $this->dateTimeFormatter->formatTimeSpan($lastCronRun),
'backgroundJobsUrl' => $this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'server']) . '#backgroundjobs',
];
}

protected function getCronErrors() {
$errors = json_decode($this->config->getAppValue('core', 'cronErrors', ''), true);

if (is_array($errors)) {
return $errors;
}

return [];
}

private function isTemporaryDirectoryWritable(): bool {
try {
if (!empty($this->tempManager->getTempBaseDir())) {
Expand Down Expand Up @@ -399,15 +291,9 @@ protected function isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(): bool {
public function check() {
return new DataResponse(
[
'suggestedOverwriteCliURL' => $this->getSuggestedOverwriteCliURL(),
'cronInfo' => $this->getLastCronInfo(),
'cronErrors' => $this->getCronErrors(),
'isFairUseOfFreePushService' => $this->isFairUseOfFreePushService(),
'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(),
'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'),
'isCorrectMemcachedPHPModuleInstalled' => $this->isCorrectMemcachedPHPModuleInstalled(),
'hasPassedCodeIntegrityCheck' => $this->checker->hasPassedCheck(),
'codeIntegrityCheckerDocumentation' => $this->urlGenerator->linkToDocs('admin-code-integrity'),
'isSettimelimitAvailable' => $this->isSettimelimitAvailable(),
'areWebauthnExtensionsEnabled' => $this->areWebauthnExtensionsEnabled(),
'isMysqlUsedWithoutUTF8MB4' => $this->isMysqlUsedWithoutUTF8MB4(),
Expand Down
76 changes: 76 additions & 0 deletions apps/settings/lib/SetupChecks/CodeIntegrity.php
@@ -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'),
],
],
);
}
}
}