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.
 
 
 
 
 

945 lines
27 KiB

<?php
/**
* @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
*
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Joas Schilling <coding@schilljs.com>
*
* @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 OCA\Spreed\Chat\ChatManager;
use OCA\Spreed\Exceptions\InvalidPasswordException;
use OCA\Spreed\Exceptions\ParticipantNotFoundException;
use OCA\Spreed\Exceptions\RoomNotFoundException;
use OCA\Spreed\GuestManager;
use OCA\Spreed\Manager;
use OCA\Spreed\Participant;
use OCA\Spreed\Room;
use OCA\Spreed\TalkSession;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IL10N;
use OCP\ILogger;
use OCP\IRequest;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IGroup;
use OCP\IGroupManager;
class RoomController extends OCSController {
/** @var string */
private $userId;
/** @var TalkSession */
private $session;
/** @var IUserManager */
private $userManager;
/** @var IGroupManager */
private $groupManager;
/** @var ILogger */
private $logger;
/** @var Manager */
private $manager;
/** @var GuestManager */
private $guestManager;
/** @var ChatManager */
private $chatManager;
/** @var IL10N */
private $l10n;
/**
* @param string $appName
* @param string $UserId
* @param IRequest $request
* @param TalkSession $session
* @param IUserManager $userManager
* @param IGroupManager $groupManager
* @param ILogger $logger
* @param Manager $manager
* @param GuestManager $guestManager
* @param ChatManager $chatManager
* @param IL10N $l10n
*/
public function __construct($appName,
$UserId,
IRequest $request,
TalkSession $session,
IUserManager $userManager,
IGroupManager $groupManager,
ILogger $logger,
Manager $manager,
GuestManager $guestManager,
ChatManager $chatManager,
IL10N $l10n) {
parent::__construct($appName, $request);
$this->session = $session;
$this->userId = $UserId;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->logger = $logger;
$this->manager = $manager;
$this->guestManager = $guestManager;
$this->chatManager = $chatManager;
$this->l10n = $l10n;
}
/**
* Get all currently existent rooms which the user has joined
*
* @NoAdminRequired
*
* @return DataResponse
*/
public function getRooms() {
$rooms = $this->manager->getRoomsForParticipant($this->userId);
$return = [];
foreach ($rooms as $room) {
try {
$return[] = $this->formatRoom($room, $room->getParticipant($this->userId));
} catch (RoomNotFoundException $e) {
} catch (\RuntimeException $e) {
}
}
return new DataResponse($return);
}
/**
* @PublicPage
*
* @param string $token
* @return DataResponse
*/
public function getRoom($token) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$participant = null;
try {
$participant = $room->getParticipant($this->userId);
} catch (ParticipantNotFoundException $e) {
try {
$participant = $room->getParticipantBySession($this->session->getSessionForRoom($token));
} catch (ParticipantNotFoundException $e) {
}
}
return new DataResponse($this->formatRoom($room, $participant));
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
}
/**
* @param Room $room
* @param Participant $participant
* @return array
* @throws RoomNotFoundException
*/
protected function formatRoom(Room $room, Participant $participant = null) {
if ($participant instanceof Participant) {
$participantType = $participant->getParticipantType();
$participantInCall = $participant->isInCall();
} else {
$participantType = Participant::GUEST;
$participantInCall = false;
}
$roomData = [
'id' => $room->getId(),
'token' => $room->getToken(),
'type' => $room->getType(),
'name' => $room->getName(),
'displayName' => $room->getName(),
'participantType' => $participantType,
'participantInCall' => $participantInCall,
'count' => $room->getNumberOfParticipants(false, time() - 30),
'hasPassword' => $room->hasPassword(),
'hasCall' => $room->getActiveSince() instanceof \DateTimeInterface,
'unreadMessages' => 0,
];
if (!$participant instanceof Participant) {
// Unauthenticated user without a session (didn't enter password)
$roomData = array_merge($roomData, [
'lastPing' => 0,
'sessionId' => '0',
'participants' => [],
'numGuests' => 0,
'hasCall' => false,
'guestList' => '',
]);
return $roomData;
}
$currentUser = $this->userManager->get($this->userId);
if ($currentUser instanceof IUser) {
$roomData['unreadMessages'] = $this->chatManager->getUnreadCount($room->getId(), $currentUser);
}
// Sort by lastPing
/** @var array[] $participants */
$participants = $room->getParticipants();
$sortParticipants = function(array $participant1, array $participant2) {
return $participant2['lastPing'] - $participant1['lastPing'];
};
uasort($participants['users'], $sortParticipants);
uasort($participants['guests'], $sortParticipants);
$participantList = [];
foreach ($participants['users'] as $userId => $data) {
$user = $this->userManager->get($userId);
if ($user instanceof IUser) {
$participantList[(string) $user->getUID()] = [
'name' => $user->getDisplayName(),
'type' => $data['participantType'],
'call' => $data['inCall'],
];
}
}
$activeGuests = array_filter($participants['guests'], function($data) {
return $data['lastPing'] > time() - 30;
});
$numActiveGuests = count($activeGuests);
if ($numActiveGuests !== count($participants['guests'])) {
$room->cleanGuestParticipants();
}
$roomData = array_merge($roomData, [
'lastPing' => $participant->getLastPing(),
'sessionId' => $participant->getSessionId(),
'participants' => $participantList,
'numGuests' => $numActiveGuests,
]);
if ($this->userId !== null) {
unset($participantList[$this->userId]);
$numOtherParticipants = count($participantList);
$numGuestParticipants = $numActiveGuests;
} else {
$numOtherParticipants = count($participantList);
$numGuestParticipants = $numActiveGuests - 1;
}
$guestString = '';
switch ($room->getType()) {
case Room::ONE_TO_ONE_CALL:
// As name of the room use the name of the other person participating
if ($numOtherParticipants === 1) {
// Only one other participant
reset($participantList);
$roomData['name'] = key($participantList);
$roomData['displayName'] = $participantList[$roomData['name']]['name'];
} else {
// Invalid user count, there must be exactly 2 users in each one2one room
$this->logger->warning('one2one room found with invalid participant count. Leaving room for everyone', [
'app' => 'spreed',
]);
$room->deleteRoom();
}
break;
/** @noinspection PhpMissingBreakStatementInspection */
case Room::PUBLIC_CALL:
if ($this->userId === null && $numGuestParticipants) {
$guestString = $this->l10n->n('%n other guest', '%n other guests', $numGuestParticipants);
} else if ($numGuestParticipants) {
$guestString = $this->l10n->n('%n guest', '%n guests', $numGuestParticipants);
}
// no break;
case Room::GROUP_CALL:
if ($room->getName() === '') {
// As name of the room use the names of the other participants
$participantList = array_map(function($participant) {
return $participant['name'];
}, $participantList);
if ($this->userId === null) {
$participantList[] = $this->l10n->t('You');
} else if ($numOtherParticipants === 0) {
$participantList = [$this->l10n->t('You')];
}
if ($guestString !== '') {
$participantList[] = $guestString;
}
$roomData['displayName'] = implode($this->l10n->t(', '), $participantList);
}
break;
default:
// Invalid room type
$this->logger->warning('Invalid room type found. Leaving room for everyone', [
'app' => 'spreed',
]);
$room->deleteRoom();
throw new RoomNotFoundException('The room type is unknown');
}
$roomData['guestList'] = $guestString;
return $roomData;
}
/**
* Initiates a one-to-one video call from the current user to the recipient
*
* @NoAdminRequired
*
* @param int $roomType
* @param string $invite
* @param string $roomName
* @return DataResponse
*/
public function createRoom($roomType, $invite = '', $roomName = '') {
switch ((int) $roomType) {
case Room::ONE_TO_ONE_CALL:
return $this->createOneToOneRoom($invite);
case Room::GROUP_CALL:
if ($invite === '') {
return $this->createEmptyRoom($roomName, false);
}
return $this->createGroupRoom($invite);
case Room::PUBLIC_CALL:
return $this->createEmptyRoom($roomName);
}
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
/**
* Initiates a one-to-one video call from the current user to the recipient
*
* @NoAdminRequired
*
* @param string $targetUserName
* @return DataResponse
*/
protected function createOneToOneRoom($targetUserName) {
$currentUser = $this->userManager->get($this->userId);
if (!$currentUser instanceof IUser) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$targetUser = $this->userManager->get($targetUserName);
if (!$targetUser instanceof IUser) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if ($this->userId === $targetUserName) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
// If room exists: Reuse that one, otherwise create a new one.
try {
$room = $this->manager->getOne2OneRoom($this->userId, $targetUser->getUID());
return new DataResponse(['token' => $room->getToken()], Http::STATUS_OK);
} catch (RoomNotFoundException $e) {
$room = $this->manager->createOne2OneRoom();
$room->addUsers([
'userId' => $currentUser->getUID(),
'participantType' => Participant::OWNER,
], [
'userId' => $targetUser->getUID(),
'participantType' => Participant::OWNER,
]);
return new DataResponse([
'token' => $room->getToken(),
'name' => $room->getName(),
'displayName' => $targetUser->getDisplayName(),
], Http::STATUS_CREATED);
}
}
/**
* Initiates a group video call from the selected group
*
* @NoAdminRequired
*
* @param string $targetGroupName
* @return DataResponse
*/
protected function createGroupRoom($targetGroupName) {
$targetGroup = $this->groupManager->get($targetGroupName);
$currentUser = $this->userManager->get($this->userId);
if (!$targetGroup instanceof IGroup) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!$currentUser instanceof IUser) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
// Create the room
$room = $this->manager->createGroupRoom($targetGroup->getGID());
$room->addUsers([
'userId' => $currentUser->getUID(),
'participantType' => Participant::OWNER,
]);
$usersInGroup = $targetGroup->getUsers();
$participants = [];
foreach ($usersInGroup as $user) {
if ($currentUser->getUID() === $user->getUID()) {
// Owner is already added.
continue;
}
$participants[] = [
'userId' => $user->getUID(),
];
}
call_user_func_array([$room, 'addUsers'], $participants);
return new DataResponse([
'token' => $room->getToken(),
'name' => $room->getName(),
'displayName' => $room->getName(),
], Http::STATUS_CREATED);
}
/**
* @NoAdminRequired
*
* @param string $roomName
* @param bool $public
* @return DataResponse
*/
protected function createEmptyRoom($roomName, $public = true) {
$currentUser = $this->userManager->get($this->userId);
if (!$currentUser instanceof IUser) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
// Create the room
if ($public) {
$room = $this->manager->createPublicRoom($roomName);
} else {
$room = $this->manager->createGroupRoom($roomName);
}
$room->addUsers([
'userId' => $currentUser->getUID(),
'participantType' => Participant::OWNER,
]);
return new DataResponse([
'token' => $room->getToken(),
'name' => $room->getName(),
'displayName' => $room->getName(),
], Http::STATUS_CREATED);
}
/**
* @NoAdminRequired
*
* @param string $token
* @param string $roomName
* @return DataResponse
*/
public function renameRoom($token, $roomName) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$participant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!in_array($participant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
if (strlen($roomName) > 200) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
if (!$room->setName($roomName)) {
return new DataResponse([], Http::STATUS_METHOD_NOT_ALLOWED);
}
return new DataResponse([]);
}
/**
* @NoAdminRequired
*
* @param string $token
* @return DataResponse
*/
public function deleteRoom($token) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$participant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!in_array($participant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
$room->deleteRoom();
return new DataResponse([]);
}
/**
* @NoAdminRequired
*
* @param string $token
* @return DataResponse
*/
public function getParticipants($token) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$participants = $room->getParticipants();
$results = [];
foreach ($participants['users'] as $userId => $participant) {
$user = $this->userManager->get((string) $userId);
if (!$user instanceof IUser) {
continue;
}
$results[] = array_merge($participant, [
'userId' => (string) $userId,
'displayName' => (string) $user->getDisplayName(),
]);
}
$guestSessions = [];
foreach ($participants['guests'] as $participant) {
$guestSessions[] = sha1($participant['sessionId']);
}
$guestNames = $this->guestManager->getNamesBySessionHashes($guestSessions);
foreach ($participants['guests'] as $participant) {
$sessionHash = sha1($participant['sessionId']);
$results[] = array_merge($participant, [
'participantType' => Participant::GUEST,
'userId' => '',
'displayName' => isset($guestNames[$sessionHash]) ? $guestNames[$sessionHash] : '',
]);
}
return new DataResponse($results);
}
/**
* @NoAdminRequired
*
* @param string $token
* @param string $newParticipant
* @return DataResponse
*/
public function addParticipantToRoom($token, $newParticipant) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$participant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!in_array($participant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
$participants = $room->getParticipants();
if (isset($participants['users'][$newParticipant])) {
return new DataResponse([]);
}
$currentUser = $this->userManager->get($this->userId);
if (!$currentUser instanceof IUser) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$newUser = $this->userManager->get($newParticipant);
if (!$newUser instanceof IUser) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$data = [];
if ($room->getType() === Room::ONE_TO_ONE_CALL) {
// In case a user is added to a one2one call, we change the call to a group call
$room->changeType(Room::GROUP_CALL);
$data = ['type' => $room->getType()];
}
$room->addUsers([
'userId' => $newUser->getUID(),
]);
return new DataResponse($data);
}
/**
* @NoAdminRequired
*
* @param string $token
* @param string $participant
* @return DataResponse
*/
public function removeParticipantFromRoom($token, $participant) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$currentParticipant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!in_array($currentParticipant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
if ($room->getType() === Room::ONE_TO_ONE_CALL) {
$room->deleteRoom();
return new DataResponse([]);
}
try {
$targetParticipant = $room->getParticipant($participant);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if ($targetParticipant->getParticipantType() === Participant::OWNER) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
$targetUser = $this->userManager->get($participant);
if (!$targetUser instanceof IUser) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$room->removeUser($targetUser);
return new DataResponse([]);
}
/**
* @NoAdminRequired
*
* @param string $token
* @return DataResponse
*/
public function removeSelfFromRoom($token) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$room->getParticipant($this->userId); // Check if the participant is part of the room
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if ($room->getType() === Room::ONE_TO_ONE_CALL || $room->getNumberOfParticipants() === 1) {
$room->deleteRoom();
} else {
$currentUser = $this->userManager->get($this->userId);
if (!$currentUser instanceof IUser) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
$room->removeUser($currentUser);
}
return new DataResponse([]);
}
/**
* @NoAdminRequired
*
* @param string $token
* @param string $participant
* @return DataResponse
*/
public function removeGuestFromRoom($token, $participant) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$currentParticipant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!in_array($currentParticipant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
try {
$targetParticipant = $room->getParticipantBySession($participant);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if ($targetParticipant->getParticipantType() !== Participant::GUEST) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
$room->removeParticipantBySession($targetParticipant);
return new DataResponse([]);
}
/**
* @NoAdminRequired
*
* @param string $token
* @return DataResponse
*/
public function makePublic($token) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$participant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!in_array($participant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
if ($room->getType() !== Room::PUBLIC_CALL) {
$room->changeType(Room::PUBLIC_CALL);
}
return new DataResponse();
}
/**
* @NoAdminRequired
*
* @param string $token
* @return DataResponse
*/
public function makePrivate($token) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$participant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!in_array($participant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
if ($room->getType() === Room::PUBLIC_CALL) {
$room->changeType(Room::GROUP_CALL);
}
return new DataResponse();
}
/**
* @NoAdminRequired
*
* @param string $token
* @param string $password
* @return DataResponse
*/
public function setPassword($token, $password) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$participant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!in_array($participant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
if ($room->getType() !== Room::PUBLIC_CALL) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
$room->setPassword($password);
return new DataResponse();
}
/**
* @PublicPage
* @UseSession
*
* @param string $token
* @param string $password
* @return DataResponse
*/
public function joinRoom($token, $password = '') {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
try {
if ($this->userId !== null) {
$newSessionId = $room->joinRoom($this->userId, $password, $this->session->getPasswordForRoom($token) === $room->getToken());
} else {
$newSessionId = $room->joinRoomGuest($password, $this->session->getPasswordForRoom($token) === $room->getToken());
}
} catch (InvalidPasswordException $e) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
$this->session->removePasswordForRoom($token);
$this->session->setSessionForRoom($token, $newSessionId);
$room->ping($this->userId, $newSessionId, time());
return new DataResponse([
'sessionId' => $newSessionId,
]);
}
/**
* @PublicPage
* @UseSession
*
* @param string $token
* @return DataResponse
*/
public function leaveRoom($token) {
$sessionId = $this->session->getSessionForRoom($token);
$this->session->removeSessionForRoom($token);
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
if ($this->userId === null) {
$participant = $room->getParticipantBySession($sessionId);
$room->removeParticipantBySession($participant);
} else {
$participant = $room->getParticipant($this->userId);
$room->leaveRoom($participant->getUser());
}
} catch (RoomNotFoundException $e) {
} catch (ParticipantNotFoundException $e) {
}
return new DataResponse();
}
/**
* @NoAdminRequired
*
* @param string $token
* @param string $participant
* @return DataResponse
*/
public function promoteModerator($token, $participant) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$currentParticipant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if (!in_array($currentParticipant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
try {
$targetParticipant = $room->getParticipant($participant);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if ($targetParticipant->getParticipantType() !== Participant::USER) {
return new DataResponse([], Http::STATUS_PRECONDITION_FAILED);
}
$room->setParticipantType($participant, Participant::MODERATOR);
return new DataResponse();
}
/**
* @NoAdminRequired
*
* @param string $token
* @param string $participant
* @return DataResponse
*/
public function demoteModerator($token, $participant) {
try {
$room = $this->manager->getRoomForParticipantByToken($token, $this->userId);
$currentParticipant = $room->getParticipant($this->userId);
} catch (RoomNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if ($this->userId === $participant) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
if (!in_array($currentParticipant->getParticipantType(), [Participant::OWNER, Participant::MODERATOR], true)) {
return new DataResponse([], Http::STATUS_FORBIDDEN);
}
try {
$targetParticipant = $room->getParticipant($participant);
} catch (ParticipantNotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
if ($targetParticipant->getParticipantType() !== Participant::MODERATOR) {
return new DataResponse([], Http::STATUS_PRECONDITION_FAILED);
}
$room->setParticipantType($participant, Participant::USER);
return new DataResponse();
}
}