diff options
author | Joas Schilling <coding@schilljs.com> | 2024-02-21 15:09:15 +0100 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2024-02-23 14:33:07 +0100 |
commit | 61a9a2170899fcd643c1615b7f6d6d4a2a867df6 (patch) | |
tree | 95f26b6428615b24eaea7755c794ea79e95a8a49 | |
parent | 821f6001ba1f3e2d8f6fd3b4df3833b944268b75 (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.php | 2 | ||||
-rw-r--r-- | lib/Capabilities.php | 42 | ||||
-rw-r--r-- | lib/Controller/RoomController.php | 26 | ||||
-rw-r--r-- | lib/Federation/Proxy/TalkV1/Controller/RoomController.php | 33 | ||||
-rw-r--r-- | lib/ResponseDefinitions.php | 39 |
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 { } |