You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

257 lines
7.6 KiB

<?php
/**
* @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
*
* @author Lukas Reschke <lukas@statuscode.ch>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Spreed\Controller;
use OC\HintException;
use OCA\Spreed\Exceptions\ParticipantNotFoundException;
use OCA\Spreed\Exceptions\RoomNotFoundException;
use OCA\Spreed\Config;
use OCA\Spreed\Manager;
use OCA\Spreed\Participant;
use OCA\Spreed\Room;
use OCA\Spreed\TalkSession;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\ILogger;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\Notification\IManager;
class PageController extends Controller {
/** @var string */
private $userId;
/** @var RoomController */
private $api;
/** @var TalkSession */
private $session;
/** @var ILogger */
private $logger;
/** @var Manager */
private $manager;
/** @var IURLGenerator */
private $url;
/** @var IManager */
private $notificationManager;
/** @var Config */
private $config;
/**
* @param string $appName
* @param IRequest $request
* @param RoomController $api
* @param TalkSession $session
* @param string $UserId
* @param ILogger $logger
* @param Manager $manager
* @param IURLGenerator $url
* @param IManager $notificationManager
* @param Config $config
*/
public function __construct($appName,
IRequest $request,
RoomController $api,
TalkSession $session,
$UserId,
ILogger $logger,
Manager $manager,
IURLGenerator $url,
IManager $notificationManager,
Config $config) {
parent::__construct($appName, $request);
$this->api = $api;
$this->session = $session;
$this->userId = $UserId;
$this->logger = $logger;
$this->manager = $manager;
$this->url = $url;
$this->notificationManager = $notificationManager;
$this->config = $config;
}
/**
* @PublicPage
* @NoCSRFRequired
* @UseSession
*
* @param string $token
* @param string $callUser
* @param string $password
* @return TemplateResponse|RedirectResponse
* @throws HintException
*/
public function index($token = '', $callUser = '', $password = '') {
if ($this->userId === null) {
return $this->guestEnterRoom($token, $password);
}
if ($token !== '') {
$room = null;
try {
$room = $this->manager->getRoomByToken($token);
if ($this->userId !== null) {
$notification = $this->notificationManager->createNotification();
try {
$notification->setApp('spreed')
->setUser($this->userId)
->setObject('room', $room->getId());
$this->notificationManager->markProcessed($notification);
$notification->setObject('call', $room->getId());
$this->notificationManager->markProcessed($notification);
} catch (\InvalidArgumentException $e) {
$this->logger->logException($e, ['app' => 'spreed']);
}
}
// If the room is not a public room, check if the user is in the participants
if ($room->getType() !== Room::PUBLIC_CALL) {
$this->manager->getRoomForParticipant($room->getId(), $this->userId);
}
} catch (RoomNotFoundException $e) {
// Room not found, redirect to main page
$token = '';
}
$this->session->removePasswordForRoom($token);
if ($room instanceof Room && $room->hasPassword()) {
// If the user joined themselves or is not found, they need the password.
try {
$participant = $room->getParticipant($this->userId);
$requirePassword = $participant->getParticipantType() === Participant::USER_SELF_JOINED;
} catch (ParticipantNotFoundException $e) {
$requirePassword = true;
}
if ($requirePassword) {
$passwordVerification = $room->verifyPassword($password);
if ($passwordVerification['result']) {
$this->session->setPasswordForRoom($token, $token);
} else {
if ($passwordVerification['url'] === '') {
return new TemplateResponse($this->appName, 'authenticate', [], 'guest');
}
else {
return new RedirectResponse($passwordVerification['url']);
}
}
}
}
} else {
$response = $this->api->createRoom(Room::ONE_TO_ONE_CALL, $callUser);
if ($response->getStatus() !== Http::STATUS_NOT_FOUND) {
$data = $response->getData();
return $this->showCall($data['token']);
}
}
$params = [
'token' => $token,
'signaling-settings' => $this->config->getSettings($this->userId),
];
$response = new TemplateResponse($this->appName, 'index', $params);
$csp = new ContentSecurityPolicy();
$csp->addAllowedConnectDomain('*');
$csp->addAllowedMediaDomain('blob:');
$response->setContentSecurityPolicy($csp);
return $response;
}
/**
* @param string $token
* @param string $password
* @return TemplateResponse|RedirectResponse
* @throws HintException
*/
protected function guestEnterRoom($token, $password) {
try {
$room = $this->manager->getRoomByToken($token);
if ($room->getType() !== Room::PUBLIC_CALL) {
throw new RoomNotFoundException();
}
} catch (RoomNotFoundException $e) {
return new RedirectResponse($this->url->linkToRoute('core.login.showLoginForm', [
'redirect_url' => $this->url->linkToRoute('spreed.Page.index', ['token' => $token]),
]));
}
$this->session->removePasswordForRoom($token);
if ($room->hasPassword()) {
$passwordVerification = [
'result' => false,
'url' => ''
];
$passwordVerification = $room->verifyPassword($password);
if ($passwordVerification['result']) {
$this->session->setPasswordForRoom($token, $token);
} else {
if ($passwordVerification['url'] == '') {
return new TemplateResponse($this->appName, 'authenticate', [], 'guest');
}
else {
return new RedirectResponse($passwordVerification['url']);
}
}
}
$params = [
'token' => $token,
'signaling-settings' => $this->config->getSettings($this->userId),
];
$response = new TemplateResponse($this->appName, 'index-public', $params, 'base');
$csp = new ContentSecurityPolicy();
$csp->addAllowedConnectDomain('*');
$csp->addAllowedMediaDomain('blob:');
$response->setContentSecurityPolicy($csp);
return $response;
}
/**
* @param string $token
* @return RedirectResponse
*/
protected function showCall($token) {
// These redirects are already done outside of this method
if ($this->userId === null) {
try {
$room = $this->manager->getRoomByToken($token);
if ($room->getType() !== Room::PUBLIC_CALL) {
throw new RoomNotFoundException();
}
return new RedirectResponse($this->url->linkToRoute('spreed.Page.index', ['token' => $token]));
} catch (RoomNotFoundException $e) {
return new RedirectResponse($this->url->linkToRoute('core.login.showLoginForm', [
'redirect_url' => $this->url->linkToRoute('spreed.Page.index', ['token' => $token]),
]));
}
}
return new RedirectResponse($this->url->linkToRoute('spreed.Page.index', ['token' => $token]));
}
}