mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-02-04 04:56:52 +00:00
Merge 4a2d5bbfda into d813314494
This commit is contained in:
commit
c035f3e925
1 changed files with 153 additions and 96 deletions
|
|
@ -1,148 +1,210 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
// increase memory limit to 2GB
|
||||
ini_set('memory_limit', '2048M');
|
||||
/**
|
||||
* Entry point/Bootstrapper for the Nextcloud All-in-One Web UI & API.
|
||||
* Initializes DI container, configures PHP, registers routes & middleware.
|
||||
*/
|
||||
|
||||
// set max execution time to 2h just in case of a very slow internet connection
|
||||
ini_set('max_execution_time', '7200');
|
||||
|
||||
// Log whole log messages
|
||||
ini_set('log_errors_max_len', '0');
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use DI\Container;
|
||||
use Slim\Csrf\Guard;
|
||||
use Slim\Factory\AppFactory;
|
||||
use Slim\Routing\RouteCollectorProxy;
|
||||
use Slim\Views\Twig;
|
||||
use Slim\Views\TwigMiddleware;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
//-------------------------------------------------
|
||||
// Configuration Constants
|
||||
//-------------------------------------------------
|
||||
const AIO_MEMORY_LIMIT = '2048M';
|
||||
const AIO_MAX_EXECUTION_TIME = '7200'; // (2h) in case of a very slow internet connection
|
||||
const AIO_SESSION_MAX_LIFETIME = '86400'; // (24h)
|
||||
const AIO_COOKIE_LIFETIME = '0'; // Auto logout on browser close
|
||||
const AIO_LOG_ERRORS_MAX_LEN = '0'; // Log whole log messages
|
||||
const AIO_TWIG_CACHE_PATH = false; // e.g., __DIR__ . '/../var/twig-cache'
|
||||
const AIO_DISPLAY_ERRORS = false;
|
||||
|
||||
//-------------------------------------------------
|
||||
// PHP Settings
|
||||
//-------------------------------------------------
|
||||
ini_set('memory_limit', AIO_MEMORY_LIMIT);
|
||||
ini_set('max_execution_time', AIO_MAX_EXECUTION_TIME);
|
||||
ini_set('session.cookie_lifetime', AIO_COOKIE_LIFETIME);
|
||||
ini_set('session.gc_maxlifetime', AIO_SESSION_MAX_LIFETIME);
|
||||
ini_set('log_errors_max_len', AIO_LOG_ERRORS_MAX_LEN);
|
||||
|
||||
//-------------------------------------------------
|
||||
// Dependency Injection
|
||||
//-------------------------------------------------
|
||||
$container = \AIO\DependencyInjection::GetContainer();
|
||||
AppFactory::setContainer($container);
|
||||
|
||||
// Session directory depends on application config:
|
||||
$dataConst = $container->get(\AIO\Data\DataConst::class);
|
||||
ini_set('session.save_path', $dataConst->GetSessionDirectory());
|
||||
|
||||
// Auto logout on browser close
|
||||
ini_set('session.cookie_lifetime', '0');
|
||||
|
||||
# Keep session for 24h max
|
||||
ini_set('session.gc_maxlifetime', '86400');
|
||||
|
||||
// Create app
|
||||
AppFactory::setContainer($container);
|
||||
//-------------------------------------------------
|
||||
// Application Creation and Core Middleware
|
||||
//-------------------------------------------------
|
||||
$app = AppFactory::create();
|
||||
$responseFactory = $app->getResponseFactory();
|
||||
|
||||
// Register Middleware On Container
|
||||
$container->set(Guard::class, function () use ($responseFactory) {
|
||||
// Register CSRF middleware (container-only)
|
||||
$container->set(Guard::class, function () use ($responseFactory): Guard {
|
||||
$guard = new Guard($responseFactory);
|
||||
$guard->setPersistentTokenMode(true);
|
||||
return $guard;
|
||||
});
|
||||
|
||||
// Register Middleware To Be Executed On All Routes
|
||||
session_start();
|
||||
|
||||
// Activate CSRF middleware for all routes
|
||||
$app->add(Guard::class);
|
||||
|
||||
// Create Twig
|
||||
$twig = Twig::create(__DIR__ . '/../templates/', ['cache' => false]);
|
||||
// Setup and activate Twig middleware
|
||||
$twig = Twig::create(__DIR__ . '/../templates/',
|
||||
[ 'cache' => AIO_TWIG_CACHE_PATH ]
|
||||
);
|
||||
$app->add(TwigMiddleware::create($app, $twig));
|
||||
|
||||
// Add CSRF extension to Twig so templates can access CSRF tokens
|
||||
$twig->addExtension(new \AIO\Twig\CsrfExtension($container->get(Guard::class)));
|
||||
|
||||
// Auth Middleware
|
||||
// Establish and activate authentication middleware for all routes
|
||||
$app->add(new \AIO\Middleware\AuthMiddleware($container->get(\AIO\Auth\AuthManager::class)));
|
||||
|
||||
// API
|
||||
$app->post('/api/docker/watchtower', AIO\Controller\DockerController::class . ':StartWatchtowerContainer');
|
||||
$app->get('/api/docker/getwatchtower', AIO\Controller\DockerController::class . ':StartWatchtowerContainer');
|
||||
$app->post('/api/docker/start', AIO\Controller\DockerController::class . ':StartContainer');
|
||||
$app->post('/api/docker/backup', AIO\Controller\DockerController::class . ':StartBackupContainerBackup');
|
||||
$app->post('/api/docker/backup-check', AIO\Controller\DockerController::class . ':StartBackupContainerCheck');
|
||||
$app->post('/api/docker/backup-list', AIO\Controller\DockerController::class . ':StartBackupContainerList');
|
||||
$app->post('/api/docker/backup-check-repair', AIO\Controller\DockerController::class . ':StartBackupContainerCheckRepair');
|
||||
$app->post('/api/docker/backup-test', AIO\Controller\DockerController::class . ':StartBackupContainerTest');
|
||||
$app->post('/api/docker/restore', AIO\Controller\DockerController::class . ':StartBackupContainerRestore');
|
||||
$app->post('/api/docker/stop', AIO\Controller\DockerController::class . ':StopContainer');
|
||||
$app->get('/api/docker/logs', AIO\Controller\DockerController::class . ':GetLogs');
|
||||
$app->post('/api/auth/login', AIO\Controller\LoginController::class . ':TryLogin');
|
||||
$app->get('/api/auth/getlogin', AIO\Controller\LoginController::class . ':GetTryLogin');
|
||||
$app->post('/api/auth/logout', AIO\Controller\LoginController::class . ':Logout');
|
||||
$app->post('/api/configuration', \AIO\Controller\ConfigurationController::class . ':SetConfig');
|
||||
//-------------------------------------------------
|
||||
// API Routes
|
||||
//-------------------------------------------------
|
||||
$app->group('/api/docker', function (RouteCollectorProxy $group): void {
|
||||
// Docker Container management
|
||||
$group->post('/watchtower', AIO\Controller\DockerController::class . ':StartWatchtowerContainer');
|
||||
$group->get('/getwatchtower', AIO\Controller\DockerController::class . ':StartWatchtowerContainer');
|
||||
$group->post('/start', AIO\Controller\DockerController::class . ':StartContainer');
|
||||
$group->post('/stop', AIO\Controller\DockerController::class . ':StopContainer');
|
||||
$group->get('/logs', AIO\Controller\DockerController::class . ':GetLogs');
|
||||
// Backups
|
||||
$group->post('/backup', AIO\Controller\DockerController::class . ':StartBackupContainerBackup');
|
||||
$group->post('/backup-check', AIO\Controller\DockerController::class . ':StartBackupContainerCheck');
|
||||
$group->post('/backup-list', AIO\Controller\DockerController::class . ':StartBackupContainerList');
|
||||
$group->post('/backup-check-repair', AIO\Controller\DockerController::class . ':StartBackupContainerCheckRepair');
|
||||
$group->post('/backup-test', AIO\Controller\DockerController::class . ':StartBackupContainerTest');
|
||||
$group->post('/restore', AIO\Controller\DockerController::class . ':StartBackupContainerRestore');
|
||||
});
|
||||
|
||||
// Views
|
||||
$app->get('/containers', function (Request $request, Response $response, array $args) use ($container) {
|
||||
// Auth-related
|
||||
$app->group('/api/auth', function (RouteCollectorProxy $group): void {
|
||||
$group->post('/login', AIO\Controller\LoginController::class . ':TryLogin');
|
||||
$group->get('/getlogin', AIO\Controller\LoginController::class . ':GetTryLogin');
|
||||
$group->post('/logout', AIO\Controller\LoginController::class . ':Logout');
|
||||
});
|
||||
|
||||
// Configuration endpoints
|
||||
$app->post('/api/configuration', AIO\Controller\ConfigurationController::class . ':SetConfig');
|
||||
|
||||
//-------------------------------------------------
|
||||
// Views Routes
|
||||
//-------------------------------------------------
|
||||
|
||||
// Containers
|
||||
$app->get('/containers', function (Request $request, Response $response, array $args) use ($container): Response {
|
||||
$view = Twig::fromRequest($request);
|
||||
$view->addExtension(new \AIO\Twig\ClassExtension());
|
||||
|
||||
/** @var \AIO\Data\ConfigurationManager $configurationManager */
|
||||
$configurationManager = $container->get(\AIO\Data\ConfigurationManager::class);
|
||||
/** @var \AIO\Docker\DockerActionManager $dockerActionManager */
|
||||
$dockerActionManager = $container->get(\AIO\Docker\DockerActionManager::class);
|
||||
/** @var \AIO\Controller\DockerController $dockerController */
|
||||
$dockerController = $container->get(\AIO\Controller\DockerController::class);
|
||||
|
||||
// Ensure master container is attached to the required Docker network
|
||||
$dockerActionManager->ConnectMasterContainerToNetwork();
|
||||
// Ensure the domaincheck container is started for domain configuration validation
|
||||
$dockerController->StartDomaincheckContainer();
|
||||
|
||||
// Check if bypass_mastercontainer_update is provided on the URL, a special developer mode to bypass a mastercontainer update and use local image.
|
||||
// URL parameters
|
||||
$params = $request->getQueryParams();
|
||||
$bypass_mastercontainer_update = isset($params['bypass_mastercontainer_update']);
|
||||
$bypass_container_update = isset($params['bypass_container_update']);
|
||||
$skip_domain_validation = isset($params['skip_domain_validation']);
|
||||
$bypassMastercontainerUpdate = isset($params['bypass_mastercontainer_update']);
|
||||
$bypassContainerUpdate = isset($params['bypass_container_update']);
|
||||
$skipDomainValidation = isset($params['skip_domain_validation']);
|
||||
|
||||
return $view->render($response, 'containers.twig', [
|
||||
// === Instance & Domain Information ===
|
||||
'domain' => $configurationManager->GetDomain(),
|
||||
'timezone' => $configurationManager->GetTimezone(),
|
||||
'current_channel' => $dockerActionManager->GetCurrentChannel(),
|
||||
|
||||
// ---- Ports & Networking ----
|
||||
'apache_port' => $configurationManager->GetApachePort(),
|
||||
'talk_port' => $configurationManager->GetTalkPort(),
|
||||
|
||||
// ---- Containers & Status ----
|
||||
'containers' => (new \AIO\ContainerDefinitionFetcher($configurationManager, $container))->FetchDefinition(),
|
||||
'is_mastercontainer_update_available' => $bypassMastercontainerUpdate ? false : $dockerActionManager->IsMastercontainerUpdateAvailable(),
|
||||
'was_start_button_clicked' => $configurationManager->wasStartButtonClicked(),
|
||||
'has_update_available' => $dockerActionManager->isAnyUpdateAvailable(),
|
||||
'automatic_updates' => $configurationManager->areAutomaticUpdatesEnabled(),
|
||||
|
||||
// ---- Backups ----
|
||||
'borg_backup_host_location' => $configurationManager->GetBorgBackupHostLocation(),
|
||||
'borg_remote_repo' => $configurationManager->GetBorgRemoteRepo(),
|
||||
'borg_public_key' => $configurationManager->GetBorgPublicKey(),
|
||||
'nextcloud_password' => $configurationManager->GetAndGenerateSecret('NEXTCLOUD_PASSWORD'),
|
||||
'containers' => (new \AIO\ContainerDefinitionFetcher($container->get(\AIO\Data\ConfigurationManager::class), $container))->FetchDefinition(),
|
||||
'borgbackup_password' => $configurationManager->GetAndGenerateSecret('BORGBACKUP_PASSWORD'),
|
||||
'is_mastercontainer_update_available' => ( $bypass_mastercontainer_update ? false : $dockerActionManager->IsMastercontainerUpdateAvailable() ),
|
||||
'has_backup_run_once' => $configurationManager->hasBackupRunOnce(),
|
||||
'is_backup_container_running' => $dockerActionManager->isBackupContainerRunning(),
|
||||
'backup_exit_code' => $dockerActionManager->GetBackupcontainerExitCode(),
|
||||
'is_instance_restore_attempt' => $configurationManager->isInstanceRestoreAttempt(),
|
||||
'borg_backup_mode' => $configurationManager->GetBackupMode(),
|
||||
'was_start_button_clicked' => $configurationManager->wasStartButtonClicked(),
|
||||
'has_update_available' => $dockerActionManager->isAnyUpdateAvailable(),
|
||||
'last_backup_time' => $configurationManager->GetLastBackupTime(),
|
||||
'backup_times' => $configurationManager->GetBackupTimes(),
|
||||
'current_channel' => $dockerActionManager->GetCurrentChannel(),
|
||||
'is_clamav_enabled' => $configurationManager->isClamavEnabled(),
|
||||
'is_onlyoffice_enabled' => $configurationManager->isOnlyofficeEnabled(),
|
||||
'is_collabora_enabled' => $configurationManager->isCollaboraEnabled(),
|
||||
'is_talk_enabled' => $configurationManager->isTalkEnabled(),
|
||||
'borg_restore_password' => $configurationManager->GetBorgRestorePassword(),
|
||||
'daily_backup_time' => $configurationManager->GetDailyBackupTime(),
|
||||
'is_daily_backup_running' => $configurationManager->isDailyBackupRunning(),
|
||||
'timezone' => $configurationManager->GetTimezone(),
|
||||
'skip_domain_validation' => $configurationManager->shouldDomainValidationBeSkipped($skip_domain_validation),
|
||||
'talk_port' => $configurationManager->GetTalkPort(),
|
||||
'collabora_dictionaries' => $configurationManager->GetCollaboraDictionaries(),
|
||||
'collabora_additional_options' => $configurationManager->GetAdditionalCollaboraOptions(),
|
||||
'automatic_updates' => $configurationManager->areAutomaticUpdatesEnabled(),
|
||||
'is_backup_section_enabled' => $configurationManager->isBackupSectionEnabled(),
|
||||
'is_imaginary_enabled' => $configurationManager->isImaginaryEnabled(),
|
||||
'is_fulltextsearch_enabled' => $configurationManager->isFulltextsearchEnabled(),
|
||||
'additional_backup_directories' => $configurationManager->GetAdditionalBackupDirectoriesString(),
|
||||
|
||||
// ---- Nextcloud and PHP Config ----
|
||||
'nextcloud_password' => $configurationManager->GetAndGenerateSecret('NEXTCLOUD_PASSWORD'),
|
||||
'nextcloud_datadir' => $configurationManager->GetNextcloudDatadirMount(),
|
||||
'nextcloud_mount' => $configurationManager->GetNextcloudMount(),
|
||||
'nextcloud_upload_limit' => $configurationManager->GetNextcloudUploadLimit(),
|
||||
'nextcloud_max_time' => $configurationManager->GetNextcloudMaxTime(),
|
||||
'nextcloud_memory_limit' => $configurationManager->GetNextcloudMemoryLimit(),
|
||||
|
||||
// ---- Feature/App Enablement ----
|
||||
'is_clamav_enabled' => $configurationManager->isClamavEnabled(),
|
||||
'is_onlyoffice_enabled' => $configurationManager->isOnlyofficeEnabled(),
|
||||
'is_collabora_enabled' => $configurationManager->isCollaboraEnabled(),
|
||||
'is_talk_enabled' => $configurationManager->isTalkEnabled(),
|
||||
'is_backup_section_enabled' => $configurationManager->isBackupSectionEnabled(),
|
||||
'is_imaginary_enabled' => $configurationManager->isImaginaryEnabled(),
|
||||
'is_fulltextsearch_enabled' => $configurationManager->isFulltextsearchEnabled(),
|
||||
'is_dri_device_enabled' => $configurationManager->isDriDeviceEnabled(),
|
||||
'is_nvidia_gpu_enabled' => $configurationManager->isNvidiaGpuEnabled(),
|
||||
'is_talk_recording_enabled' => $configurationManager->isTalkRecordingEnabled(),
|
||||
'is_docker_socket_proxy_enabled' => $configurationManager->isDockerSocketProxyEnabled(),
|
||||
'is_whiteboard_enabled' => $configurationManager->isWhiteboardEnabled(),
|
||||
|
||||
// ---- Integration-specific Customization ----
|
||||
'collabora_dictionaries' => $configurationManager->GetCollaboraDictionaries(),
|
||||
'collabora_additional_options' => $configurationManager->GetAdditionalCollaboraOptions(),
|
||||
|
||||
// ---- Community Containers ----
|
||||
'community_containers' => $configurationManager->listAvailableCommunityContainers(),
|
||||
'community_containers_enabled' => $configurationManager->GetEnabledCommunityContainers(),
|
||||
'bypass_container_update' => $bypass_container_update,
|
||||
|
||||
// ---- Misc Flags ----
|
||||
'skip_domain_validation' => $configurationManager->shouldDomainValidationBeSkipped($skipDomainValidation),
|
||||
'bypass_container_update' => $bypassContainerUpdate,
|
||||
]);
|
||||
})->setName('profile');
|
||||
$app->get('/login', function (Request $request, Response $response, array $args) use ($container) {
|
||||
});
|
||||
|
||||
// Login
|
||||
$app->get('/login', function (Request $request, Response $response, array $args) use ($container): Response {
|
||||
$view = Twig::fromRequest($request);
|
||||
/** @var \AIO\Docker\DockerActionManager $dockerActionManager */
|
||||
$dockerActionManager = $container->get(\AIO\Docker\DockerActionManager::class);
|
||||
|
|
@ -150,51 +212,46 @@ $app->get('/login', function (Request $request, Response $response, array $args)
|
|||
'is_login_allowed' => $dockerActionManager->isLoginAllowed(),
|
||||
]);
|
||||
});
|
||||
$app->get('/setup', function (Request $request, Response $response, array $args) use ($container) {
|
||||
|
||||
// Setup
|
||||
$app->get('/setup', function (Request $request, Response $response, array $args) use ($container): Response {
|
||||
$view = Twig::fromRequest($request);
|
||||
/** @var \AIO\Data\Setup $setup */
|
||||
$setup = $container->get(\AIO\Data\Setup::class);
|
||||
|
||||
if(!$setup->CanBeInstalled()) {
|
||||
return $view->render(
|
||||
$response,
|
||||
'already-installed.twig'
|
||||
);
|
||||
if (!$setup->CanBeInstalled()) {
|
||||
return $view->render($response, 'already-installed.twig');
|
||||
}
|
||||
|
||||
return $view->render(
|
||||
$response,
|
||||
'setup.twig',
|
||||
[
|
||||
return $view->render($response, 'setup.twig', [
|
||||
'password' => $setup->Setup(),
|
||||
]
|
||||
);
|
||||
]);
|
||||
});
|
||||
|
||||
// Auth Redirector
|
||||
$app->get('/', function (\Psr\Http\Message\RequestInterface $request, Response $response, array $args) use ($container) {
|
||||
//-------------------------------------------------
|
||||
// Root Redirector
|
||||
//-------------------------------------------------
|
||||
$app->get('/', function (Request $request, Response $response, array $args) use ($container): Response {
|
||||
/** @var \AIO\Auth\AuthManager $authManager */
|
||||
$authManager = $container->get(\AIO\Auth\AuthManager::class);
|
||||
|
||||
/** @var \AIO\Data\Setup $setup */
|
||||
$setup = $container->get(\AIO\Data\Setup::class);
|
||||
if($setup->CanBeInstalled()) {
|
||||
return $response
|
||||
->withHeader('Location', 'setup')
|
||||
->withStatus(302);
|
||||
}
|
||||
|
||||
if($authManager->IsAuthenticated()) {
|
||||
return $response
|
||||
->withHeader('Location', 'containers')
|
||||
->withStatus(302);
|
||||
} else {
|
||||
return $response
|
||||
->withHeader('Location', 'login')
|
||||
->withStatus(302);
|
||||
if ($setup->CanBeInstalled()) {
|
||||
return $response->withHeader('Location', 'setup')->withStatus(302);
|
||||
}
|
||||
if ($authManager->IsAuthenticated()) {
|
||||
return $response->withHeader('Location', 'containers')->withStatus(302);
|
||||
}
|
||||
return $response->withHeader('Location', 'login')->withStatus(302);
|
||||
});
|
||||
|
||||
$errorMiddleware = $app->addErrorMiddleware(false, true, true);
|
||||
//-------------------------------------------------
|
||||
// Error Middleware
|
||||
//-------------------------------------------------
|
||||
|
||||
// TODO: Figure out why the default plain text renderer is being used by logging
|
||||
// TODO: Change logging to not generate stack traces for 404s
|
||||
// TODO: Change logging to log the path
|
||||
$errorMiddleware = $app->addErrorMiddleware(AIO_DISPLAY_ERRORS, true, true);
|
||||
|
||||
$app->run();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue