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

Whiteboard exapp #226

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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: 3 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

use OCA\Whiteboard\Controller\ExAppController;
use OCA\Whiteboard\Controller\JWTController;
use OCA\Whiteboard\Controller\SettingsController;
use OCA\Whiteboard\Controller\WhiteboardController;
Expand All @@ -21,5 +22,7 @@
['name' => 'Whiteboard#show', 'url' => '{fileId}', 'verb' => 'GET'],
/** @see SettingsController::update() */
['name' => 'Settings#update', 'url' => 'settings', 'verb' => 'POST'],
/** @see ExAppController::updateSettings() */
['name' => 'ExApp#updateSettings', 'url' => 'ex_app/settings', 'verb' => 'POST'],
]
];
27 changes: 27 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@

namespace OCA\Whiteboard\AppInfo;

use OCA\AppAPI\Middleware\AppAPIAuthMiddleware;
use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent;
use OCA\Viewer\Event\LoadViewer;
use OCA\Whiteboard\Listener\AddContentSecurityPolicyListener;
use OCA\Whiteboard\Listener\BeforeTemplateRenderedListener;
use OCA\Whiteboard\Listener\LoadViewerListener;
use OCA\Whiteboard\Listener\RegisterTemplateCreatorListener;
use OCA\Whiteboard\Service\ExAppService;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
Expand All @@ -25,6 +27,9 @@
use OCP\IL10N;
use OCP\Security\CSP\AddContentSecurityPolicyEvent;
use OCP\Util;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Throwable;

/**
* @psalm-suppress UndefinedClass
Expand All @@ -37,15 +42,27 @@ public function __construct(array $params = []) {
parent::__construct(self::APP_ID, $params);
}

/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function register(IRegistrationContext $context): void {
include_once __DIR__ . '/../../vendor/autoload.php';

$context->registerEventListener(AddContentSecurityPolicyEvent::class, AddContentSecurityPolicyListener::class);
$context->registerEventListener(LoadViewer::class, LoadViewerListener::class);
$context->registerEventListener(RegisterTemplateCreatorEvent::class, RegisterTemplateCreatorListener::class);
$context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);

if (class_exists(AppAPIAuthMiddleware::class) && $this->getExAppService()->isWhiteboardWebsocketEnabled()) {
$context->registerMiddleware(AppAPIAuthMiddleware::class);
}
}

/**
* @throws ContainerExceptionInterface
* @throws Throwable
*/
public function boot(IBootContext $context): void {
[$major] = Util::getVersion();
if ($major < 30) {
Expand All @@ -55,5 +72,15 @@ public function boot(IBootContext $context): void {
});
});
}

$this->getExAppService()->initFrontendState();
}

/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function getExAppService(): ExAppService {
return $this->getContainer()->get(ExAppService::class);
}
}
16 changes: 16 additions & 0 deletions lib/Consts/ExAppConsts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

declare(strict_types=1);

namespace OCA\Whiteboard\Consts;

final class ExAppConsts {
public const APP_API_ID = 'app_api';
public const WHITEBOARD_EX_APP_ID = 'whiteboard_websocket';
public const WHITEBOARD_EX_APP_ENABLED_KEY = 'isWhiteboardWebsocketEnabled';
}
59 changes: 59 additions & 0 deletions lib/Controller/ExAppController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Whiteboard\Controller;

use Exception;
use OCA\AppAPI\Attribute\AppAPIAuth;
use OCA\Whiteboard\Service\ConfigService;
use OCA\Whiteboard\Service\ExceptionService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest;

/**
* @psalm-suppress UndefinedClass
* @psalm-suppress MissingDependency
* @psalm-suppress UndefinedAttributeClass
*/
final class ExAppController extends Controller {
public function __construct(
IRequest $request,
private ExceptionService $exceptionService,
private ConfigService $configService,
) {
parent::__construct('whiteboard', $request);
}

#[NoCSRFRequired]
#[PublicPage]
#[AppAPIAuth]
public function updateSettings(): DataResponse {
try {
$serverUrl = $this->request->getParam('serverUrl');
$secret = $this->request->getParam('secret');

if ($serverUrl !== null) {
$this->configService->setCollabBackendUrl($serverUrl);
}

if ($secret !== null) {
$this->configService->setWhiteboardSharedSecret($secret);
}

return new DataResponse([
'message' => 'Settings updated',
]);
} catch (Exception $e) {
return $this->exceptionService->handleException($e);
}
}
}
8 changes: 4 additions & 4 deletions lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
*/
final class SettingsController extends Controller {
public function __construct(
IRequest $request,
IRequest $request,
private ExceptionService $exceptionService,
private JWTService $jwtService,
private ConfigService $configService,
private JWTService $jwtService,
private ConfigService $configService,
) {
parent::__construct('whiteboard', $request);
}
Expand All @@ -45,7 +45,7 @@ public function update(): DataResponse {
}

return new DataResponse([
'jwt' => $this->jwtService->generateJWTFromPayload([ 'serverUrl' => $serverUrl ])
'jwt' => $this->jwtService->generateJWTFromPayload(['serverUrl' => $serverUrl])
]);
} catch (Exception $e) {
return $this->exceptionService->handleException($e);
Expand Down
70 changes: 70 additions & 0 deletions lib/Service/ExAppService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Whiteboard\Service;

use OCA\AppAPI\Service\ExAppService as AppAPIService;
use OCA\Whiteboard\Consts\ExAppConsts;
use OCP\App\IAppManager;
use OCP\AppFramework\Services\IInitialState;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Throwable;

/**
* @psalm-suppress UndefinedClass
* @psalm-suppress MissingDependency
*/
final class ExAppService {
private ?AppAPIService $appAPIService = null;

public function __construct(
private IAppManager $appManager,
private ContainerInterface $container,
private IInitialState $initialState,
private LoggerInterface $logger,
) {
$this->initAppAPIService();
}

private function initAppAPIService(): void {
$isAppAPIEnabled = $this->isAppAPIEnabled();

if (class_exists(AppAPIService::class) && $isAppAPIEnabled) {
try {
$this->appAPIService = $this->container->get(AppAPIService::class);
} catch (Throwable $e) {
$this->logger->error('exApp', [$e->getMessage()]);
}
}
}

private function isAppAPIEnabled(): bool {
return $this->appManager->isEnabledForUser(ExAppConsts::APP_API_ID);
}

public function isExAppEnabled(string $appId): bool {
if ($this->appAPIService === null) {
return false;
}

return $this->appAPIService->getExApp($appId)?->getEnabled() === 1;
}

public function isWhiteboardWebsocketEnabled(): bool {
return $this->isExAppEnabled(ExAppConsts::WHITEBOARD_EX_APP_ID);
}

public function initFrontendState(): void {
$this->initialState->provideInitialState(
ExAppConsts::WHITEBOARD_EX_APP_ENABLED_KEY,
$this->isWhiteboardWebsocketEnabled()
);
}
}
10 changes: 8 additions & 2 deletions lib/Settings/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace OCA\Whiteboard\Settings;

use OCA\Whiteboard\Service\ConfigService;
use OCA\Whiteboard\Service\ExAppService;
use OCA\Whiteboard\Service\JWTService;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\TemplateResponse;
Expand All @@ -18,6 +19,7 @@ public function __construct(
private IInitialState $initialState,
private ConfigService $configService,
private JWTService $jwtService,
private ExAppService $exAppService,
) {
}

Expand All @@ -37,11 +39,15 @@ public function getForm(): TemplateResponse {
return $response;
}

public function getSection() {
public function getSection(): ?string {
if ($this->exAppService->isWhiteboardWebsocketEnabled()) {
return null;
}

return 'whiteboard';
}

public function getPriority() {
public function getPriority(): int {
return 0;
}
}
3 changes: 3 additions & 0 deletions lib/Settings/Section.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?php

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Whiteboard\Settings;

use OCA\Whiteboard\Service\ExAppService;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\Settings\IIconSection;
Expand All @@ -14,6 +16,7 @@ class Section implements IIconSection {
public function __construct(
private IURLGenerator $url,
private IL10N $l10n,
private ExAppService $exAppService,
) {
}

Expand Down
Loading
Loading