summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2024-02-21 15:09:15 +0100
committerJoas Schilling <coding@schilljs.com>2024-02-23 14:33:07 +0100
commit61a9a2170899fcd643c1615b7f6d6d4a2a867df6 (patch)
tree95f26b6428615b24eaea7755c794ea79e95a8a49
parent821f6001ba1f3e2d8f6fd3b4df3833b944268b75 (diff)
feat(federation): Add endpoint to get (remote) capabilities of a conversation
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r--appinfo/routes/routesRoomController.php2
-rw-r--r--lib/Capabilities.php42
-rw-r--r--lib/Controller/RoomController.php26
-rw-r--r--lib/Federation/Proxy/TalkV1/Controller/RoomController.php33
-rw-r--r--lib/ResponseDefinitions.php39
5 files changed, 104 insertions, 38 deletions
diff --git a/appinfo/routes/routesRoomController.php b/appinfo/routes/routesRoomController.php
index 776a81ab8..1da2316a8 100644
--- a/appinfo/routes/routesRoomController.php
+++ b/appinfo/routes/routesRoomController.php
@@ -120,5 +120,7 @@ return [
['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],
],
];
diff --git a/lib/Capabilities.php b/lib/Capabilities.php
index 83f01d33c..cb78f226d 100644
--- a/lib/Capabilities.php
+++ b/lib/Capabilities.php
@@ -38,6 +38,9 @@ use OCP\IUserSession;
use OCP\Translation\ITranslationManager;
use OCP\Util;
+/**
+ * @psalm-import-type TalkCapabilities from ResponseDefinitions
+ */
class Capabilities implements IPublicCapability {
protected ICache $talkCache;
@@ -55,44 +58,7 @@ class Capabilities implements IPublicCapability {
/**
* @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 {
diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php
index 8645e29a5..a4c1f6d28 100644
--- a/lib/Controller/RoomController.php
+++ b/lib/Controller/RoomController.php
@@ -28,6 +28,7 @@ declare(strict_types=1);
namespace OCA\Talk\Controller;
+use OCA\Talk\Capabilities;
use OCA\Talk\Config;
use OCA\Talk\Events\AAttendeeRemovedEvent;
use OCA\Talk\Events\BeforeRoomsFetchEvent;
@@ -89,6 +90,7 @@ use OCP\UserStatus\IUserStatus;
use Psr\Log\LoggerInterface;
/**
+ * @psalm-import-type TalkCapabilities from ResponseDefinitions
* @psalm-import-type TalkParticipant from ResponseDefinitions
* @psalm-import-type TalkRoom from ResponseDefinitions
*/
@@ -122,6 +124,7 @@ class RoomController extends AEnvironmentAwareController {
protected IThrottler $throttler,
protected LoggerInterface $logger,
protected Authenticator $federationAuthenticator,
+ protected Capabilities $capabilities,
) {
parent::__construct($appName, $request);
}
@@ -2148,4 +2151,27 @@ class RoomController extends AEnvironmentAwareController {
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)),
+ ]);
+ }
}
diff --git a/lib/Federation/Proxy/TalkV1/Controller/RoomController.php b/lib/Federation/Proxy/TalkV1/Controller/RoomController.php
index 0be69af8f..55184f37f 100644
--- a/lib/Federation/Proxy/TalkV1/Controller/RoomController.php
+++ b/lib/Federation/Proxy/TalkV1/Controller/RoomController.php
@@ -36,6 +36,7 @@ use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
/**
+ * @psalm-import-type TalkCapabilities from ResponseDefinitions
* @psalm-import-type TalkParticipant from ResponseDefinitions
* @psalm-import-type TalkRoom from ResponseDefinitions
*/
@@ -88,4 +89,36 @@ class RoomController {
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);
+ }
}
diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php
index 9c553add2..de7825fd8 100644
--- a/lib/ResponseDefinitions.php
+++ b/lib/ResponseDefinitions.php
@@ -265,6 +265,45 @@ namespace OCA\Talk;
* 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 {
}