From 6052b9820afba7ad067c67fdeccd45588bd9cb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D?= Date: Sat, 11 Jun 2022 11:55:49 +0200 Subject: [PATCH] refactor: [WIP] Migrate config general controller. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rubén D --- .../ConfigGeneral/DownloadConfigBackup.php | 127 +++++++++++ .../ConfigGeneral/DownloadLogController.php | 102 +++++++++ .../SaveController.php} | 215 ++++++------------ 3 files changed, 298 insertions(+), 146 deletions(-) create mode 100644 app/modules/web/Controllers/ConfigGeneral/DownloadConfigBackup.php create mode 100644 app/modules/web/Controllers/ConfigGeneral/DownloadLogController.php rename app/modules/web/Controllers/{ConfigGeneralController.php => ConfigGeneral/SaveController.php} (58%) diff --git a/app/modules/web/Controllers/ConfigGeneral/DownloadConfigBackup.php b/app/modules/web/Controllers/ConfigGeneral/DownloadConfigBackup.php new file mode 100644 index 00000000..d6f169a5 --- /dev/null +++ b/app/modules/web/Controllers/ConfigGeneral/DownloadConfigBackup.php @@ -0,0 +1,127 @@ +. + */ + +namespace SP\Modules\Web\Controllers\ConfigGeneral; + +use Exception; +use Klein\Klein; +use RuntimeException; +use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; +use SP\Core\Acl\UnauthorizedPageException; +use SP\Core\Application; +use SP\Core\Events\Event; +use SP\Core\Events\EventMessage; +use SP\Core\PhpExtensionChecker; +use SP\Core\UI\ThemeInterface; +use SP\Domain\Config\ConfigBackupServiceInterface; +use SP\Domain\Config\Services\ConfigBackupService; +use SP\Http\RequestInterface; +use SP\Modules\Web\Controllers\SimpleControllerBase; +use SP\Modules\Web\Controllers\Traits\JsonTrait; + +/** + * Class DownloadConfigBackup + */ +final class DownloadConfigBackup extends SimpleControllerBase +{ + use JsonTrait; + + private ConfigBackupServiceInterface $configBackupService; + + public function __construct( + Application $application, + ThemeInterface $theme, + Klein $router, + Acl $acl, + RequestInterface $request, + PhpExtensionChecker $extensionChecker, + ConfigBackupServiceInterface $configBackupService + ) { + parent::__construct($application, $theme, $router, $acl, $request, $extensionChecker); + + $this->configBackupService = $configBackupService; + } + + public function downloadConfigBackupAction(string $type): string + { + if ($this->configData->isDemoEnabled()) { + return __('Ey, this is a DEMO!!'); + } + + try { + $this->eventDispatcher->notifyEvent( + 'download.configBackupFile', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('File downloaded')) + ->addDetail(__u('File'), 'config.json') + ) + ); + + if ($type === 'json') { + $data = ConfigBackupService::configToJson($this->configBackupService->getBackup()); + } else { + throw new RuntimeException('Not implemented'); + } + + $response = $this->router->response(); + $response->header('Cache-Control', 'max-age=60, must-revalidate'); + $response->header('Content-length', strlen($data)); + $response->header('Content-type', 'application/json'); + $response->header('Content-Description', ' sysPass file'); + $response->header('Content-transfer-encoding', 'chunked'); + $response->header('Content-Disposition', 'attachment; filename="config.json"'); + $response->header('Set-Cookie', 'fileDownload=true; path=/'); + $response->header('Content-transfer-encoding', 'binary'); + $response->header('Set-Cookie', 'fileDownload=true; path=/'); + + $response->body($data); + $response->send(true); + } catch (Exception $e) { + processException($e); + + $this->eventDispatcher->notifyEvent('exception', new Event($e)); + } + + return ''; + } + + /** + * @throws \JsonException + * @throws \SP\Core\Exceptions\SessionTimeout + */ + protected function initialize(): void + { + try { + $this->checks(); + $this->checkAccess(ActionsInterface::CONFIG_GENERAL); + } catch (UnauthorizedPageException $e) { + $this->eventDispatcher->notifyEvent('exception', new Event($e)); + + $this->returnJsonResponseException($e); + } + } +} \ No newline at end of file diff --git a/app/modules/web/Controllers/ConfigGeneral/DownloadLogController.php b/app/modules/web/Controllers/ConfigGeneral/DownloadLogController.php new file mode 100644 index 00000000..36d1f8c6 --- /dev/null +++ b/app/modules/web/Controllers/ConfigGeneral/DownloadLogController.php @@ -0,0 +1,102 @@ +. + */ + +namespace SP\Modules\Web\Controllers\ConfigGeneral; + + +use Exception; +use SP\Core\Acl\ActionsInterface; +use SP\Core\Acl\UnauthorizedPageException; +use SP\Core\Context\SessionContext; +use SP\Core\Events\Event; +use SP\Core\Events\EventMessage; +use SP\Infrastructure\File\FileHandler; +use SP\Modules\Web\Controllers\SimpleControllerBase; +use SP\Modules\Web\Controllers\Traits\JsonTrait; + +/** + * Class DownloadLogController + */ +final class DownloadLogController extends SimpleControllerBase +{ + use JsonTrait; + + public function downloadLogAction(): string + { + if ($this->configData->isDemoEnabled()) { + return __('Ey, this is a DEMO!!'); + } + + try { + SessionContext::close(); + + $file = new FileHandler(LOG_FILE); + $file->checkFileExists(); + + $this->eventDispatcher->notifyEvent( + 'download.logFile', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('File downloaded')) + ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile())) + ) + ); + + $response = $this->router->response(); + $response->header('Cache-Control', 'max-age=60, must-revalidate'); + $response->header('Content-length', $file->getFileSize()); + $response->header('Content-type', $file->getFileType()); + $response->header('Content-Description', ' sysPass file'); + $response->header('Content-transfer-encoding', 'chunked'); + $response->header('Content-Disposition', 'attachment; filename="'.basename($file->getFile()).'"'); + $response->header('Set-Cookie', 'fileDownload=true; path=/'); + $response->send(); + + $file->readChunked(); + } catch (Exception $e) { + processException($e); + + $this->eventDispatcher->notifyEvent('exception', new Event($e)); + } + + return ''; + } + + /** + * @throws \JsonException + * @throws \SP\Core\Exceptions\SessionTimeout + */ + protected function initialize(): void + { + try { + $this->checks(); + $this->checkAccess(ActionsInterface::CONFIG_GENERAL); + } catch (UnauthorizedPageException $e) { + $this->eventDispatcher->notifyEvent('exception', new Event($e)); + + $this->returnJsonResponseException($e); + } + } +} \ No newline at end of file diff --git a/app/modules/web/Controllers/ConfigGeneralController.php b/app/modules/web/Controllers/ConfigGeneral/SaveController.php similarity index 58% rename from app/modules/web/Controllers/ConfigGeneralController.php rename to app/modules/web/Controllers/ConfigGeneral/SaveController.php index 5e7ae6ed..eede16c9 100644 --- a/app/modules/web/Controllers/ConfigGeneralController.php +++ b/app/modules/web/Controllers/ConfigGeneral/SaveController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -22,19 +22,17 @@ * along with sysPass. If not, see . */ -namespace SP\Modules\Web\Controllers; +namespace SP\Modules\Web\Controllers\ConfigGeneral; -use Exception; -use RuntimeException; use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; -use SP\Core\Context\SessionContext; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; -use SP\Domain\Config\Services\ConfigBackupService; +use SP\Core\Exceptions\SPException; +use SP\Core\Exceptions\ValidationException; +use SP\Domain\Config\In\ConfigDataInterface; use SP\Domain\Config\Services\ConfigUtil; -use SP\Http\JsonResponse; -use SP\Infrastructure\File\FileHandler; +use SP\Modules\Web\Controllers\SimpleControllerBase; use SP\Modules\Web\Controllers\Traits\ConfigTrait; use SP\Util\Util; @@ -43,13 +41,11 @@ use SP\Util\Util; * * @package SP\Modules\Web\Controllers */ -final class ConfigGeneralController extends SimpleControllerBase +final class SaveController extends SimpleControllerBase { use ConfigTrait; /** - * @throws \DI\DependencyException - * @throws \DI\NotFoundException * @throws \JsonException */ public function saveAction(): bool @@ -57,7 +53,35 @@ final class ConfigGeneralController extends SimpleControllerBase $configData = $this->config->getConfigData(); $eventMessage = EventMessage::factory(); - // General + try { + $this->handleGeneralConfig($configData); + $this->handleEventsConfig($configData, $eventMessage); + $this->handleProxyConfig($configData, $eventMessage); + $this->handleAuthConfig($configData, $eventMessage); + } catch (ValidationException $e) { + return $this->returnJsonResponseException($e); + } + + return $this->saveConfig( + $configData, + $this->config, + function () use ($eventMessage, $configData) { + if ($configData->isMaintenance()) { + Util::lockApp($this->session->getUserData()->getId(), 'config'); + } + + $this->eventDispatcher->notifyEvent('save.config.general', new Event($this, $eventMessage)); + } + ); + } + + /** + * @param \SP\Domain\Config\In\ConfigDataInterface $configData + * + * @return void + */ + private function handleGeneralConfig(ConfigDataInterface $configData): void + { $siteLang = $this->request->analyzeString('sitelang'); $siteTheme = $this->request->analyzeString('sitetheme', 'material-blue'); $sessionTimeout = $this->request->analyzeInt('session_timeout', 300); @@ -79,8 +103,17 @@ final class ConfigGeneralController extends SimpleControllerBase $configData->setCheckUpdates($checkUpdatesEnabled); $configData->setCheckNotices($checkNoticesEnabled); $configData->setEncryptSession($encryptSessionEnabled); + } - // Events + /** + * @param \SP\Domain\Config\In\ConfigDataInterface $configData + * @param \SP\Core\Events\EventMessage $eventMessage + * + * @return void + * @throws \SP\Core\Exceptions\ValidationException + */ + private function handleEventsConfig(ConfigDataInterface $configData, EventMessage $eventMessage): void + { $logEnabled = $this->request->analyzeBool('log_enabled', false); $syslogEnabled = $this->request->analyzeBool('syslog_enabled', false); $remoteSyslogEnabled = $this->request->analyzeBool('remotesyslog_enabled', false); @@ -91,9 +124,7 @@ final class ConfigGeneralController extends SimpleControllerBase $configData->setLogEvents( $this->request->analyzeArray( 'log_events', - function ($items) { - return ConfigUtil::eventsAdapter($items); - }, + fn($items) => ConfigUtil::eventsAdapter($items), [] ) ); @@ -102,10 +133,7 @@ final class ConfigGeneralController extends SimpleControllerBase if ($remoteSyslogEnabled) { if (!$syslogServer || !$syslogPort) { - return $this->returnJsonResponse( - JsonResponse::JSON_ERROR, - __u('Missing remote syslog parameters') - ); + throw new ValidationException(SPException::ERROR, __u('Missing remote syslog parameters')); } $configData->setSyslogRemoteEnabled(true); @@ -120,21 +148,25 @@ final class ConfigGeneralController extends SimpleControllerBase $eventMessage->addDescription(__u('Remote syslog disabled')); } + } - // Proxy + /** + * @param \SP\Domain\Config\In\ConfigDataInterface $configData + * @param \SP\Core\Events\EventMessage $eventMessage + * + * @return void + * @throws \SP\Core\Exceptions\ValidationException + */ + private function handleProxyConfig(ConfigDataInterface $configData, EventMessage $eventMessage): void + { $proxyEnabled = $this->request->analyzeBool('proxy_enabled', false); $proxyServer = $this->request->analyzeString('proxy_server'); $proxyPort = $this->request->analyzeInt('proxy_port', 8080); $proxyUser = $this->request->analyzeString('proxy_user'); $proxyPass = $this->request->analyzeEncrypted('proxy_pass'); - - // Valores para Proxy if ($proxyEnabled && (!$proxyServer || !$proxyPort)) { - return $this->returnJsonResponse( - JsonResponse::JSON_ERROR, - __u('Missing Proxy parameters ') - ); + throw new ValidationException(SPException::ERROR, __u('Missing Proxy parameters ')); } if ($proxyEnabled) { @@ -155,15 +187,22 @@ final class ConfigGeneralController extends SimpleControllerBase $eventMessage->addDescription(__u('Proxy disabled')); } + } - // Autentificación + /** + * @param \SP\Domain\Config\In\ConfigDataInterface $configData + * @param \SP\Core\Events\EventMessage $eventMessage + * + * @return void + */ + private function handleAuthConfig(ConfigDataInterface $configData, EventMessage $eventMessage): void + { $authBasicEnabled = $this->request->analyzeBool('authbasic_enabled', false); $authBasicAutologinEnabled = $this->request->analyzeBool('authbasicautologin_enabled', false); $authBasicDomain = $this->request->analyzeString('authbasic_domain'); $authSsoDefaultGroup = $this->request->analyzeInt('sso_defaultgroup'); $authSsoDefaultProfile = $this->request->analyzeInt('sso_defaultprofile'); - // Valores para Autentificación if ($authBasicEnabled) { $configData->setAuthBasicEnabled(true); $configData->setAuthBasicAutoLoginEnabled($authBasicAutologinEnabled); @@ -180,119 +219,6 @@ final class ConfigGeneralController extends SimpleControllerBase $eventMessage->addDescription(__u('Auth Basic disabled')); } - - return $this->saveConfig( - $configData, - $this->config, - function () use ($eventMessage, $configData) { - if ($configData->isMaintenance()) { - Util::lockApp( - $this->session->getUserData()->getId(), - 'config' - ); - } - - $this->eventDispatcher->notifyEvent( - 'save.config.general', - new Event($this, $eventMessage) - ); - } - ); - } - - public function downloadLogAction(): string - { - if ($this->configData->isDemoEnabled()) { - return __('Ey, this is a DEMO!!'); - } - - try { - SessionContext::close(); - - $file = new FileHandler(LOG_FILE); - $file->checkFileExists(); - - $this->eventDispatcher->notifyEvent( - 'download.logFile', - new Event( - $this, - EventMessage::factory() - ->addDescription(__u('File downloaded')) - ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile())) - ) - ); - - $response = $this->router->response(); - $response->header('Cache-Control', 'max-age=60, must-revalidate'); - $response->header('Content-length', $file->getFileSize()); - $response->header('Content-type', $file->getFileType()); - $response->header('Content-Description', ' sysPass file'); - $response->header('Content-transfer-encoding', 'chunked'); - $response->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"'); - $response->header('Set-Cookie', 'fileDownload=true; path=/'); - $response->send(); - - $file->readChunked(); - } catch (Exception $e) { - processException($e); - - $this->eventDispatcher->notifyEvent( - 'exception', - new Event($e) - ); - } - - return ''; - } - - public function downloadConfigBackupAction(string $type): string - { - if ($this->configData->isDemoEnabled()) { - return __('Ey, this is a DEMO!!'); - } - - try { - $this->eventDispatcher->notifyEvent( - 'download.configBackupFile', - new Event( - $this, - EventMessage::factory() - ->addDescription(__u('File downloaded')) - ->addDetail(__u('File'), 'config.json') - ) - ); - - $configBackupService = $this->dic->get(ConfigBackupService::class); - - if ($type === 'json') { - $data = ConfigBackupService::configToJson($configBackupService->getBackup()); - } else { - throw new RuntimeException('Not implemented'); - } - - $response = $this->router->response(); - $response->header('Cache-Control', 'max-age=60, must-revalidate'); - $response->header('Content-length', strlen($data)); - $response->header('Content-type', 'application/json'); - $response->header('Content-Description', ' sysPass file'); - $response->header('Content-transfer-encoding', 'chunked'); - $response->header('Content-Disposition', 'attachment; filename="config.json"'); - $response->header('Set-Cookie', 'fileDownload=true; path=/'); - $response->header('Content-transfer-encoding', 'binary'); - $response->header('Set-Cookie', 'fileDownload=true; path=/'); - - $response->body($data); - $response->send(true); - } catch (Exception $e) { - processException($e); - - $this->eventDispatcher->notifyEvent( - 'exception', - new Event($e) - ); - } - - return ''; } /** @@ -305,10 +231,7 @@ final class ConfigGeneralController extends SimpleControllerBase $this->checks(); $this->checkAccess(ActionsInterface::CONFIG_GENERAL); } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent( - 'exception', - new Event($e) - ); + $this->eventDispatcher->notifyEvent('exception', new Event($e)); $this->returnJsonResponseException($e); }