Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/theming/lib/ThemingDefaults.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
namespace OCA\Theming;

use OC\Kernel\Kernel;
use OCA\Theming\AppInfo\Application;
use OCA\Theming\Service\BackgroundService;
use OCP\App\AppPathNotFoundException;
Expand Down Expand Up @@ -395,7 +396,7 @@ public function replaceImagePath($app, $image) {
}
$route = $this->urlGenerator->linkToRoute('theming.Theming.getManifest', ['app' => $app ]);
}
if (str_starts_with($image, 'filetypes/') && file_exists(\OC::$SERVERROOT . '/core/img/' . $image)) {
if (str_starts_with($image, 'filetypes/') && file_exists(Kernel::getInstance()->getServerRoot() . '/core/img/' . $image)) {
$route = $this->urlGenerator->linkToRoute('theming.Icon.getThemedIcon', ['app' => $app, 'image' => $image]);
}

Expand Down
116 changes: 7 additions & 109 deletions console.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,120 +2,18 @@

declare(strict_types=1);

use OCP\IConfig;
use OCP\IURLGenerator;
use OCP\Server;

/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
require_once __DIR__ . '/lib/versioncheck.php';

use OC\Console\Application;
use OCP\AppFramework\Http\Response;
use OCP\Diagnostics\IEventLogger;
use OCP\IRequest;
use OCP\Profiler\IProfiler;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;

define('OC_CONSOLE', 1);

function exceptionHandler($exception) {
echo 'An unhandled exception has been thrown:' . PHP_EOL;
echo $exception;
exit(1);
}
try {
require_once __DIR__ . '/lib/base.php';

// set to run indefinitely if needed
if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
@set_time_limit(0);
}

if (!OC::$CLI) {
echo 'This script can be run from the command line only' . PHP_EOL;
exit(1);
}

$config = Server::get(IConfig::class);
set_exception_handler('exceptionHandler');

if (!function_exists('posix_getuid')) {
echo 'The posix extensions are required - see https://www.php.net/manual/en/book.posix.php' . PHP_EOL;
exit(1);
}

$user = posix_getuid();
$configUser = fileowner(OC::$configDir . 'config.php');
if ($user !== $configUser) {
echo 'Console has to be executed with the user that owns the file config/config.php' . PHP_EOL;
echo 'Current user id: ' . $user . PHP_EOL;
echo 'Owner id of config.php: ' . $configUser . PHP_EOL;
echo "Try adding 'sudo -u #" . $configUser . "' to the beginning of the command (without the single quotes)" . PHP_EOL;
echo "If running with 'docker exec' try adding the option '-u " . $configUser . "' to the docker command (without the single quotes)" . PHP_EOL;
exit(1);
}

$oldWorkingDir = getcwd();
if ($oldWorkingDir === false) {
echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL;
echo "Can't determine current working dir - the script will continue to work but be aware of the above fact." . PHP_EOL;
} elseif ($oldWorkingDir !== __DIR__ && !chdir(__DIR__)) {
echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL;
echo "Can't change to Nextcloud root directory." . PHP_EOL;
exit(1);
}
use OC\Kernel\ConsoleKernel;

if (!(function_exists('pcntl_signal') && function_exists('pcntl_signal_dispatch')) && !in_array('--no-warnings', $argv)) {
echo 'The process control (PCNTL) extensions are required in case you want to interrupt long running commands - see https://www.php.net/manual/en/book.pcntl.php' . PHP_EOL;
echo "Additionally the function 'pcntl_signal' and 'pcntl_signal_dispatch' need to be enabled in your php.ini." . PHP_EOL;
}

$eventLogger = Server::get(IEventLogger::class);
$eventLogger->start('console:build_application', 'Build Application instance and load commands');

$application = Server::get(Application::class);
/* base.php will have removed eventual debug options from argv in $_SERVER */
$argv = $_SERVER['argv'];
$input = new ArgvInput($argv);
$output = new ConsoleOutput();
$application->loadCommands($input, $output);

$eventLogger->end('console:build_application');
$eventLogger->start('console:run', 'Run the command');

$application->setAutoExit(false);
$exitCode = $application->run($input);

$eventLogger->end('console:run');

$profiler = Server::get(IProfiler::class);
if ($profiler->isEnabled()) {
$eventLogger->end('runtime');
$profile = $profiler->collect(Server::get(IRequest::class), new Response());
$profile->setMethod('occ');
$profile->setUrl(implode(' ', $argv));
$profiler->saveProfile($profile);

$urlGenerator = Server::get(IURLGenerator::class);
$url = $urlGenerator->linkToRouteAbsolute('profiler.main.profiler', [
'profiler' => 'db',
'token' => $profile->getToken(),
]);
$output->getErrorOutput()->writeln('Profiler output available at ' . $url);
}

if ($exitCode > 255) {
$exitCode = 255;
}
require_once __DIR__ . '/lib/versioncheck.php';
require_once __DIR__ . '/lib/private/Kernel/Kernel.php';
require_once __DIR__ . '/lib/private/Kernel/ConsoleKernel.php';

exit($exitCode);
} catch (Exception $ex) {
exceptionHandler($ex);
} catch (Error $ex) {
exceptionHandler($ex);
}
(new ConsoleKernel())
->boot()
->run($_SERVER['argv']);
28 changes: 15 additions & 13 deletions core/Controller/SetupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

use OC\IntegrityCheck\Checker;
use OC\Setup;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\IInitialStateService;
use OCP\IURLGenerator;
use OCP\Server;
Expand All @@ -31,7 +35,7 @@ public function __construct(
$this->autoConfigFile = \OC::$configDir . 'autoconfig.php';
}

public function run(array $post): void {
public function run(array $post): Response {
// Check for autosetup:
$post = $this->loadAutoConfig($post);
$opts = $this->setupHelper->getSystemInfo();
Expand All @@ -45,8 +49,7 @@ public function run(array $post): void {
}

if (!$this->setupHelper->canInstallFileExists()) {
$this->displaySetupForbidden();
return;
return $this->displaySetupForbidden();
}

if (isset($post['install']) && $post['install'] == 'true') {
Expand All @@ -56,21 +59,21 @@ public function run(array $post): void {

if (count($e) > 0) {
$options = array_merge($opts, $post, $errors);
$this->display($options);
return $this->display($options);
} else {
$this->finishSetup();
return $this->finishSetup();
}
} else {
$options = array_merge($opts, $post);
$this->display($options);
return $this->display($options);
}
}

private function displaySetupForbidden(): void {
$this->templateManager->printGuestPage('', 'installation_forbidden');
private function displaySetupForbidden(): TemplateResponse {
return new TemplateResponse('', 'installation_forbidden', [], TemplateResponse::RENDER_AS_GUEST);
}

public function display(array $post): void {
public function display(array $post): TemplateResponse {
$defaults = [
'adminlogin' => '',
'adminpass' => '',
Expand Down Expand Up @@ -103,10 +106,10 @@ public function display(array $post): void {
'adminDBConfiguration' => $this->urlGenerator->linkToDocs('admin-db-configuration'),
]);

$this->templateManager->printGuestPage('', 'installation');
return new TemplateResponse('', 'installation', [], TemplateResponse::RENDER_AS_GUEST);
}

private function finishSetup(): void {
private function finishSetup(): RedirectResponse {
if (file_exists($this->autoConfigFile)) {
unlink($this->autoConfigFile);
}
Expand All @@ -116,8 +119,7 @@ private function finishSetup(): void {
$this->templateManager->printGuestPage('', 'installation_incomplete');
}

header('Location: ' . Server::get(IURLGenerator::class)->getAbsoluteURL('index.php/core/apps/recommended'));
exit();
return new RedirectResponse(Server::get(IURLGenerator::class)->getAbsoluteURL('index.php/core/apps/recommended'));
}

/**
Expand Down
102 changes: 10 additions & 92 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,99 +10,17 @@

require_once __DIR__ . '/lib/versioncheck.php';

use OC\ServiceUnavailableException;
use OC\User\LoginException;
use OCP\HintException;
use OC\Kernel\HttpKernel;
use OCP\AppFramework\Http\IOutput;
use OCP\IRequest;
use OCP\Security\Bruteforce\MaxDelayReached;
use OCP\Server;
use OCP\Template\ITemplateManager;
use Psr\Log\LoggerInterface;

try {
require_once __DIR__ . '/lib/base.php';
require_once __DIR__ . '/lib/private/Kernel/Kernel.php';
require_once __DIR__ . '/lib/private/Kernel/HttpKernel.php';

OC::handleRequest();
} catch (ServiceUnavailableException $ex) {
Server::get(LoggerInterface::class)->error($ex->getMessage(), [
'app' => 'index',
'exception' => $ex,
]);
$kernel = (new HttpKernel())
->boot();

//show the user a detailed error page
Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, 503);
} catch (HintException $ex) {
try {
Server::get(ITemplateManager::class)->printErrorPage($ex->getMessage(), $ex->getHint(), 503);
} catch (Exception $ex2) {
try {
Server::get(LoggerInterface::class)->error($ex->getMessage(), [
'app' => 'index',
'exception' => $ex,
]);
Server::get(LoggerInterface::class)->error($ex2->getMessage(), [
'app' => 'index',
'exception' => $ex2,
]);
} catch (Throwable $e) {
// no way to log it properly - but to avoid a white page of death we try harder and ignore this one here
}

//show the user a detailed error page
Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, 500);
}
} catch (LoginException $ex) {
$request = Server::get(IRequest::class);
/**
* Routes with the @CORS annotation and other API endpoints should
* not return a webpage, so we only print the error page when html is accepted,
* otherwise we reply with a JSON array like the SecurityMiddleware would do.
*/
if (stripos($request->getHeader('Accept'), 'html') === false) {
http_response_code(401);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['message' => $ex->getMessage()]);
exit();
}
Server::get(ITemplateManager::class)->printErrorPage($ex->getMessage(), $ex->getMessage(), 401);
} catch (MaxDelayReached $ex) {
$request = Server::get(IRequest::class);
/**
* Routes with the @CORS annotation and other API endpoints should
* not return a webpage, so we only print the error page when html is accepted,
* otherwise we reply with a JSON array like the BruteForceMiddleware would do.
*/
if (stripos($request->getHeader('Accept'), 'html') === false) {
http_response_code(429);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['message' => $ex->getMessage()]);
exit();
}
http_response_code(429);
Server::get(ITemplateManager::class)->printGuestPage('core', '429');
} catch (Exception $ex) {
Server::get(LoggerInterface::class)->error($ex->getMessage(), [
'app' => 'index',
'exception' => $ex,
]);

//show the user a detailed error page
Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, 500);
} catch (Error $ex) {
try {
Server::get(LoggerInterface::class)->error($ex->getMessage(), [
'app' => 'index',
'exception' => $ex,
]);
} catch (Error $e) {
http_response_code(500);
header('Content-Type: text/plain; charset=utf-8');
print("Internal Server Error\n\n");
print("The server encountered an internal error and was unable to complete your request.\n");
print("Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.\n");
print("More details can be found in the webserver log.\n");

throw $ex;
}
Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, 500);
}
$request = $kernel->getServer()->get(IRequest::class);
$output = $kernel->getServer()->get(IOutput::class);
$response = $kernel->handle($request);
$kernel->deliverResponse($request, $response, $output);
Loading