From a1ffa4c4e33fe8b4b71f9796a2bdcc9193ab3d6e Mon Sep 17 00:00:00 2001 From: sualko Date: Sun, 17 May 2020 13:39:01 +0200 Subject: [PATCH] feat: add api check - show result - show if url or secret is invalid - add trailing slash to url --- appinfo/routes.php | 2 + lib/BigBlueButton/API.php | 31 ++++++++++++++ lib/Controller/ServerController.php | 24 +++++++++++ templates/admin.php | 8 +++- ts/Manager/Api.ts | 9 ++++ ts/Manager/App.scss | 31 +++++++++++++- ts/Manager/Nextcloud.d.ts | 6 +++ ts/admin.ts | 64 ++++++++++++++++++++++++++++- 8 files changed, 170 insertions(+), 5 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 6cd6bf5..a9fb817 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -6,6 +6,8 @@ return [ ], 'routes' => [ ['name' => 'server#records', 'url' => '/server/{roomUid}/records', 'verb' => 'GET'], + ['name' => 'server#check', 'url' => '/server/check', 'verb' => 'POST'], + ['name' => 'server#version', 'url' => '/server/version', 'verb' => 'GET'], ['name' => 'server#delete_record', 'url' => '/server/record/{recordId}', 'verb' => 'DELETE'], ['name' => 'join#index', 'url' => '/b/{token}', 'verb' => 'GET'], ['name' => 'room_api#preflighted_cors', 'url' => '/api/0.1/{path}', diff --git a/lib/BigBlueButton/API.php b/lib/BigBlueButton/API.php index d9c26f6..f56acf7 100644 --- a/lib/BigBlueButton/API.php +++ b/lib/BigBlueButton/API.php @@ -8,6 +8,7 @@ use BigBlueButton\Parameters\JoinMeetingParameters; use BigBlueButton\Parameters\GetRecordingsParameters; use BigBlueButton\Core\Record; use BigBlueButton\Parameters\DeleteRecordingsParameters; +use BigBlueButton\Parameters\IsMeetingRunningParameters; use OCA\BigBlueButton\Db\Room; use OCP\IConfig; use OCP\IURLGenerator; @@ -180,4 +181,34 @@ class API 'metas' => $record->getMetas(), ]; } + + public function check($url, $secret) + { + $server = new BigBlueButton($url, $secret); + + $meetingParams = new IsMeetingRunningParameters('foobar'); + + try { + $response = $server->isMeetingRunning($meetingParams); + + if (!$response->success() && !$response->failed()) { + return 'invalid-url'; + } + + if (!$response->success()) { + return 'invalid-secret'; + } + + return 'success'; + } catch (\Exception $e) { + return 'invalid-url'; + } + } + + public function getVersion($url = null) + { + $server = $url === null ? $this->getServer() : new BigBlueButton($url, ''); + + return $server->getApiVersion()->getVersion(); + } } diff --git a/lib/Controller/ServerController.php b/lib/Controller/ServerController.php index b2955b2..72f4d80 100644 --- a/lib/Controller/ServerController.php +++ b/lib/Controller/ServerController.php @@ -76,4 +76,28 @@ class ServerController extends Controller return new DataResponse($success); } + + public function check(string $url, string $secret) + { + if ($url === null || empty($url) || $secret === null || empty($secret)) { + return new DataResponse(false); + } + + return new DataResponse($this->server->check($url, $secret)); + } + + public function version(string $url) + { + if ($url === null || empty($url)) { + return new DataResponse(false, Http::STATUS_NOT_FOUND); + } + + try { + $version = $this->server->getVersion($url); + } catch (\Exception $e) { + return new DataResponse(false, Http::STATUS_NOT_FOUND); + } + + return new DataResponse($version); + } } diff --git a/templates/admin.php b/templates/admin.php index 42491f7..9c08144 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -8,9 +8,13 @@ script('bbb', 'admin');

BigBlueButton

+

t('Get your API url and secret by executing "sudo bbb-conf --secret" on your BigBlueButton server.')); ?>

+
- - + + + +
\ No newline at end of file diff --git a/ts/Manager/Api.ts b/ts/Manager/Api.ts index 6c9b788..10d89aa 100644 --- a/ts/Manager/Api.ts +++ b/ts/Manager/Api.ts @@ -75,6 +75,15 @@ class Api { return response.data; } + + public async checkServer(url: string, secret: string): Promise<'success'|'invalid-url'|'invalid:secret'> { + const response = await axios.post(this.getUrl('server/check'), { + url, + secret, + }); + + return response.data; + } } export const api = new Api(); diff --git a/ts/Manager/App.scss b/ts/Manager/App.scss index 9dc14b1..3c6a7e6 100644 --- a/ts/Manager/App.scss +++ b/ts/Manager/App.scss @@ -1,5 +1,4 @@ #bbb-warning { - margin: 3em; padding: 1em; background-color: rgb(255, 255, 123); display: inline-block; @@ -9,7 +8,37 @@ } } +#bbb-success { + padding: 1em; + background-color: rgb(176, 252, 132); + display: inline-block; + + .icon { + display: inline-block; + } +} + +#bbb-settings { + #bbb-warning, + #bbb-success { + margin: 1em 0; + } + + [type="url"], + [type="password"] { + width: 250px; + } + + p { + margin-bottom: 1em; + } +} + #bbb-react-root { + #bbb-warning, + #bbb-success { + margin: 3em; + } .icon { display: inline-block; diff --git a/ts/Manager/Nextcloud.d.ts b/ts/Manager/Nextcloud.d.ts index c63bf4a..550f526 100644 --- a/ts/Manager/Nextcloud.d.ts +++ b/ts/Manager/Nextcloud.d.ts @@ -46,6 +46,12 @@ declare namespace OC { } } + namespace PasswordConfirmation { + function requiresPasswordConfirmation(): boolean; + + function requirePasswordConfirmation(cb: () => void): void; + } + function generateUrl(url: string, parameters?: { [key: string]: string }, options?: EscapeOptions) function linkToOCS(service: string, version: number): string; diff --git a/ts/admin.ts b/ts/admin.ts index ec847b5..c91b661 100644 --- a/ts/admin.ts +++ b/ts/admin.ts @@ -1,10 +1,70 @@ +import {api} from './Manager/Api'; +import './Manager/App.scss'; + declare const OCP: any; $(() => { + function generateWarningElement(message: string) { + return $(`
${message}
`); + } + + function generateSuccessElement(message: string) { + return $(`
${message}
`); + } + + async function checkServer(url: string, secret: string) { + const result = await api.checkServer(url, secret); + + if (result === 'success') { + return; + } + + throw result; + } + + function checkPasswordConfirmation() { + return new Promise(resolve => { + if (OC.PasswordConfirmation && OC.PasswordConfirmation.requiresPasswordConfirmation()) { + OC.PasswordConfirmation.requirePasswordConfirmation(() => resolve()); + + return; + } + + resolve(); + }); + } + + async function saveSettings(url: string, secret: string) { + url += url.endsWith('/') ? '' : '/'; + + await checkServer(url, secret); + await checkPasswordConfirmation(); + + OCP.AppConfig.setValue('bbb', 'api.url', url); + OCP.AppConfig.setValue('bbb', 'api.secret', secret); + } + $('#bbb-settings form').submit(function (ev) { ev.preventDefault(); - OCP.AppConfig.setValue('bbb', 'api.url', this['api.url'].value); - OCP.AppConfig.setValue('bbb', 'api.secret', this['api.secret'].value); + $('#bbb-result').empty(); + + saveSettings(this['api.url'].value, this['api.secret'].value).then(() => { + const successElement = generateSuccessElement(t('bbb', 'Settings saved')); + + $('#bbb-result').append(successElement); + }).catch(err => { + let message = t('bbb', 'Unexpected error occurred'); + + if (err === 'invalid-url') { + message = t('bbb', 'API url is invalid'); + } else if (err === 'invalid-secret') { + message = t('bbb', 'API secret is invalid'); + } + + const warningElement = generateWarningElement(message); + + $('#bbb-result').append(warningElement); + }); }); }); \ No newline at end of file