%PDF- %PDF-
| Direktori : /www/varak.net/nextcloud.varak.net/apps/app_api/lib/Controller/ |
| Current File : //www/varak.net/nextcloud.varak.net/apps/app_api/lib/Controller/DaemonConfigController.php |
<?php
declare(strict_types=1);
namespace OCA\AppAPI\Controller;
use OCA\AppAPI\AppInfo\Application;
use OCA\AppAPI\Db\DaemonConfig;
use OCA\AppAPI\DeployActions\DockerActions;
use OCA\AppAPI\Service\AppAPIService;
use OCA\AppAPI\Service\DaemonConfigService;
use OCA\AppAPI\Service\ExAppService;
use OCP\AppFramework\ApiController;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\Response;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IRequest;
use OCP\Security\ICrypto;
/**
* DaemonConfig actions (for UI)
*/
class DaemonConfigController extends ApiController {
public function __construct(
IRequest $request,
private readonly IConfig $config,
private readonly DaemonConfigService $daemonConfigService,
private readonly DockerActions $dockerActions,
private readonly AppAPIService $service,
private readonly ExAppService $exAppService,
private readonly IL10N $l10n,
private readonly ICrypto $crypto,
) {
parent::__construct(Application::APP_ID, $request);
}
public function getAllDaemonConfigs(): Response {
return new JSONResponse([
'daemons' => $this->daemonConfigService->getDaemonConfigsWithAppsCount(),
'default_daemon_config' => $this->config->getAppValue(Application::APP_ID, 'default_daemon_config'),
]);
}
#[PasswordConfirmationRequired]
public function registerDaemonConfig(array $daemonConfigParams, bool $defaultDaemon = false): Response {
$daemonConfig = $this->daemonConfigService->registerDaemonConfig($daemonConfigParams);
if ($daemonConfig !== null && $defaultDaemon) {
$this->config->setAppValue(Application::APP_ID, 'default_daemon_config', $daemonConfig->getName());
}
return new JSONResponse([
'success' => $daemonConfig !== null,
'daemonConfig' => $daemonConfig,
]);
}
#[PasswordConfirmationRequired]
public function updateDaemonConfig(string $name, array $daemonConfigParams): Response {
$daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name);
// Safely check if "haproxy_password" exists before accessing it
$haproxyPassword = $daemonConfigParams['deploy_config']['haproxy_password'] ?? null;
// Restore the original password if "dummySecret123" is provided
if ($haproxyPassword === 'dummySecret123') {
$daemonConfigParams['deploy_config']['haproxy_password'] = $daemonConfig->getDeployConfig()['haproxy_password'] ?? "";
} elseif (!empty($haproxyPassword)) {
// New password provided, encrypt it
$daemonConfigParams['deploy_config']['haproxy_password'] = $this->crypto->encrypt($haproxyPassword);
}
// Create and update DaemonConfig instance
$updatedDaemonConfig = new DaemonConfig($daemonConfigParams);
$updatedDaemonConfig->setId($daemonConfig->getId());
$updatedDaemonConfig = $this->daemonConfigService->updateDaemonConfig($updatedDaemonConfig);
// Check if update was successful before proceeding
if ($updatedDaemonConfig === null) {
return new JSONResponse([
'success' => false,
'daemonConfig' => null,
]);
}
// Mask the password with "dummySecret123" if it is set
$updatedDeployConfig = $updatedDaemonConfig->getDeployConfig();
if (!empty($updatedDeployConfig['haproxy_password'] ?? null)) {
$updatedDeployConfig['haproxy_password'] = 'dummySecret123';
$updatedDaemonConfig->setDeployConfig($updatedDeployConfig);
}
return new JSONResponse([
'success' => true,
'daemonConfig' => $updatedDaemonConfig,
]);
}
#[PasswordConfirmationRequired]
public function unregisterDaemonConfig(string $name): Response {
$daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name);
$defaultDaemonConfig = $this->config->getAppValue(Application::APP_ID, 'default_daemon_config', '');
$this->service->removeExAppsByDaemonConfigName($daemonConfig);
if ($daemonConfig->getName() === $defaultDaemonConfig) {
$this->config->deleteAppValue(Application::APP_ID, 'default_daemon_config');
}
$daemonConfig = $this->daemonConfigService->unregisterDaemonConfig($daemonConfig);
return new JSONResponse([
'success' => $daemonConfig !== null,
'daemonConfig' => $daemonConfig,
]);
}
public function verifyDaemonConnection(string $name): Response {
$daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name);
if ($daemonConfig->getAcceptsDeployId() !== $this->dockerActions->getAcceptsDeployId()) {
return new JSONResponse([
'error' => sprintf('Only "%s" is supported', $this->dockerActions->getAcceptsDeployId()),
]);
}
$this->dockerActions->initGuzzleClient($daemonConfig);
$dockerDaemonAccessible = $this->dockerActions->ping($this->dockerActions->buildDockerUrl($daemonConfig));
return new JSONResponse([
'success' => $dockerDaemonAccessible,
]);
}
public function checkDaemonConnection(array $daemonParams): Response {
// Safely check if "haproxy_password" exists before accessing it
// note: UI passes here 'deploy_config' instead of 'deployConfig'
$haproxyPassword = $daemonParams['deploy_config']['haproxy_password'] ?? null;
if ($haproxyPassword === 'dummySecret123') {
// For cases when the password itself is 'dummySecret123'
$daemonParams['deploy_config']['haproxy_password'] = $this->crypto->encrypt($haproxyPassword);
// Check if such record is present in the DB
$daemonConfig = $this->daemonConfigService->getDaemonConfigByName($daemonParams['name']);
if ($daemonConfig !== null) {
// such Daemon config already present in the DB
$haproxyPasswordDB = $daemonConfig->getDeployConfig()['haproxy_password'] ?? "";
if ($haproxyPasswordDB) {
// get password from the DB instead of the “masked” one
$daemonParams['deploy_config']['haproxy_password'] = $haproxyPasswordDB;
}
}
} elseif (!empty($haproxyPassword)) {
// New password provided, encrypt it, as "initGuzzleClient" expects to receive encrypted password
$daemonParams['deploy_config']['haproxy_password'] = $this->crypto->encrypt($haproxyPassword);
}
$daemonConfig = new DaemonConfig([
'name' => $daemonParams['name'],
'display_name' => $daemonParams['display_name'],
'accepts_deploy_id' => $daemonParams['accepts_deploy_id'],
'protocol' => $daemonParams['protocol'],
'host' => $daemonParams['host'],
'deploy_config' => $daemonParams['deploy_config'],
]);
if ($daemonConfig->getAcceptsDeployId() !== $this->dockerActions->getAcceptsDeployId()) {
return new JSONResponse([
'error' => sprintf('Only "%s" is supported', $this->dockerActions->getAcceptsDeployId()),
]);
}
$this->dockerActions->initGuzzleClient($daemonConfig);
$dockerDaemonAccessible = $this->dockerActions->ping($this->dockerActions->buildDockerUrl($daemonConfig));
return new JSONResponse([
'success' => $dockerDaemonAccessible,
]);
}
public function startTestDeploy(string $name): Response {
$daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name);
if (!$daemonConfig) {
return new JSONResponse(['error' => $this->l10n->t('Daemon config not found')], Http::STATUS_NOT_FOUND);
}
if (!$this->service->runOccCommand(
sprintf("app_api:app:register --silent %s %s --info-xml %s --test-deploy-mode",
Application::TEST_DEPLOY_APPID, $daemonConfig->getName(), Application::TEST_DEPLOY_INFO_XML)
)) {
return new JSONResponse(['error' => $this->l10n->t('Error starting install of ExApp')], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$elapsedTime = 0;
while ($elapsedTime < 5000000 && !$this->exAppService->getExApp(Application::TEST_DEPLOY_APPID)) {
usleep(150000); // 0.15
$elapsedTime += 150000;
}
$exApp = $this->exAppService->getExApp(Application::TEST_DEPLOY_APPID);
if ($exApp === null) {
return new JSONResponse(['error' => $this->l10n->t('ExApp failed to register, check the NC logs')], Http::STATUS_INTERNAL_SERVER_ERROR);
}
return new JSONResponse([
'status' => $exApp->getStatus(),
]);
}
public function stopTestDeploy(string $name): Response {
$exApp = $this->exAppService->getExApp(Application::TEST_DEPLOY_APPID);
if ($exApp !== null) {
$this->service->runOccCommand(sprintf("app_api:app:unregister --silent --force %s", Application::TEST_DEPLOY_APPID));
$elapsedTime = 0;
while ($elapsedTime < 5000000 && $this->exAppService->getExApp(Application::TEST_DEPLOY_APPID) !== null) {
usleep(150000); // 0.15
$elapsedTime += 150000;
}
}
$exApp = $this->exAppService->getExApp(Application::TEST_DEPLOY_APPID);
return new JSONResponse([
'success' => $exApp === null,
]);
}
public function getTestDeployStatus(string $name): Response {
$exApp = $this->exAppService->getExApp(Application::TEST_DEPLOY_APPID);
if (is_null($exApp) || $exApp->getDaemonConfigName() !== $name) {
return new JSONResponse(['error' => $this->l10n->t('ExApp not found, failed to get status')], Http::STATUS_NOT_FOUND);
}
return new JSONResponse($exApp->getStatus());
}
}