Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions lib/Controller/RoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,43 @@ public function getParticipants(bool $includeStatus = false): DataResponse {
if ($this->room->isFederatedConversation()) {
/** @var \OCA\Talk\Federation\Proxy\TalkV1\Controller\RoomController $proxy */
$proxy = \OCP\Server::get(\OCA\Talk\Federation\Proxy\TalkV1\Controller\RoomController::class);
return $proxy->getParticipants($this->room, $this->participant);
$response = $proxy->getParticipants($this->room, $this->participant);
$data = $response->getData();

if ($this->userId !== null
&& $includeStatus
&& count($data) < Config::USER_STATUS_INTEGRATION_LIMIT
&& $this->appManager->isEnabledForUser('user_status')) {
$userIds = array_filter(array_map(static function (array $parsedParticipant): ?string {
if ($parsedParticipant['actorType'] === Attendee::ACTOR_USERS) {
return $parsedParticipant['actorId'];
}
return null;
}, $data));

$statuses = $this->statusManager->getUserStatuses($userIds);
$data = array_map(static function (array $parsedParticipant) use ($statuses): array {
if ($parsedParticipant['actorType'] === Attendee::ACTOR_USERS
&& isset($statuses[$parsedParticipant['actorId']])) {
$userId = $parsedParticipant['actorId'];
if (isset($statuses[$userId])) {
$parsedParticipant['status'] = $statuses[$userId]->getStatus();
$parsedParticipant['statusIcon'] = $statuses[$userId]->getIcon();
$parsedParticipant['statusMessage'] = $statuses[$userId]->getMessage();
$parsedParticipant['statusClearAt'] = $statuses[$userId]->getClearAt()?->getTimestamp();
} else {
$parsedParticipant['status'] = IUserStatus::OFFLINE;
$parsedParticipant['statusIcon'] = null;
$parsedParticipant['statusMessage'] = null;
$parsedParticipant['statusClearAt'] = null;
}
}
return $parsedParticipant;
}, $data);
}

$response->setData($data);
return $response;
}

if ($this->participant->getAttendee()->getParticipantType() === Participant::GUEST) {
Expand Down Expand Up @@ -916,7 +952,7 @@ protected function formatParticipantList(array $participants, bool $includeStatu
&& $includeStatus
&& count($participants) < Config::USER_STATUS_INTEGRATION_LIMIT
&& $this->appManager->isEnabledForUser('user_status')) {
$userIds = array_filter(array_map(static function (Participant $participant) {
$userIds = array_filter(array_map(static function (Participant $participant): ?string {
if ($participant->getAttendee()->getActorType() === Attendee::ACTOR_USERS) {
return $participant->getAttendee()->getActorId();
}
Expand Down
2 changes: 0 additions & 2 deletions lib/Federation/Proxy/TalkV1/Controller/RoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public function __construct(
/**
* @see \OCA\Talk\Controller\RoomController::getParticipants()
*
* @param bool $includeStatus Include the user statuses
* @return DataResponse<Http::STATUS_OK, TalkParticipant[], array{X-Nextcloud-Has-User-Statuses?: bool}>
* @throws CannotReachRemoteException
*
Expand All @@ -50,7 +49,6 @@ public function getParticipants(Room $room, Participant $participant): DataRespo
/** @var TalkParticipant[] $data */
$data = $this->proxy->getOCSData($proxy);

// FIXME post-load status information of now local users
/** @var TalkParticipant[] $data */
$data = $this->userConverter->convertAttendees($room, $data, 'actorType', 'actorId', 'displayName');
$headers = [];
Expand Down
14 changes: 11 additions & 3 deletions tests/integration/features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -738,17 +738,18 @@ public function userIsParticipantOfRoom(string $user, string $isOrNotParticipant
}

/**
* @Then /^user "([^"]*)" sees the following attendees in room "([^"]*)" with (\d+) \((v4)\)$/
* @Then /^user "([^"]*)" sees the following attendees( with status)? in room "([^"]*)" with (\d+) \((v4)\)$/
*
* @param string $user
* @param string $withStatus
* @param string $identifier
* @param int $statusCode
* @param string $apiVersion
* @param TableNode $formData
*/
public function userSeesAttendeesInRoom(string $user, string $identifier, int $statusCode, string $apiVersion, ?TableNode $formData = null): void {
public function userSeesAttendeesInRoom(string $user, string $withStatus, string $identifier, int $statusCode, string $apiVersion, ?TableNode $formData = null): void {
$this->setCurrentUser($user);
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants');
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/participants?includeStatus=' . ($withStatus === ' with status' ? '1' : '0'));
$this->assertStatusCode($this->response, $statusCode);

if ($formData instanceof TableNode) {
Expand Down Expand Up @@ -821,6 +822,9 @@ protected function assertAttendeeList(string $identifier, ?TableNode $formData,
if (isset($expectedKeys['callId'])) {
$data['callId'] = (string) $attendee['callId'];
}
if (isset($expectedKeys['status'], $attendee['status'])) {
$data['status'] = (string) $attendee['status'];
}
if (isset($expectedKeys['sessionIds'])) {
$sessionIds = '[';
foreach ($attendee['sessionIds'] as $sessionId) {
Expand Down Expand Up @@ -898,6 +902,10 @@ protected function assertAttendeeList(string $identifier, ?TableNode $formData,
if (isset($attendee['actorType']) && $attendee['actorType'] === 'phones') {
$attendee['participantType'] = (string)$this->mapParticipantTypeTestInput($attendee['participantType']);
}

if (isset($attendee['status']) && $attendee['status'] === 'ABSENT') {
unset($attendee['status']);
}
return $attendee;
}, $formData->getHash(), $result);
$expected = array_filter($expected);
Expand Down
40 changes: 40 additions & 0 deletions tests/integration/features/federation/user-statuses.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Feature: federation/user-statuses

Background:
Given using server "REMOTE"
And user "participant2" exists
And user "participant3" exists
And the following "spreed" app config is set
| federation_enabled | yes |
And using server "LOCAL"
And user "participant1" exists
And the following "spreed" app config is set
| federation_enabled | yes |

Scenario: User statuses are added to the participant request in federated conversations
Given user "participant1" creates room "room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds federated_user "participant2@REMOTE" to room "room" with 200 (v4)
And user "participant1" adds federated_user "participant3@REMOTE" to room "room" with 200 (v4)
And using server "REMOTE"
And user "participant2" has the following invitations (v1)
| remoteServerUrl | remoteToken | state | inviterCloudId | inviterDisplayName |
| LOCAL | room | 0 | participant1@http://localhost:8080 | participant1-displayname |
And user "participant2" accepts invite to room "room" of server "LOCAL" with 200 (v1)
| id | name | type | remoteServer | remoteToken |
| LOCAL::room | room | 2 | LOCAL | room |
Then user "participant2" set status to "away" with 200 (v1)
And user "participant3" has the following invitations (v1)
| remoteServerUrl | remoteToken | state | inviterCloudId | inviterDisplayName |
| LOCAL | room | 0 | participant1@http://localhost:8080 | participant1-displayname |
And user "participant3" accepts invite to room "room" of server "LOCAL" with 200 (v1)
| id | name | type | remoteServer | remoteToken |
| LOCAL::room | room | 2 | LOCAL | room |
Then user "participant3" set status to "dnd" with 200 (v1)
And user "participant2" is participant of room "LOCAL::room" (v4)
And user "participant2" sees the following attendees with status in room "LOCAL::room" with 200 (v4)
| actorType | actorId | participantType | status |
| federated_users | participant1@{$LOCAL_URL} | 1 | ABSENT |
| users | participant2 | 3 | away |
| users | participant3 | 3 | dnd |