From c0c73d1e4998aef30ed93431afd1f526acb18d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 5 Mar 2020 20:41:29 +0100 Subject: [PATCH] Send participant permissions to the external signaling server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to filter control messages the external signaling server needs to know the permissions of each participant. Those permissions need to be set when the participant joins the room or if the participant type is changed. All participants should have permissions to publish media and screen, but only logged in moderators should have permission to send control messages. Signed-off-by: Daniel Calviño Sánchez --- lib/Controller/SignalingController.php | 6 + lib/Signaling/BackendNotifier.php | 6 + .../Controller/SignalingControllerTest.php | 121 ++++++++++++++++++ tests/php/Signaling/BackendNotifierTest.php | 95 +++++++++++++- 4 files changed, 226 insertions(+), 2 deletions(-) diff --git a/lib/Controller/SignalingController.php b/lib/Controller/SignalingController.php index c4d76dbf4..77e746afc 100644 --- a/lib/Controller/SignalingController.php +++ b/lib/Controller/SignalingController.php @@ -428,6 +428,11 @@ class SignalingController extends OCSController { } } + $permissions = ['publish-media', 'publish-screen']; + if ($participant instanceof Participant && $participant->hasModeratorPermissions(false)) { + $permissions[] = 'control'; + } + $event = new SignalingEvent($room, $participant, $action); $this->dispatcher->dispatch(self::EVENT_BACKEND_SIGNALING_ROOMS, $event); @@ -437,6 +442,7 @@ class SignalingController extends OCSController { 'version' => '1.0', 'roomid' => $room->getToken(), 'properties' => $room->getPropertiesForSignaling((string) $userId), + 'permissions' => $permissions, ], ]; if ($event->getSession()) { diff --git a/lib/Signaling/BackendNotifier.php b/lib/Signaling/BackendNotifier.php index 5750e0d14..59bb62d52 100644 --- a/lib/Signaling/BackendNotifier.php +++ b/lib/Signaling/BackendNotifier.php @@ -229,6 +229,11 @@ class BackendNotifier { $participant['userId'] = $userId; $users[] = $participant; if (\in_array($participant['sessionId'], $sessionIds, true)) { + $participant['permissions'] = ['publish-media', 'publish-screen']; + if ($participant['participantType'] === Participant::OWNER || + $participant['participantType'] === Participant::MODERATOR) { + $participant['permissions'][] = 'control'; + } $changed[] = $participant; } } @@ -238,6 +243,7 @@ class BackendNotifier { } $users[] = $participant; if (\in_array($participant['sessionId'], $sessionIds, true)) { + $participant['permissions'] = ['publish-media', 'publish-screen']; $changed[] = $participant; } } diff --git a/tests/php/Controller/SignalingControllerTest.php b/tests/php/Controller/SignalingControllerTest.php index a536d37d7..eae2edf0f 100644 --- a/tests/php/Controller/SignalingControllerTest.php +++ b/tests/php/Controller/SignalingControllerTest.php @@ -398,6 +398,115 @@ class SignalingControllerTest extends \Test\TestCase { 'name' => $roomName, 'type' => Room::ONE_TO_ONE_CALL, ], + 'permissions' => [ + 'publish-media', + 'publish-screen', + ], + ], + ], $result->getData()); + } + + public function testBackendRoomUserPublic() { + $roomToken = 'the-room'; + $roomName = 'the-room-name'; + $room = $this->createMock(Room::class); + $this->manager->expects($this->once()) + ->method('getRoomByToken') + ->with($roomToken) + ->willReturn($room); + + $participant = $this->createMock(Participant::class); + $room->expects($this->once()) + ->method('getParticipant') + ->with($this->userId) + ->willReturn($participant); + $room->expects($this->once()) + ->method('getToken') + ->willReturn($roomToken); + $room->expects($this->once()) + ->method('getPropertiesForSignaling') + ->with($this->userId) + ->willReturn([ + 'name' => $roomName, + 'type' => Room::PUBLIC_CALL, + ]); + + $result = $this->performBackendRequest([ + 'type' => 'room', + 'room' => [ + 'roomid' => $roomToken, + 'userid' => $this->userId, + 'sessionid' => '', + ], + ]); + $this->assertSame([ + 'type' => 'room', + 'room' => [ + 'version' => '1.0', + 'roomid' => $roomToken, + 'properties' => [ + 'name' => $roomName, + 'type' => Room::PUBLIC_CALL, + ], + 'permissions' => [ + 'publish-media', + 'publish-screen', + ], + ], + ], $result->getData()); + } + + public function testBackendRoomModeratorPublic() { + $roomToken = 'the-room'; + $roomName = 'the-room-name'; + $room = $this->createMock(Room::class); + $this->manager->expects($this->once()) + ->method('getRoomByToken') + ->with($roomToken) + ->willReturn($room); + + $participant = $this->createMock(Participant::class); + $participant->expects($this->once()) + ->method('hasModeratorPermissions') + ->with(false) + ->willReturn(true); + $room->expects($this->once()) + ->method('getParticipant') + ->with($this->userId) + ->willReturn($participant); + $room->expects($this->once()) + ->method('getToken') + ->willReturn($roomToken); + $room->expects($this->once()) + ->method('getPropertiesForSignaling') + ->with($this->userId) + ->willReturn([ + 'name' => $roomName, + 'type' => Room::PUBLIC_CALL, + ]); + + $result = $this->performBackendRequest([ + 'type' => 'room', + 'room' => [ + 'roomid' => $roomToken, + 'userid' => $this->userId, + 'sessionid' => '', + ], + ]); + $this->assertSame([ + 'type' => 'room', + 'room' => [ + 'version' => '1.0', + 'roomid' => $roomToken, + 'properties' => [ + 'name' => $roomName, + 'type' => Room::PUBLIC_CALL, + ], + 'permissions' => [ + 'publish-media', + 'publish-screen', + 'control', + ], ], ], $result->getData()); } @@ -445,6 +554,10 @@ class SignalingControllerTest extends \Test\TestCase { 'name' => $roomName, 'type' => Room::PUBLIC_CALL, ], + 'permissions' => [ + 'publish-media', + 'publish-screen', + ], ], ], $result->getData()); } @@ -496,6 +609,10 @@ class SignalingControllerTest extends \Test\TestCase { 'name' => $roomName, 'type' => Room::PUBLIC_CALL, ], + 'permissions' => [ + 'publish-media', + 'publish-screen', + ], ], ], $result->getData()); } @@ -581,6 +698,10 @@ class SignalingControllerTest extends \Test\TestCase { 'name' => $roomName, 'type' => Room::ONE_TO_ONE_CALL, ], + 'permissions' => [ + 'publish-media', + 'publish-screen', + ], 'session' => [ 'foo' => 'bar', 'room' => $roomToken, diff --git a/tests/php/Signaling/BackendNotifierTest.php b/tests/php/Signaling/BackendNotifierTest.php index a2f6bcbe4..37676eabf 100644 --- a/tests/php/Signaling/BackendNotifierTest.php +++ b/tests/php/Signaling/BackendNotifierTest.php @@ -562,6 +562,7 @@ class BackendNotifierTest extends \Test\TestCase { 'participants' => [ 'changed' => [ [ + 'permissions' => ['publish-media', 'publish-screen', 'control'], 'inCall' => 0, 'lastPing' => 0, 'sessionId' => $userSession, @@ -595,6 +596,7 @@ class BackendNotifierTest extends \Test\TestCase { 'participants' => [ 'changed' => [ [ + 'permissions' => ['publish-media', 'publish-screen'], 'inCall' => 0, 'lastPing' => 0, 'sessionId' => $guestSession, @@ -624,8 +626,8 @@ class BackendNotifierTest extends \Test\TestCase { $room->addUsers([ 'userId' => $notJoinedUserId, ]); - $participant = $room->getParticipant($notJoinedUserId); - $room->setParticipantType($participant, Participant::MODERATOR); + $notJoinedParticipant = $room->getParticipant($notJoinedUserId); + $room->setParticipantType($notJoinedParticipant, Participant::MODERATOR); $requests = $this->controller->getRequests(); $bodies = array_map(function($request) use ($room) { @@ -660,6 +662,95 @@ class BackendNotifierTest extends \Test\TestCase { ], ], ], $bodies); + + $this->controller->clearRequests(); + $room->setParticipantType($participant, Participant::USER); + + $requests = $this->controller->getRequests(); + $bodies = array_map(function($request) use ($room) { + return json_decode($this->validateBackendRequest($this->baseUrl . '/api/v1/room/' . $room->getToken(), $request), true); + }, $requests); + $this->assertContains([ + 'type' => 'participants', + 'participants' => [ + 'changed' => [ + [ + 'permissions' => ['publish-media', 'publish-screen'], + 'inCall' => 0, + 'lastPing' => 0, + 'sessionId' => $userSession, + 'participantType' => Participant::USER, + 'userId' => $this->userId, + ], + ], + 'users' => [ + [ + 'inCall' => 0, + 'lastPing' => 0, + 'sessionId' => $userSession, + 'participantType' => Participant::USER, + 'userId' => $this->userId, + ], + [ + 'inCall' => 0, + 'lastPing' => 0, + 'sessionId' => 0, + 'participantType' => Participant::MODERATOR, + 'userId' => $notJoinedUserId, + ], + [ + 'inCall' => 0, + 'lastPing' => 0, + 'sessionId' => $guestSession, + 'participantType' => Participant::GUEST_MODERATOR, + ], + ], + ], + ], $bodies); + + $this->controller->clearRequests(); + $room->setParticipantType($guestParticipant, Participant::GUEST); + + $requests = $this->controller->getRequests(); + $bodies = array_map(function($request) use ($room) { + return json_decode($this->validateBackendRequest($this->baseUrl . '/api/v1/room/' . $room->getToken(), $request), true); + }, $requests); + $this->assertContains([ + 'type' => 'participants', + 'participants' => [ + 'changed' => [ + [ + 'permissions' => ['publish-media', 'publish-screen'], + 'inCall' => 0, + 'lastPing' => 0, + 'sessionId' => $guestSession, + 'participantType' => Participant::GUEST, + ], + ], + 'users' => [ + [ + 'inCall' => 0, + 'lastPing' => 0, + 'sessionId' => $userSession, + 'participantType' => Participant::USER, + 'userId' => $this->userId, + ], + [ + 'inCall' => 0, + 'lastPing' => 0, + 'sessionId' => 0, + 'participantType' => Participant::MODERATOR, + 'userId' => $notJoinedUserId, + ], + [ + 'inCall' => 0, + 'lastPing' => 0, + 'sessionId' => $guestSession, + 'participantType' => Participant::GUEST, + ], + ], + ], + ], $bodies); } }