Browse Source

Add system messages for inviting, accepting and declining

Signed-off-by: Joas Schilling <coding@schilljs.com>
pull/7464/head
Joas Schilling 3 years ago
parent
commit
be00d4e42c
No known key found for this signature in database GPG Key ID: 7076EA9751AACDDA
  1. 38
      lib/Chat/Parser/SystemMessage.php
  2. 7
      lib/Chat/SystemMessage/Listener.php
  3. 25
      lib/Federation/CloudFederationProviderTalk.php
  4. 2
      tests/integration/features/bootstrap/FeatureContext.php
  5. 18
      tests/integration/features/federation/invite.feature
  6. 6
      tests/php/Chat/Parser/SystemMessageTest.php
  7. 4
      tests/php/Federation/FederationTest.php

38
lib/Chat/Parser/SystemMessage.php

@ -34,6 +34,7 @@ use OCA\Talk\Participant;
use OCA\Talk\Room;
use OCA\Talk\Share\RoomShareProvider;
use OCP\Comments\IComment;
use OCP\Federation\ICloudIdManager;
use OCP\Files\InvalidPathException;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
@ -57,6 +58,7 @@ class SystemMessage {
protected RoomShareProvider $shareProvider;
protected PhotoCache $photoCache;
protected IRootFolder $rootFolder;
protected ICloudIdManager $cloudIdManager;
protected IURLGenerator $url;
protected ?IL10N $l = null;
@ -80,6 +82,7 @@ class SystemMessage {
RoomShareProvider $shareProvider,
PhotoCache $photoCache,
IRootFolder $rootFolder,
ICloudIdManager $cloudIdManager,
IURLGenerator $url) {
$this->userManager = $userManager;
$this->groupManager = $groupManager;
@ -88,6 +91,7 @@ class SystemMessage {
$this->shareProvider = $shareProvider;
$this->photoCache = $photoCache;
$this->rootFolder = $rootFolder;
$this->cloudIdManager = $cloudIdManager;
$this->url = $url;
}
@ -285,6 +289,26 @@ class SystemMessage {
$parsedMessage = $this->l->t('An administrator removed {user}');
}
}
} elseif ($message === 'federated_user_added') {
$parsedParameters['federated_user'] = $this->getRemoteUser($parameters['federated_user']);
$parsedMessage = $this->l->t('{actor} invited {user}');
if ($currentUserIsActor) {
$parsedMessage = $this->l->t('You invited {user}');
} elseif ($cliIsActor) {
$parsedMessage = $this->l->t('An administrator invited {user}');
} elseif ($parsedParameters['federated_user']['id'] === $parsedParameters['actor']['id']) {
$parsedMessage = $this->l->t('{federated_user} accepted the invitation');
}
} elseif ($message === 'federated_user_removed') {
$parsedParameters['federated_user'] = $this->getRemoteUser($parameters['federated_user']);
$parsedMessage = $this->l->t('{actor} removed {federated_user}');
if ($currentUserIsActor) {
$parsedMessage = $this->l->t('You removed {federated_user}');
} elseif ($cliIsActor) {
$parsedMessage = $this->l->t('An administrator removed {federated_user}');
} elseif ($parsedParameters['federated_user']['id'] === $parsedParameters['actor']['id']) {
$parsedMessage = $this->l->t('{federated_user} declined the invitation');
}
} elseif ($message === 'group_added') {
$parsedParameters['group'] = $this->getGroup($parameters['group']);
$parsedMessage = $this->l->t('{actor} added group {group}');
@ -588,6 +612,9 @@ class SystemMessage {
if ($actorType === Attendee::ACTOR_GUESTS) {
return $this->getGuest($room, $actorId);
}
if ($actorType === Attendee::ACTOR_FEDERATED_USERS) {
return $this->getRemoteUser($actorId);
}
return $this->getUser($actorId);
}
@ -616,6 +643,17 @@ class SystemMessage {
];
}
protected function getRemoteUser(string $federationId): array {
$cloudId = $this->cloudIdManager->resolveCloudId($federationId);
return [
'type' => 'user',
'id' => $cloudId->getUser(),
'name' => $cloudId->getDisplayId(),
'server' => $cloudId->getRemote(),
];
}
protected function getDisplayName(string $uid): string {
$user = $this->userManager->get($uid);
if ($user instanceof IUser) {

7
lib/Chat/SystemMessage/Listener.php

@ -370,6 +370,8 @@ class Listener implements IEventListener {
$this->sendSystemMessage($event->getRoom(), 'group_added', ['group' => $attendee->getActorId()]);
} elseif ($attendee->getActorType() === Attendee::ACTOR_CIRCLES) {
$this->sendSystemMessage($event->getRoom(), 'circle_added', ['circle' => $attendee->getActorId()]);
} elseif ($attendee->getActorType() === Attendee::ACTOR_FEDERATED_USERS) {
$this->sendSystemMessage($event->getRoom(), 'federated_user_added', ['federated_user' => $attendee->getActorId()]);
}
}
}
@ -380,6 +382,8 @@ class Listener implements IEventListener {
$this->sendSystemMessage($event->getRoom(), 'group_removed', ['group' => $attendee->getActorId()]);
} elseif ($attendee->getActorType() === Attendee::ACTOR_CIRCLES) {
$this->sendSystemMessage($event->getRoom(), 'circle_removed', ['circle' => $attendee->getActorId()]);
} elseif ($attendee->getActorType() === Attendee::ACTOR_FEDERATED_USERS) {
$this->sendSystemMessage($event->getRoom(), 'federated_user_removed', ['federated_user' => $attendee->getActorId()]);
}
}
}
@ -399,6 +403,9 @@ class Listener implements IEventListener {
} elseif ($this->session->exists('talk-overwrite-actor')) {
$actorType = Attendee::ACTOR_USERS;
$actorId = $this->session->get('talk-overwrite-actor');
} elseif ($this->session->exists('talk-overwrite-actor-type')) {
$actorType = $this->session->get('talk-overwrite-actor-type');
$actorId = $this->session->get('talk-overwrite-actor-id');
} else {
$actorType = Attendee::ACTOR_GUESTS;
$sessionId = $this->talkSession->getSessionForRoom($room->getToken());

25
lib/Federation/CloudFederationProviderTalk.php

@ -29,6 +29,7 @@ use Exception;
use OCA\FederatedFileSharing\AddressHandler;
use OCA\Talk\AppInfo\Application;
use OCA\Talk\Config;
use OCA\Talk\Events\AttendeesAddedEvent;
use OCA\Talk\Manager;
use OCA\Talk\Model\Attendee;
use OCA\Talk\Model\AttendeeMapper;
@ -37,6 +38,7 @@ use OCA\Talk\Room;
use OCA\Talk\Service\ParticipantService;
use OCP\AppFramework\Http;
use OCP\DB\Exception as DBException;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\Exceptions\ActionNotSupportedException;
use OCP\Federation\Exceptions\AuthenticationFailedException;
use OCP\Federation\Exceptions\BadRequestException;
@ -44,6 +46,7 @@ use OCP\Federation\Exceptions\ProviderCouldNotAddShareException;
use OCP\Federation\ICloudFederationProvider;
use OCP\Federation\ICloudFederationShare;
use OCP\HintException;
use OCP\ISession;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
@ -69,6 +72,8 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
private AttendeeMapper $attendeeMapper;
private Manager $manager;
private ISession $session;
private IEventDispatcher $dispatcher;
private LoggerInterface $logger;
public function __construct(
@ -81,6 +86,8 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
ParticipantService $participantService,
AttendeeMapper $attendeeMapper,
Manager $manager,
ISession $session,
IEventDispatcher $dispatcher,
LoggerInterface $logger
) {
$this->userManager = $userManager;
@ -92,6 +99,8 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
$this->participantService = $participantService;
$this->attendeeMapper = $attendeeMapper;
$this->manager = $manager;
$this->session = $session;
$this->dispatcher = $dispatcher;
$this->logger = $logger;
}
@ -193,7 +202,15 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
private function shareAccepted(int $id, array $notification): array {
$attendee = $this->getAttendeeAndValidate($id, $notification['sharedSecret']);
// TODO: Add activity for share accepted
$this->session->set('talk-overwrite-actor-type', $attendee->getActorType());
$this->session->set('talk-overwrite-actor-id', $attendee->getActorId());
$room = $this->manager->getRoomById($attendee->getRoomId());
$event = new AttendeesAddedEvent($room, [$attendee]);
$this->dispatcher->dispatchTyped($event);
$this->session->remove('talk-overwrite-actor-type');
$this->session->remove('talk-overwrite-actor-id');
return [];
}
@ -206,9 +223,15 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
private function shareDeclined(int $id, array $notification): array {
$attendee = $this->getAttendeeAndValidate($id, $notification['sharedSecret']);
$this->session->set('talk-overwrite-actor-type', $attendee->getActorType());
$this->session->set('talk-overwrite-actor-id', $attendee->getActorId());
$room = $this->manager->getRoomById($attendee->getRoomId());
$participant = new Participant($room, $attendee, null);
$this->participantService->removeAttendee($room, $participant, Room::PARTICIPANT_LEFT);
$this->session->remove('talk-overwrite-actor-type');
$this->session->remove('talk-overwrite-actor-id');
return [];
}

2
tests/integration/features/bootstrap/FeatureContext.php

@ -1818,7 +1818,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
$data = [
'room' => self::$tokenToIdentifier[$message['token']],
'actorType' => (string) $message['actorType'],
'actorId' => ($message['actorType'] === 'guests') ? self::$sessionIdToUser[$message['actorId']]: (string) $message['actorId'],
'actorId' => ($message['actorType'] === 'guests') ? self::$sessionIdToUser[$message['actorId']] : (string) $message['actorId'],
'systemMessage' => (string) $message['systemMessage'],
];

18
tests/integration/features/federation/invite.feature

@ -25,6 +25,10 @@ Feature: federation/invite
| actorType | actorId | participantType |
| users | participant1 | 1 |
| federated_users | participant2 | 3 |
Then user "participant1" sees the following system messages in room "room" with 200
| room | actorType | actorId | systemMessage | message | messageParameters |
| room | users | participant1 | federated_user_added | You invited {user} | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"},"federated_user":{"type":"user","id":"participant2","name":"participant2@localhost:8180","server":"http:\/\/localhost:8180"}} |
| room | users | participant1 | conversation_created | You created the conversation | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"}} |
And user "participant2" has the following invitations (v1)
| remote_server | remote_token |
| LOCAL | room |
@ -37,6 +41,11 @@ Feature: federation/invite
| actorType | actorId | participantType |
| users | participant1 | 1 |
| federated_users | participant2 | 3 |
Then user "participant1" sees the following system messages in room "room" with 200
| room | actorType | actorId | systemMessage | message | messageParameters |
| room | federated_users | participant2@http://localhost:8180 | federated_user_added | {federated_user} accepted the invitation | {"actor":{"type":"user","id":"participant2","name":"participant2@localhost:8180","server":"http:\/\/localhost:8180"},"federated_user":{"type":"user","id":"participant2","name":"participant2@localhost:8180","server":"http:\/\/localhost:8180"}} |
| room | users | participant1 | federated_user_added | You invited {user} | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"},"federated_user":{"type":"user","id":"participant2","name":"participant2@localhost:8180","server":"http:\/\/localhost:8180"}} |
| room | users | participant1 | conversation_created | You created the conversation | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"}} |
Scenario: Declining an invite
Given the following "spreed" app config is set
@ -49,6 +58,10 @@ Feature: federation/invite
| actorType | actorId | participantType |
| users | participant1 | 1 |
| federated_users | participant2 | 3 |
Then user "participant1" sees the following system messages in room "room" with 200
| room | actorType | actorId | systemMessage | message | messageParameters |
| room | users | participant1 | federated_user_added | You invited {user} | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"},"federated_user":{"type":"user","id":"participant2","name":"participant2@localhost:8180","server":"http:\/\/localhost:8180"}} |
| room | users | participant1 | conversation_created | You created the conversation | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"}} |
And user "participant2" has the following invitations (v1)
| remote_server | remote_token |
| LOCAL | room |
@ -60,3 +73,8 @@ Feature: federation/invite
When user "participant1" sees the following attendees in room "room" with 200 (v4)
| actorType | actorId | participantType |
| users | participant1 | 1 |
Then user "participant1" sees the following system messages in room "room" with 200
| room | actorType | actorId | systemMessage | message | messageParameters |
| room | federated_users | participant2@http://localhost:8180 | federated_user_removed | {federated_user} declined the invitation | {"actor":{"type":"user","id":"participant2","name":"participant2@localhost:8180","server":"http:\/\/localhost:8180"},"federated_user":{"type":"user","id":"participant2","name":"participant2@localhost:8180","server":"http:\/\/localhost:8180"}} |
| room | users | participant1 | federated_user_added | You invited {user} | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"},"federated_user":{"type":"user","id":"participant2","name":"participant2@localhost:8180","server":"http:\/\/localhost:8180"}} |
| room | users | participant1 | conversation_created | You created the conversation | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"}} |

6
tests/php/Chat/Parser/SystemMessageTest.php

@ -33,6 +33,7 @@ use OCA\Talk\Participant;
use OCA\Talk\Room;
use OCA\Talk\Share\RoomShareProvider;
use OCP\Comments\IComment;
use OCP\Federation\ICloudIdManager;
use OCP\Files\Folder;
use OCP\Files\InvalidPathException;
use OCP\Files\IRootFolder;
@ -71,6 +72,8 @@ class SystemMessageTest extends TestCase {
protected $rootFolder;
/** @var IURLGenerator|MockObject */
protected $url;
/** @var ICloudIdManager|MockObject */
protected $cloudIdManager;
/** @var IL10N|MockObject */
protected $l;
@ -85,6 +88,7 @@ class SystemMessageTest extends TestCase {
$this->photoCache = $this->createMock(PhotoCache::class);
$this->rootFolder = $this->createMock(IRootFolder::class);
$this->url = $this->createMock(IURLGenerator::class);
$this->cloudIdManager = $this->createMock(ICloudIdManager::class);
$this->l = $this->createMock(IL10N::class);
$this->l->expects($this->any())
->method('t')
@ -114,6 +118,7 @@ class SystemMessageTest extends TestCase {
$this->shareProvider,
$this->photoCache,
$this->rootFolder,
$this->cloudIdManager,
$this->url,
])
->onlyMethods($methods)
@ -129,6 +134,7 @@ class SystemMessageTest extends TestCase {
$this->shareProvider,
$this->photoCache,
$this->rootFolder,
$this->cloudIdManager,
$this->url
);
}

4
tests/php/Federation/FederationTest.php

@ -34,10 +34,12 @@ use OCA\Talk\Model\AttendeeMapper;
use OCA\Talk\Room;
use OCA\Talk\Service\ParticipantService;
use OCP\BackgroundJob\IJobList;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\ICloudFederationFactory;
use OCP\Federation\ICloudFederationNotification;
use OCP\Federation\ICloudFederationProviderManager;
use OCP\Federation\ICloudFederationShare;
use OCP\ISession;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
@ -108,6 +110,8 @@ class FederationTest extends TestCase {
$this->createMock(ParticipantService::class),
$this->attendeeMapper,
$this->createMock(Manager::class),
$this->createMock(ISession::class),
$this->createMock(IEventDispatcher::class),
$this->logger
);
}

Loading…
Cancel
Save