Skip to content

Commit

Permalink
feat(federation): Add endpoint to get (remote) capabilities of a conv…
Browse files Browse the repository at this point in the history
…ersation

Signed-off-by: Joas Schilling <coding@schilljs.com>
  • Loading branch information
nickvergessen committed Feb 21, 2024
1 parent db5c23a commit 155ab5c
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 38 deletions.
2 changes: 2 additions & 0 deletions appinfo/routes/routesRoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,7 @@
['name' => 'Room#setRecordingConsent', 'url' => '/api/{apiVersion}/room/{token}/recording-consent', 'verb' => 'PUT', 'requirements' => $requirementsWithToken],
/** @see \OCA\Talk\Controller\RoomController::setMessageExpiration() */
['name' => 'Room#setMessageExpiration', 'url' => '/api/{apiVersion}/room/{token}/message-expiration', 'verb' => 'POST', 'requirements' => $requirementsWithToken],
/** @see \OCA\Talk\Controller\RoomController::getCapabilities() */
['name' => 'Room#getCapabilities', 'url' => '/api/{apiVersion}/room/{token}/capabilities', 'verb' => 'GET', 'requirements' => $requirementsWithToken],
],
];
42 changes: 4 additions & 38 deletions lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
use OCP\Translation\ITranslationManager;
use OCP\Util;

/**
* @psalm-import-type TalkCapabilities from ResponseDefinitions
*/
class Capabilities implements IPublicCapability {
protected ICache $talkCache;

Expand All @@ -55,44 +58,7 @@ public function __construct(

/**
* @return array{
* spreed: array{
* features: string[],
* config: array{
* attachments: array{
* allowed: bool,
* folder?: string,
* },
* call: array{
* enabled: bool,
* breakout-rooms: bool,
* recording: bool,
* recording-consent: int,
* supported-reactions: string[],
* predefined-backgrounds: string[],
* can-upload-background: bool,
* sip-enabled: bool,
* sip-dialout-enabled: bool,
* can-enable-sip: bool,
* },
* chat: array{
* max-length: int,
* read-privacy: int,
* has-translation-providers: bool,
* typing-privacy: int,
* },
* conversations: array{
* can-create: bool,
* },
* previews: array{
* max-gif-size: int,
* },
* signaling: array{
* session-ping-limit: int,
* hello-v2-token-key?: string,
* },
* },
* version: string,
* },
* spreed: TalkCapabilities,
* }|array<empty>
*/
public function getCapabilities(): array {
Expand Down
26 changes: 26 additions & 0 deletions lib/Controller/RoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

namespace OCA\Talk\Controller;

use OCA\Talk\Capabilities;
use OCA\Talk\Config;
use OCA\Talk\Events\AAttendeeRemovedEvent;
use OCA\Talk\Events\BeforeRoomsFetchEvent;
Expand Down Expand Up @@ -89,6 +90,7 @@
use Psr\Log\LoggerInterface;

/**
* @psalm-import-type TalkCapabilities from ResponseDefinitions
* @psalm-import-type TalkParticipant from ResponseDefinitions
* @psalm-import-type TalkRoom from ResponseDefinitions
*/
Expand Down Expand Up @@ -122,6 +124,7 @@ public function __construct(
protected IThrottler $throttler,
protected LoggerInterface $logger,
protected Authenticator $federationAuthenticator,
protected Capabilities $capabilities,
) {
parent::__construct($appName, $request);
}
Expand Down Expand Up @@ -2148,4 +2151,27 @@ public function setMessageExpiration(int $seconds): DataResponse {

return new DataResponse();
}

/**
* Get capabilities for a room
*
* @return DataResponse<Http::STATUS_OK, TalkCapabilities|array<empty>, array{X-Nextcloud-Talk-Hash: string}>
*
* 200: Get capabilities successfully
*/
#[FederationSupported]
#[PublicPage]
#[RequireParticipant]
public function getCapabilities(): DataResponse {
if ($this->room->getRemoteServer()) {
/** @var \OCA\Talk\Federation\Proxy\TalkV1\Controller\RoomController $proxy */
$proxy = \OCP\Server::get(\OCA\Talk\Federation\Proxy\TalkV1\Controller\RoomController::class);
return $proxy->getCapabilities($this->room, $this->participant);
}

$capabilities = $this->capabilities->getCapabilities();
return new DataResponse($capabilities['spreed'] ?? [], Http::STATUS_OK, [
'X-Nextcloud-Talk-Hash' => sha1(json_encode($capabilities)),
]);
}
}
33 changes: 33 additions & 0 deletions lib/Federation/Proxy/TalkV1/Controller/RoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use OCP\AppFramework\Http\DataResponse;

/**
* @psalm-import-type TalkCapabilities from ResponseDefinitions
* @psalm-import-type TalkParticipant from ResponseDefinitions
* @psalm-import-type TalkRoom from ResponseDefinitions
*/
Expand Down Expand Up @@ -88,4 +89,36 @@ public function getParticipants(Room $room, Participant $participant, bool $incl

return new DataResponse($data, Http::STATUS_OK, $headers);
}

/**
* @return DataResponse<Http::STATUS_OK, TalkCapabilities|array<empty>, array{X-Nextcloud-Talk-Hash: string}>
* @throws CannotReachRemoteException
* @throws RemoteClientException
*
* 200: Get capabilities successfully
*/
public function getCapabilities(Room $room, Participant $participant): DataResponse {
$proxy = $this->proxy->get(
$participant->getAttendee()->getInvitedCloudId(),
$participant->getAttendee()->getAccessToken(),
$room->getRemoteServer() . '/ocs/v2.php/apps/spreed/api/v4/room/' . $room->getRemoteToken() . '/capabilities',
);

try {
$content = $proxy->getBody();
$responseData = json_decode($content, true, flags: JSON_THROW_ON_ERROR);
if (!is_array($responseData)) {
throw new \RuntimeException('JSON response is not an array');
}
} catch (\Throwable $e) {
throw new CannotReachRemoteException('Error parsing JSON response', $e->getCode(), $e);
}

/** @var TalkCapabilities|array<empty> $data */
$data = $responseData['ocs']['data'] ?? [];

$headers = ['X-Nextcloud-Talk-Hash' => $proxy->getHeader('X-Nextcloud-Talk-Hash')];

return new DataResponse($data, Http::STATUS_OK, $headers);
}
}
39 changes: 39 additions & 0 deletions lib/ResponseDefinitions.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,45 @@
* turnservers: array{urls: string[], username: string, credential: mixed}[],
* userId: ?string,
* }
*
* @psalm-type TalkCapabilities = array{
* features: string[],
* config: array{
* attachments: array{
* allowed: bool,
* folder?: string,
* },
* call: array{
* enabled: bool,
* breakout-rooms: bool,
* recording: bool,
* recording-consent: int,
* supported-reactions: string[],
* predefined-backgrounds: string[],
* can-upload-background: bool,
* sip-enabled: bool,
* sip-dialout-enabled: bool,
* can-enable-sip: bool,
* },
* chat: array{
* max-length: int,
* read-privacy: int,
* has-translation-providers: bool,
* typing-privacy: int,
* },
* conversations: array{
* can-create: bool,
* },
* previews: array{
* max-gif-size: int,
* },
* signaling: array{
* session-ping-limit: int,
* hello-v2-token-key?: string,
* },
* },
* version: string,
* }
*/
class ResponseDefinitions {
}

0 comments on commit 155ab5c

Please sign in to comment.