diff options
-rw-r--r-- | lib/Room.php | 6 | ||||
-rw-r--r-- | lib/Signaling/Listener.php | 13 | ||||
-rw-r--r-- | src/utils/signaling.js | 13 | ||||
-rw-r--r-- | tests/php/Signaling/BackendNotifierTest.php | 98 |
4 files changed, 124 insertions, 6 deletions
diff --git a/lib/Room.php b/lib/Room.php index f3f03880a..647462b40 100644 --- a/lib/Room.php +++ b/lib/Room.php @@ -434,9 +434,9 @@ class Room { ]; if ($roomModified) { - $properties = array_merge($properties, [ - 'description' => $this->getDescription(), - ]); + $properties['description'] = $this->getDescription(); + } else { + $properties['participant-list'] = 'refresh'; } $event = new SignalingRoomPropertiesEvent($this, $userId, $properties); diff --git a/lib/Signaling/Listener.php b/lib/Signaling/Listener.php index 6b3e37554..a7bf3250d 100644 --- a/lib/Signaling/Listener.php +++ b/lib/Signaling/Listener.php @@ -35,6 +35,7 @@ use OCA\Talk\Events\RemoveUserEvent; use OCA\Talk\Events\RoomEvent; use OCA\Talk\GuestManager; use OCA\Talk\Model\Session; +use OCA\Talk\Participant; use OCA\Talk\Room; use OCA\Talk\Service\ParticipantService; use OCA\Talk\Service\SessionService; @@ -216,8 +217,16 @@ class Listener { $sessionIds = []; if ($event->getParticipant()->getSession()) { - $sessionIds[] = $event->getParticipant()->getSession()->getSessionId(); - $notifier->roomSessionsRemoved($event->getRoom(), $sessionIds); + // Only for guests and self-joined users disconnecting is "leaving" and therefor should trigger a disinvite + $attendeeParticipantType = $event->getParticipant()->getAttendee()->getParticipantType(); + if ($attendeeParticipantType === Participant::GUEST + || $attendeeParticipantType === Participant::GUEST_MODERATOR) { + $sessionIds[] = $event->getParticipant()->getSession()->getSessionId(); + $notifier->roomSessionsRemoved($event->getRoom(), $sessionIds); + } + if ($attendeeParticipantType === Participant::USER_SELF_JOINED) { + $notifier->roomsDisinvited($event->getRoom(), [$event->getParticipant()->getAttendee()->getActorId()]); + } } }); diff --git a/src/utils/signaling.js b/src/utils/signaling.js index 8efa849b4..382c0d25f 100644 --- a/src/utils/signaling.js +++ b/src/utils/signaling.js @@ -1219,8 +1219,19 @@ Signaling.Standalone.prototype.processRoomMessageEvent = function(data) { Signaling.Standalone.prototype.processRoomListEvent = function(data) { switch (data.event.type) { + case 'update': + if (data.event.update.properties['participant-list']) { + console.debug('Room list event for participant list', data) + if (data.event.update.roomid === this.currentRoomToken) { + this._trigger('participantListChanged') + } else { + // Participant list in another room changed, we don't really care + } + break + } + // eslint-disable-next-line no-fallthrough case 'disinvite': - if (data.event.disinvite.roomid === this.currentRoomToken) { + if (data.event?.disinvite?.roomid === this.currentRoomToken) { if (this._isRejoiningConversationWithNewSession) { console.debug('Rejoining conversation with new session, "disinvite" message ignored') return diff --git a/tests/php/Signaling/BackendNotifierTest.php b/tests/php/Signaling/BackendNotifierTest.php index 16d43b72e..c4cb332d9 100644 --- a/tests/php/Signaling/BackendNotifierTest.php +++ b/tests/php/Signaling/BackendNotifierTest.php @@ -212,6 +212,19 @@ class BackendNotifierTest extends \Test\TestCase { $this->assertContainsEquals($message, $bodies, json_encode($bodies, JSON_PRETTY_PRINT)); } + private function assertNoMessageOfTypeWasSent(Room $room, string $messageType): void { + $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); + + $bodies = array_filter($bodies, function (array $body) use ($messageType) { + return $body['type'] === $messageType; + }); + + $this->assertEmpty($bodies); + } + private function sortParticipantUsers(array $message): array { if ($message['type'] === 'participants') { usort($message['participants']['users'], static function ($a, $b) { @@ -259,6 +272,7 @@ class BackendNotifierTest extends \Test\TestCase { 'listable' => Room::LISTABLE_NONE, 'active-since' => null, 'sip-enabled' => 0, + 'participant-list' => 'refresh', ], ], ]); @@ -295,6 +309,90 @@ class BackendNotifierTest extends \Test\TestCase { 'listable' => Room::LISTABLE_NONE, 'active-since' => null, 'sip-enabled' => 0, + 'participant-list' => 'refresh', + ], + ], + ]); + } + + public function testNoRoomDisinviteOnLeaveOfNormalUser() { + /** @var IUser|MockObject $testUser */ + $testUser = $this->createMock(IUser::class); + $testUser->expects($this->any()) + ->method('getUID') + ->willReturn($this->userId); + + $room = $this->manager->createRoom(Room::TYPE_PUBLIC); + $this->participantService->addUsers($room, [[ + 'actorType' => 'users', + 'actorId' => $this->userId, + ]]); + $participant = $this->participantService->joinRoom($room, $testUser, ''); + $this->controller->clearRequests(); + $this->participantService->leaveRoomAsSession($room, $participant); + + $this->assertNoMessageOfTypeWasSent($room, 'disinvite'); + } + + public function testRoomDisinviteOnLeaveOfSelfJoinedUser() { + /** @var IUser|MockObject $testUser */ + $testUser = $this->createMock(IUser::class); + $testUser->expects($this->any()) + ->method('getUID') + ->willReturn($this->userId); + + $room = $this->manager->createRoom(Room::TYPE_PUBLIC); + $participant = $this->participantService->joinRoom($room, $testUser, ''); + $this->controller->clearRequests(); + $this->participantService->leaveRoomAsSession($room, $participant); + + $this->assertMessageWasSent($room, [ + 'type' => 'disinvite', + 'disinvite' => [ + 'userids' => [ + $this->userId, + ], + 'alluserids' => [ + ], + 'properties' => [ + 'name' => $room->getDisplayName(''), + 'type' => $room->getType(), + 'lobby-state' => Webinary::LOBBY_NONE, + 'lobby-timer' => null, + 'read-only' => Room::READ_WRITE, + 'listable' => Room::LISTABLE_NONE, + 'active-since' => null, + 'sip-enabled' => 0, + 'participant-list' => 'refresh', + ], + ], + ]); + } + + public function testRoomDisinviteOnLeaveOfGuest() { + $room = $this->manager->createRoom(Room::TYPE_PUBLIC); + $participant = $this->participantService->joinRoomAsNewGuest($room, ''); + $this->controller->clearRequests(); + $this->participantService->leaveRoomAsSession($room, $participant); + + $this->assertMessageWasSent($room, [ + 'type' => 'disinvite', + 'disinvite' => [ + 'sessionids' => [ + $participant->getSession()->getSessionId(), + ], + 'alluserids' => [ + ], + 'properties' => [ + 'name' => $room->getDisplayName(''), + 'type' => $room->getType(), + 'lobby-state' => Webinary::LOBBY_NONE, + 'lobby-timer' => null, + 'read-only' => Room::READ_WRITE, + 'listable' => Room::LISTABLE_NONE, + 'active-since' => null, + 'sip-enabled' => 0, + 'participant-list' => 'refresh', ], ], ]); |