Browse Source
Merge pull request #4810 from nextcloud/feature/1329/sync-group-members-with-conversation-participants
Merge pull request #4810 from nextcloud/feature/1329/sync-group-members-with-conversation-participants
Sync group members with conversation participantspull/5460/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 616 additions and 54 deletions
-
5lib/AppInfo/Application.php
-
39lib/Collaboration/Collaborators/Listener.php
-
9lib/Command/Room/TRoomCommand.php
-
32lib/Controller/RoomController.php
-
117lib/Listener/GroupMembershipListener.php
-
17lib/Manager.php
-
1lib/Model/Attendee.php
-
98lib/Service/ParticipantService.php
-
17src/components/RightSidebar/Participants/CurrentParticipants/CurrentParticipants.vue
-
27src/components/RightSidebar/Participants/ParticipantsList/Participant/Participant.vue
-
1src/constants.js
-
40tests/integration/features/bootstrap/FeatureContext.php
-
2tests/integration/features/command/create.feature
-
1tests/integration/features/conversation/add-participant.feature
-
264tests/integration/features/conversation/group-participants.feature
@ -0,0 +1,117 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
/** |
|||
* @copyright Copyright (c) 2020 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\Talk\Listener; |
|||
|
|||
use OCA\Talk\Exceptions\ParticipantNotFoundException; |
|||
use OCA\Talk\Manager; |
|||
use OCA\Talk\Model\Attendee; |
|||
use OCA\Talk\Participant; |
|||
use OCA\Talk\Room; |
|||
use OCA\Talk\Service\ParticipantService; |
|||
use OCP\EventDispatcher\Event; |
|||
use OCP\EventDispatcher\IEventListener; |
|||
use OCP\Group\Events\UserAddedEvent; |
|||
use OCP\Group\Events\UserRemovedEvent; |
|||
use OCP\IGroup; |
|||
use OCP\IGroupManager; |
|||
use OCP\IUser; |
|||
|
|||
class GroupMembershipListener implements IEventListener { |
|||
|
|||
/** @var IGroupManager */ |
|||
private $groupManager; |
|||
/** @var Manager */ |
|||
private $manager; |
|||
/** @var ParticipantService */ |
|||
private $participantService; |
|||
|
|||
public function __construct(IGroupManager $groupManager, |
|||
Manager $manager, |
|||
ParticipantService $participantService) { |
|||
$this->groupManager = $groupManager; |
|||
$this->manager = $manager; |
|||
$this->participantService = $participantService; |
|||
} |
|||
|
|||
public function handle(Event $event): void { |
|||
if ($event instanceof UserAddedEvent) { |
|||
$this->addNewMemberToRooms($event->getGroup(), $event->getUser()); |
|||
} |
|||
if ($event instanceof UserRemovedEvent) { |
|||
$this->removeFormerMemberFromRooms($event->getGroup(), $event->getUser()); |
|||
} |
|||
} |
|||
|
|||
protected function addNewMemberToRooms(IGroup $group, IUser $user): void { |
|||
$rooms = $this->manager->getRoomsForActor(Attendee::ACTOR_GROUPS, $group->getGID()); |
|||
|
|||
foreach ($rooms as $room) { |
|||
try { |
|||
$participant = $room->getParticipant($user->getUID()); |
|||
if ($participant->getAttendee()->getParticipantType() === Participant::USER_SELF_JOINED) { |
|||
$this->participantService->updateParticipantType($room, $participant, Participant::USER); |
|||
} |
|||
} catch (ParticipantNotFoundException $e) { |
|||
$this->participantService->addUsers($room, [[ |
|||
'actorType' => Attendee::ACTOR_USERS, |
|||
'actorId' => $user->getUID(), |
|||
'displayName' => $user->getDisplayName(), |
|||
]]); |
|||
} |
|||
} |
|||
} |
|||
|
|||
protected function removeFormerMemberFromRooms(IGroup $group, IUser $user): void { |
|||
$rooms = $this->manager->getRoomsForActor(Attendee::ACTOR_GROUPS, $group->getGID()); |
|||
if (empty($rooms)) { |
|||
return; |
|||
} |
|||
|
|||
$userGroupIds = $this->groupManager->getUserGroupIds($user); |
|||
|
|||
$furtherMemberships = []; |
|||
foreach ($userGroupIds as $groupId) { |
|||
$groupRooms = $this->manager->getRoomsForActor(Attendee::ACTOR_GROUPS, $groupId); |
|||
foreach ($groupRooms as $room) { |
|||
$furtherMemberships[$room->getId()] = true; |
|||
} |
|||
} |
|||
|
|||
$rooms = array_filter($rooms, static function (Room $room) use ($furtherMemberships) { |
|||
// Only delete from rooms where the user is not member via another group
|
|||
return !isset($furtherMemberships[$room->getId()]); |
|||
}); |
|||
|
|||
foreach ($rooms as $room) { |
|||
try { |
|||
$participant = $room->getParticipant($user->getUID()); |
|||
$participantType = $participant->getAttendee()->getParticipantType(); |
|||
if ($participantType === Participant::USER) { |
|||
$this->participantService->removeUser($room, $user, Room::PARTICIPANT_REMOVED); |
|||
} |
|||
} catch (ParticipantNotFoundException $e) { |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,264 @@ |
|||
Feature: public |
|||
Background: |
|||
Given user "participant1" exists |
|||
Given user "participant2" exists |
|||
Given user "participant3" exists |
|||
And group "group1" exists |
|||
And group "group2" exists |
|||
And user "participant2" is member of group "group1" |
|||
|
|||
Scenario: Owner invites a group |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 3 | |
|||
| roomName | room | |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
And user "participant1" adds group "group1" to room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
|
|||
Scenario: Owner start a chat with a group |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 2 | |
|||
| source | group | |
|||
| invite |group1 | |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
|
|||
Scenario: User is added to a group which is a member of a chat |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 2 | |
|||
| source | group | |
|||
| invite |group1 | |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
And user "participant3" is member of group "group1" |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
| users | participant3 | 3 | |
|||
|
|||
Scenario: User is removed from a group which is a member of a chat |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 2 | |
|||
| source | group | |
|||
| invite |group1 | |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
And user "participant2" is not member of group "group1" |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
|
|||
Scenario: User is removed from a group which is a member of a chat but has a second group |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 2 | |
|||
| source | group | |
|||
| invite |group1 | |
|||
And user "participant2" is member of group "group2" |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
And user "participant1" adds group "group2" to room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
| groups | group2 | 3 | |
|||
And user "participant2" is not member of group "group1" |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
| groups | group2 | 3 | |
|||
|
|||
Scenario: User is not removed from a chat when one group is removed but has a second group |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 2 | |
|||
| source | group | |
|||
| invite |group1 | |
|||
And user "participant2" is member of group "group2" |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
And user "participant1" adds group "group2" to room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
| groups | group2 | 3 | |
|||
And user "participant1" removes group "group1" from room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| users | participant2 | 3 | |
|||
| groups | group2 | 3 | |
|||
|
|||
Scenario: User is removed from when their last group which is a member of a chat is removed |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 2 | |
|||
| source | group | |
|||
| invite |group1 | |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
And user "participant1" removes group "group1" from room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
|
|||
Scenario: Moderator is removed from a group which is a member of a chat but stays in the chat |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 2 | |
|||
| source | group | |
|||
| invite |group1 | |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
And user "participant1" promotes "participant2" in room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 2 | |
|||
And user "participant2" is not member of group "group1" |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 2 | |
|||
|
|||
Scenario: Group of a moderator is removed from a chat but moderator stays in the chat |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 2 | |
|||
| source | group | |
|||
| invite |group1 | |
|||
And user "participant1" promotes "participant2" in room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 2 | |
|||
And user "participant1" removes group "group1" from room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| users | participant2 | 2 | |
|||
|
|||
Scenario: User that was already a member has their group added to a chat |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 3 | |
|||
| roomName | room | |
|||
And user "participant1" adds user "participant2" to room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| users | participant2 | 3 | |
|||
And user "participant1" adds group "group1" to room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| users | participant2 | 3 | |
|||
| groups | group1 | 3 | |
|||
|
|||
Scenario: User that was self-joined has their group added to a chat |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 3 | |
|||
| roomName | room | |
|||
And user "participant2" joins room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| users | participant2 | 5 | |
|||
And user "participant1" adds group "group1" to room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| users | participant2 | 3 | |
|||
| groups | group1 | 3 | |
|||
|
|||
Scenario: User that was already a member is added to a group which is a member of a chat |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 2 | |
|||
| source | group | |
|||
| invite |group1 | |
|||
And user "participant1" adds user "participant3" to room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
| users | participant3 | 3 | |
|||
And user "participant3" is member of group "group1" |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
| users | participant3 | 3 | |
|||
|
|||
Scenario: User that was self-joined is added to a group which is a member of a chat |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 3 | |
|||
| roomName | room | |
|||
And user "participant1" adds group "group1" to room "room" with 200 (v4) |
|||
And user "participant3" joins room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
| users | participant3 | 5 | |
|||
And user "participant3" is member of group "group1" |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
|||
| users | participant2 | 3 | |
|||
| users | participant3 | 3 | |
|||
|
|||
Scenario: User that was already a member is removed from a group which is a member of a chat |
|||
# This might not be what most people desire but fixing this would mean we |
|||
# need to keep multiple records per user whether they were added manually before etc. |
|||
Given user "participant1" creates room "room" (v4) |
|||
| roomType | 3 | |
|||
| roomName | room | |
|||
And user "participant1" adds user "participant2" to room "room" with 200 (v4) |
|||
And user "participant1" adds group "group1" to room "room" with 200 (v4) |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| users | participant2 | 3 | |
|||
| groups | group1 | 3 | |
|||
And user "participant2" is not member of group "group1" |
|||
And user "participant1" sees the following attendees in room "room" with 200 (v4) |
|||
| actorType | actorId | participantType | |
|||
| users | participant1 | 1 | |
|||
| groups | group1 | 3 | |
Write
Preview
Loading…
Cancel
Save
Reference in new issue