зеркало из https://github.com/nextcloud/spreed.git
Grant permissions in the HPB based on publishing permissions
When a participant does not have publishing permissions the HPB will block signaling messages related to establishing a connection, like sending the candidates. This would prevent participants using clients not supporting yet the publishing permissions (and thus still trying to publish even if they are not allowed to) from sending media in a call. Unfortunately the lack of permissions only prevents the connection from being established. If a participant is already sending media revoking the publishing permissions will not cause the connection to be stopped by the HPB. Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
Родитель
3b73e10ca4
Коммит
7631251c99
|
@ -645,9 +645,17 @@ class SignalingController extends OCSController {
|
|||
}
|
||||
}
|
||||
|
||||
$permissions = ['publish-media', 'publish-screen'];
|
||||
if ($participant instanceof Participant && $participant->hasModeratorPermissions(false)) {
|
||||
$permissions[] = 'control';
|
||||
$permissions = [];
|
||||
if ($participant instanceof Participant) {
|
||||
if ($participant->getAttendee()->getPublishingPermissions() & (Attendee::PUBLISHING_PERMISSIONS_AUDIO | Attendee::PUBLISHING_PERMISSIONS_VIDEO)) {
|
||||
$permissions[] = 'publish-media';
|
||||
}
|
||||
if ($participant->getAttendee()->getPublishingPermissions() & Attendee::PUBLISHING_PERMISSIONS_SCREENSHARING) {
|
||||
$permissions[] = 'publish-screen';
|
||||
}
|
||||
if ($participant->hasModeratorPermissions(false)) {
|
||||
$permissions[] = 'control';
|
||||
}
|
||||
}
|
||||
|
||||
$event = new SignalingEvent($room, $participant, $action);
|
||||
|
|
|
@ -277,7 +277,13 @@ class BackendNotifier {
|
|||
$users[] = $data;
|
||||
|
||||
if (\in_array($session->getSessionId(), $sessionIds, true)) {
|
||||
$data['permissions'] = ['publish-media', 'publish-screen'];
|
||||
$data['permissions'] = [];
|
||||
if ($attendee->getPublishingPermissions() & (Attendee::PUBLISHING_PERMISSIONS_AUDIO | Attendee::PUBLISHING_PERMISSIONS_VIDEO)) {
|
||||
$data['permissions'][] = 'publish-media';
|
||||
}
|
||||
if ($attendee->getPublishingPermissions() & Attendee::PUBLISHING_PERMISSIONS_SCREENSHARING) {
|
||||
$data['permissions'][] = 'publish-screen';
|
||||
}
|
||||
if ($attendee->getParticipantType() === Participant::OWNER ||
|
||||
$attendee->getParticipantType() === Participant::MODERATOR) {
|
||||
$data['permissions'][] = 'control';
|
||||
|
|
|
@ -130,7 +130,8 @@ class Listener {
|
|||
// "participantsModified" once the clients no longer expect a
|
||||
// "roomModified" message for participant type changes.
|
||||
$dispatcher->addListener(Room::EVENT_AFTER_PARTICIPANT_TYPE_SET, $listener);
|
||||
$dispatcher->addListener(Room::EVENT_AFTER_PARTICIPANT_TYPE_SET, static function (ModifyParticipantEvent $event) {
|
||||
|
||||
$listener = static function (ModifyParticipantEvent $event) {
|
||||
if (self::isUsingInternalSignaling()) {
|
||||
return;
|
||||
}
|
||||
|
@ -151,7 +152,10 @@ class Listener {
|
|||
}
|
||||
|
||||
$notifier->participantsModified($event->getRoom(), $sessionIds);
|
||||
});
|
||||
};
|
||||
$dispatcher->addListener(Room::EVENT_AFTER_PARTICIPANT_TYPE_SET, $listener);
|
||||
$dispatcher->addListener(Room::EVENT_AFTER_PARTICIPANT_PUBLISHING_PERMISSIONS_SET, $listener);
|
||||
|
||||
$dispatcher->addListener(Room::EVENT_BEFORE_ROOM_DELETE, static function (RoomEvent $event) {
|
||||
if (self::isUsingInternalSignaling()) {
|
||||
return;
|
||||
|
|
|
@ -29,6 +29,7 @@ use OCA\Talk\Events\SignalingEvent;
|
|||
use OCA\Talk\Exceptions\ParticipantNotFoundException;
|
||||
use OCA\Talk\Exceptions\RoomNotFoundException;
|
||||
use OCA\Talk\Manager;
|
||||
use OCA\Talk\Model\Attendee;
|
||||
use OCA\Talk\Model\AttendeeMapper;
|
||||
use OCA\Talk\Model\SessionMapper;
|
||||
use OCA\Talk\Participant;
|
||||
|
@ -384,7 +385,13 @@ class SignalingControllerTest extends \Test\TestCase {
|
|||
->with($roomToken)
|
||||
->willReturn($room);
|
||||
|
||||
$attendee = Attendee::fromRow([
|
||||
'publishing_permissions' => Attendee::PUBLISHING_PERMISSIONS_ALL,
|
||||
]);
|
||||
$participant = $this->createMock(Participant::class);
|
||||
$participant->expects($this->any())
|
||||
->method('getAttendee')
|
||||
->willReturn($attendee);
|
||||
$room->expects($this->once())
|
||||
->method('getParticipant')
|
||||
->with($this->userId)
|
||||
|
@ -434,7 +441,13 @@ class SignalingControllerTest extends \Test\TestCase {
|
|||
->with($roomToken)
|
||||
->willReturn($room);
|
||||
|
||||
$attendee = Attendee::fromRow([
|
||||
'publishing_permissions' => Attendee::PUBLISHING_PERMISSIONS_ALL,
|
||||
]);
|
||||
$participant = $this->createMock(Participant::class);
|
||||
$participant->expects($this->any())
|
||||
->method('getAttendee')
|
||||
->willReturn($attendee);
|
||||
$room->expects($this->once())
|
||||
->method('getParticipant')
|
||||
->with($this->userId)
|
||||
|
@ -484,7 +497,13 @@ class SignalingControllerTest extends \Test\TestCase {
|
|||
->with($roomToken)
|
||||
->willReturn($room);
|
||||
|
||||
$attendee = Attendee::fromRow([
|
||||
'publishing_permissions' => Attendee::PUBLISHING_PERMISSIONS_ALL,
|
||||
]);
|
||||
$participant = $this->createMock(Participant::class);
|
||||
$participant->expects($this->any())
|
||||
->method('getAttendee')
|
||||
->willReturn($attendee);
|
||||
$participant->expects($this->once())
|
||||
->method('hasModeratorPermissions')
|
||||
->with(false)
|
||||
|
@ -540,7 +559,13 @@ class SignalingControllerTest extends \Test\TestCase {
|
|||
->with($roomToken)
|
||||
->willReturn($room);
|
||||
|
||||
$attendee = Attendee::fromRow([
|
||||
'publishing_permissions' => Attendee::PUBLISHING_PERMISSIONS_ALL,
|
||||
]);
|
||||
$participant = $this->createMock(Participant::class);
|
||||
$participant->expects($this->any())
|
||||
->method('getAttendee')
|
||||
->willReturn($attendee);
|
||||
$room->expects($this->once())
|
||||
->method('getParticipantBySession')
|
||||
->with($sessionId)
|
||||
|
@ -591,7 +616,13 @@ class SignalingControllerTest extends \Test\TestCase {
|
|||
->with($roomToken)
|
||||
->willReturn($room);
|
||||
|
||||
$attendee = Attendee::fromRow([
|
||||
'publishing_permissions' => Attendee::PUBLISHING_PERMISSIONS_ALL,
|
||||
]);
|
||||
$participant = $this->createMock(Participant::class);
|
||||
$participant->expects($this->any())
|
||||
->method('getAttendee')
|
||||
->willReturn($attendee);
|
||||
$room->expects($this->once())
|
||||
->method('getParticipantBySession')
|
||||
->with($sessionId)
|
||||
|
@ -632,6 +663,78 @@ class SignalingControllerTest extends \Test\TestCase {
|
|||
], $result->getData());
|
||||
}
|
||||
|
||||
public function dataBackendRoomUserPublicPublishingPermissions(): array {
|
||||
return [
|
||||
[Attendee::PUBLISHING_PERMISSIONS_NONE, []],
|
||||
[Attendee::PUBLISHING_PERMISSIONS_AUDIO, ['publish-media']],
|
||||
[Attendee::PUBLISHING_PERMISSIONS_VIDEO, ['publish-media']],
|
||||
[Attendee::PUBLISHING_PERMISSIONS_VIDEO | Attendee::PUBLISHING_PERMISSIONS_VIDEO, ['publish-media']],
|
||||
[Attendee::PUBLISHING_PERMISSIONS_SCREENSHARING, ['publish-screen']],
|
||||
[Attendee::PUBLISHING_PERMISSIONS_AUDIO | Attendee::PUBLISHING_PERMISSIONS_SCREENSHARING, ['publish-media', 'publish-screen']],
|
||||
[Attendee::PUBLISHING_PERMISSIONS_VIDEO | Attendee::PUBLISHING_PERMISSIONS_SCREENSHARING, ['publish-media', 'publish-screen']],
|
||||
[Attendee::PUBLISHING_PERMISSIONS_AUDIO | Attendee::PUBLISHING_PERMISSIONS_VIDEO | Attendee::PUBLISHING_PERMISSIONS_SCREENSHARING, ['publish-media', 'publish-screen']],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataBackendRoomUserPublicPublishingPermissions
|
||||
*
|
||||
* @param int $publishingPermissions
|
||||
* @param array $expectedBackendPermissions
|
||||
*/
|
||||
public function testBackendRoomUserPublicPublishingPermissions(int $publishingPermissions, array $expectedBackendPermissions) {
|
||||
$roomToken = 'the-room';
|
||||
$roomName = 'the-room-name';
|
||||
$room = $this->createMock(Room::class);
|
||||
$this->manager->expects($this->once())
|
||||
->method('getRoomByToken')
|
||||
->with($roomToken)
|
||||
->willReturn($room);
|
||||
|
||||
$attendee = Attendee::fromRow([
|
||||
'publishing_permissions' => $publishingPermissions,
|
||||
]);
|
||||
$participant = $this->createMock(Participant::class);
|
||||
$participant->expects($this->any())
|
||||
->method('getAttendee')
|
||||
->willReturn($attendee);
|
||||
$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' => $expectedBackendPermissions,
|
||||
],
|
||||
], $result->getData());
|
||||
}
|
||||
|
||||
public function testBackendRoomAnonymousOneToOne() {
|
||||
$roomToken = 'the-room';
|
||||
$sessionId = 'the-session';
|
||||
|
@ -679,7 +782,13 @@ class SignalingControllerTest extends \Test\TestCase {
|
|||
->with($roomToken)
|
||||
->willReturn($room);
|
||||
|
||||
$attendee = Attendee::fromRow([
|
||||
'publishing_permissions' => Attendee::PUBLISHING_PERMISSIONS_ALL,
|
||||
]);
|
||||
$participant = $this->createMock(Participant::class);
|
||||
$participant->expects($this->any())
|
||||
->method('getAttendee')
|
||||
->willReturn($attendee);
|
||||
$room->expects($this->once())
|
||||
->method('getParticipant')
|
||||
->with($this->userId)
|
||||
|
|
Загрузка…
Ссылка в новой задаче