diff --git a/lib/BigBlueButton/API.php b/lib/BigBlueButton/API.php new file mode 100644 index 0000000..2796141 --- /dev/null +++ b/lib/BigBlueButton/API.php @@ -0,0 +1,115 @@ +config = $config; + $this->urlGenerator = $urlGenerator; + } + + private function getServer() + { + if (!$this->server) { + $apiUrl = $this->config->getAppValue('bbb', 'api.url'); + $secret = $this->config->getAppValue('bbb', 'api.secret'); + + $this->server = new BigBlueButton($apiUrl, $secret); + } + + return $this->server; + } + + /** + * Create join url. + * + * @return string join url + */ + public function createJoinUrl(Room $room, int $creationTime, string $displayname, string $uid = null) + { + $password = $uid === $room->userId ? $room->moderatorPassword : $room->attendeePassword; + + $joinMeetingParams = new JoinMeetingParameters($room->uid, $displayname, $password); + + $joinMeetingParams->setCreationTime($creationTime); + $joinMeetingParams->setJoinViaHtml5(true); + $joinMeetingParams->setRedirect(true); + + if ($uid) { + $joinMeetingParams->setUserId($uid); + // $joinMeetingParams->setAvatarURL(); + } + + return $this->getServer()->getJoinMeetingURL($joinMeetingParams); + } + + /** + * Create meeting room. + * + * @return int creation time + */ + public function createMeeting(Room $room, Presentation $presentation = null) + { + $bbb = $this->getServer(); + + try { + $response = $bbb->createMeeting($this->buildMeetingParams($room, $presentation)); + } catch (\Exception $e) { + throw $e; + throw new \Exception('Can not process create request'); + } + + if (!$response->success()) { + throw new \Exception('Can not create meeting'); + } + + return $response->getCreationTime(); + } + + private function buildMeetingParams(Room $room, Presentation $presentation = null) + { + $createMeetingParams = new CreateMeetingParameters($room->uid, $room->name); + $createMeetingParams->setAttendeePassword($room->attendeePassword); + $createMeetingParams->setModeratorPassword($room->moderatorPassword); + $createMeetingParams->setRecord($room->record); + $createMeetingParams->setAllowStartStopRecording($room->record); + $createMeetingParams->setLogoutUrl($this->urlGenerator->getBaseUrl()); + + $invitationUrl = $this->urlGenerator->linkToRouteAbsolute('bbb.join.index', ['token' => $room->uid]); + $createMeetingParams->setModeratorOnlyMessage('To invite someone to the meeting, send them this link: ' . $invitationUrl); + + if (!empty($room->welcome)) { + $createMeetingParams->setWelcomeMessage($room->welcome); + } + + if ($room->maxParticipants > 0) { + $createMeetingParams->setMaxParticipants($room->maxParticipants); + } + + if ($presentation !== null && $presentation->isValid()) { + $createMeetingParams->addPresentation($presentation->getUrl(), null, $presentation->getFilename()); + } + + return $createMeetingParams; + } +} diff --git a/lib/BigBlueButton/Presentation.php b/lib/BigBlueButton/Presentation.php new file mode 100644 index 0000000..1b74528 --- /dev/null +++ b/lib/BigBlueButton/Presentation.php @@ -0,0 +1,31 @@ +url = $url; + $this->filename = $filename; + } + + public function getUrl() + { + return $this->url; + } + + public function getFilename() + { + return $this->filename; + } + + public function isValid() + { + return !empty($this->url) && !empty($this->filename); + } +} diff --git a/lib/Controller/JoinController.php b/lib/Controller/JoinController.php index 594b08a..e2b050d 100644 --- a/lib/Controller/JoinController.php +++ b/lib/Controller/JoinController.php @@ -1,17 +1,16 @@ service = $service; $this->userSession = $userSession; $this->config = $config; - $this->urlGenerator = $urlGenerator; + $this->api = $api; } protected function getPasswordHash(): string @@ -73,99 +72,51 @@ class JoinController extends PublicShareController * @PublicPage * @NoCSRFRequired */ - public function index($displayname, $u, $filename) + public function index($displayname, $u = '', $filename = '') { $room = $this->service->findByUid($this->getToken()); if ($room === null) { - return 'Room not found'; + throw new NotFoundException(); } - $uid = null; - $url = null; + $userId = null; + $presentation = null; if ($this->userSession->isLoggedIn()) { $user = $this->userSession->getUser(); $displayname = $user->getDisplayName(); - $uid = $user->getUID(); - $url = $u; + $userId = $user->getUID(); + + if ($userId === $room->userId) { + $presentation = new Presentation($u, $filename); + } } elseif (empty($displayname) || strlen($displayname) < 3) { - $apiUrl = $this->config->getAppValue($this->appName, 'api.url'); $response = new TemplateResponse($this->appName, 'publicdisplayname', [ 'room' => $room->name, 'wrongdisplayname' => !empty($displayname) && strlen($displayname) < 3 ], 'guest'); - $parsedApiUrl = parse_url($apiUrl); - - if ($parsedApiUrl === false) { - throw new \Exception('No valid api url provided'); - } - - $response->getContentSecurityPolicy()->addAllowedFormActionDomain(($parsedApiUrl['scheme'] ?: 'https') . '://' . $parsedApiUrl['host']); + $this->addFormActionDomain($response); return $response; } - return $this->processPublicJoin($room, $displayname, $uid, $url, $filename); - } - - private function processPublicJoin($room, $displayname, $uid, $presentation, $filename) - { - $apiUrl = $this->config->getAppValue($this->appName, 'api.url'); - $secret = $this->config->getAppValue($this->appName, 'api.secret'); - - $bbb = new BigBlueButton($apiUrl, $secret); - - $createMeetingParams = new CreateMeetingParameters($room->uid, $room->name); - $createMeetingParams->setAttendeePassword($room->attendeePassword); - $createMeetingParams->setModeratorPassword($room->moderatorPassword); - $createMeetingParams->setRecord($room->record); - $createMeetingParams->setAllowStartStopRecording($room->record); - $createMeetingParams->setLogoutUrl($this->urlGenerator->getBaseUrl()); - - $invitationUrl = $this->urlGenerator->linkToRouteAbsolute('bbb.join.index', ['token' => $this->getToken()]); - $createMeetingParams->setModeratorOnlyMessage('To invite someone to the meeting, send them this link: ' . $invitationUrl); - - if (!empty($room->welcome)) { - $createMeetingParams->setWelcomeMessage($room->welcome); - } - - if ($room->maxParticipants > 0) { - $createMeetingParams->setMaxParticipants($room->maxParticipants); - } - - if ($presentation) { - $createMeetingParams->addPresentation($presentation, null, $filename); - } - - try { - $response = $bbb->createMeeting($createMeetingParams); - } catch (\Exception $e) { - throw $e; - throw new \Exception('Can not process create request'); - } - - if (!$response->success()) { - throw new \Exception('Can not create meeting'); - } - - $password = $uid === $room->userId ? $room->moderatorPassword : $room->attendeePassword; - - - $joinMeetingParams = new JoinMeetingParameters($room->uid, $displayname, $password); - - $joinMeetingParams->setCreationTime($response->getCreationTime()); - $joinMeetingParams->setJoinViaHtml5(true); - - if ($uid) { - $joinMeetingParams->setUserId($uid); - // $joinMeetingParams->setAvatarURL(); - } - - $joinMeetingParams->setRedirect(true); - $joinUrl = $bbb->getJoinMeetingURL($joinMeetingParams); + $creationDate = $this->api->createMeeting($room, $presentation); + $joinUrl = $this->api->createJoinUrl($room, $creationDate, $displayname, $userId); return new RedirectResponse($joinUrl); } + + private function addFormActionDomain($response) + { + $apiUrl = $this->config->getAppValue($this->appName, 'api.url'); + $parsedApiUrl = parse_url($apiUrl); + + if ($parsedApiUrl === false) { + throw new \Exception('No valid api url provided'); + } + + $response->getContentSecurityPolicy()->addAllowedFormActionDomain(($parsedApiUrl['scheme'] ?: 'https') . '://' . $parsedApiUrl['host']); + } }