diff options
29 files changed, 366 insertions, 10 deletions
diff --git a/docs/avatar.md b/docs/avatar.md index b63b8e145..7fc908c44 100644 --- a/docs/avatar.md +++ b/docs/avatar.md @@ -70,6 +70,7 @@ ## Get conversations avatar (binary) * Required capability: `avatar` +* Federation capability: `federation-v1` * Method: `GET` * Endpoint: `/room/{token}/avatar` @@ -82,6 +83,7 @@ ## Get dark mode conversations avatar (binary) * Required capability: `avatar` +* Federation capability: `federation-v1` * Method: `GET` * Endpoint: `/room/{token}/avatar/dark` diff --git a/docs/capabilities.md b/docs/capabilities.md index c0d746cd7..1f8987a1e 100644 --- a/docs/capabilities.md +++ b/docs/capabilities.md @@ -144,3 +144,8 @@ * `edit-messages` - Whether messages can be edited (restricted to 24 hours after posting) * `silent-send-state` - Whether messages contain a flag that they were sent silently * `chat-read-last` - Whether chat can be marked read without giving a message ID (will fall back to the conversations last message ID) +* `federation-v1` - Whether basic chatting is possible with federation +* `config => federation => enabled` - Boolean, whether federation is enabled on instance +* `config => federation => incoming-enabled` - Boolean, whether users are allowed to be invited into federated conversations on other servers +* `config => federation => outgoing-enabled` - Boolean, whether users are allowed to invited federated users of other servers into conversations +* `config => federation => only-trusted-servers` - Boolean, whether federation invites are limited to trusted servers diff --git a/docs/chat.md b/docs/chat.md index 358e0b976..4a02511cf 100644 --- a/docs/chat.md +++ b/docs/chat.md @@ -10,6 +10,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`: since Nextcloud 13 It is therefor recommended to use `format=json` or send the `Accept: application/json` header, to receive a JSON response. +* Federation capability: `federation-v1` * Method: `GET` * Endpoint: `/chat/{token}` * Data: @@ -90,6 +91,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`: since Nextcloud 13 to receive a JSON response. * Required capability: `chat-get-context` +* Federation capability: `federation-v1` * Method: `GET` * Endpoint: `/chat/{token}/{messageId}/context` * Data: @@ -115,6 +117,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`: since Nextcloud 13 ## Sending a new chat message +* Federation capability: `federation-v1` * Method: `POST` * Endpoint: `/chat/{token}` * Data: @@ -284,6 +287,7 @@ See [OCP\RichObjectStrings\Definitions](https://github.com/nextcloud/server/blob ## Deleting a chat message * Required capability: `delete-messages` - `rich-object-delete` indicates if shared objects can be deleted from the chat +* Federation capability: `federation-v1` * Method: `DELETE` * Endpoint: `/chat/{token}/{messageId}` @@ -313,6 +317,7 @@ See [OCP\RichObjectStrings\Definitions](https://github.com/nextcloud/server/blob ## Editing a chat message * Required capability: `edit-messages` +* Federation capability: `federation-v1` * Method: `PUT` * Endpoint: `/chat/{token}/{messageId}` * Data: @@ -412,6 +417,7 @@ See [OCP\RichObjectStrings\Definitions](https://github.com/nextcloud/server/blob ## Mark chat as read * Required capability: `chat-read-marker` +* Federation capability: `federation-v1` * Method: `POST` * Endpoint: `/chat/{token}/read` * Data: @@ -439,6 +445,7 @@ See [OCP\RichObjectStrings\Definitions](https://github.com/nextcloud/server/blob ## Mark chat as unread * Required capability: `chat-unread` +* Federation capability: `federation-v1` * Method: `DELETE` * Endpoint: `/chat/{token}/read` @@ -460,6 +467,7 @@ See [OCP\RichObjectStrings\Definitions](https://github.com/nextcloud/server/blob ## Get mention autocomplete suggestions +* Federation capability: `federation-v1` * Method: `GET` * Endpoint: `/chat/{token}/mentions` * Data: diff --git a/docs/conversation.md b/docs/conversation.md index a043aa9d5..bcb13ce24 100644 --- a/docs/conversation.md +++ b/docs/conversation.md @@ -365,6 +365,7 @@ Get all (for moderators and in case of "free selection") or the assigned breakou ## Add conversation to favorites * Required capability: `favorites` +* Federation capability: `federation-v1` * Method: `POST` * Endpoint: `/room/{token}/favorite` @@ -377,6 +378,7 @@ Get all (for moderators and in case of "free selection") or the assigned breakou ## Remove conversation from favorites * Required capability: `favorites` +* Federation capability: `federation-v1` * Method: `DELETE` * Endpoint: `/room/{token}/favorite` @@ -389,6 +391,7 @@ Get all (for moderators and in case of "free selection") or the assigned breakou ## Set notification level * Required capability: `notification-levels` +* Federation capability: `federation-v1` * Method: `POST` * Endpoint: `/room/{token}/notify` * Data: @@ -478,3 +481,23 @@ Get all (for moderators and in case of "free selection") or the assigned breakou + `400 Bad Request` When the conversation is a breakout room + `403 Forbidden` When the current user is not a moderator/owner or the conversation is not a public conversation + `404 Not Found` When the conversation could not be found for the participant + +## Get conversation capabilities + +* Required capability: `federation-v1` +* Method: `GET` +* Endpoint: `/room/{token}/capabilities` + +* Response: + - Status code: + + `200 OK` Get capabilities + + `404 Not Found` When the conversation could not be found for the participant + + - Header: + +| field | type | Description | +|-------------------------------|--------|--------------------------------------------------------------------------------------------| +| `X-Nextcloud-Talk-Proxy-Hash` | string | Sha1 value over the capabilities in case the conversation is hosted **on another server**. | +| `X-Nextcloud-Talk-Hash` | string | Sha1 value over the capabilities in case the conversation is hosted **on this server**. | + + - Data: Server capabilities limited to the `spreed` sub-array or an empty array in case the app is disabled (for the user) diff --git a/docs/global.md b/docs/global.md index a1e728a76..6ae8ff84a 100644 --- a/docs/global.md +++ b/docs/global.md @@ -40,3 +40,19 @@ From time to time it is unavoidable to break compatibility. In such cases we try + `426 Upgrade Required` - Body: + `ocs.meta.message` contains the minimum required version of the used client + +## Federation - Not supported + +Endpoints without a "Federation capability: `federation-vX`" will return a `406 Not Acceptable` status code, when called with tokens that actually refer to a so-called proxy conversation on the local server. + +* Response: + - Status code: + + `406 Not Acceptable` + +## Federation - Remote error + +When a request is performed on a proxy conversation and the host can not be reached `422 Unprocessable Content` will be returned. The only exception will be leaving the room, where the request will still execute it's part locally so the user is no longer bothered. A background job will be queued to retry informing the remote server about the leave automatically. + +* Response: + - Status code: + + `422 Unprocessable Content` diff --git a/docs/participant.md b/docs/participant.md index d46380863..157f420fa 100644 --- a/docs/participant.md +++ b/docs/participant.md @@ -7,6 +7,7 @@ ## Get list of participants in a conversation +* Federation capability: `federation-v1` * Method: `GET` * Endpoint: `/room/{token}/participants` * Data: @@ -108,6 +109,7 @@ ## Remove yourself from a conversation +* Federation capability: `federation-v1` * Method: `DELETE` * Endpoint: `/room/{token}/participants/self` @@ -119,6 +121,7 @@ ## Join a conversation (available for call and chat) +* Federation capability: `federation-v1` * Method: `POST` * Endpoint: `/room/{token}/participants/active` * Data: @@ -165,6 +168,7 @@ ## Set session state * Required capability: `session-state` +* Federation capability: `federation-v1` * Method: `PUT` * Endpoint: `/room/{token}/participants/state` @@ -176,6 +180,7 @@ ## Leave a conversation (not available for call and chat anymore) +* Federation capability: `federation-v1` * Method: `DELETE` * Endpoint: `/room/{token}/participants/active` diff --git a/docs/reaction.md b/docs/reaction.md index 0185886ff..1373c249f 100644 --- a/docs/reaction.md +++ b/docs/reaction.md @@ -5,6 +5,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`: since Nextcloud 24 ## React to a message * Required capability: `reactions` +* Federation capability: `federation-v1` * Method: `POST` * Endpoint: `/reaction/{token}/{messageId}` * Data: @@ -33,6 +34,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`: since Nextcloud 24 ## Delete a reaction * Required capability: `reactions` +* Federation capability: `federation-v1` * Method: `DELETE` * Endpoint: `/reaction/{token}/{messageId}` * Data: @@ -60,6 +62,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`: since Nextcloud 24 ## Retrieve reactions of a message by type * Required capability: `reactions` +* Federation capability: `federation-v1` * Method: `GET` * Endpoint: `/reaction/{token}/{messageId}` * Data: diff --git a/lib/Capabilities.php b/lib/Capabilities.php index f7648cacb..2f288ff8f 100644 --- a/lib/Capabilities.php +++ b/lib/Capabilities.php @@ -28,6 +28,7 @@ namespace OCA\Talk; use OCA\Talk\Chat\ChatManager; use OCP\App\IAppManager; +use OCP\AppFramework\Services\IAppConfig; use OCP\Capabilities\IPublicCapability; use OCP\Comments\ICommentsManager; use OCP\ICache; @@ -47,6 +48,7 @@ class Capabilities implements IPublicCapability { public function __construct( protected IConfig $serverConfig, protected Config $talkConfig, + protected IAppConfig $appConfig, protected ICommentsManager $commentsManager, protected IUserSession $userSession, protected IAppManager $appManager, @@ -140,6 +142,7 @@ class Capabilities implements IPublicCapability { 'edit-messages', 'silent-send-state', 'chat-read-last', + 'federation-v1', ], 'config' => [ 'attachments' => [ @@ -163,6 +166,12 @@ class Capabilities implements IPublicCapability { 'conversations' => [ 'can-create' => $user instanceof IUser && !$this->talkConfig->isNotAllowedToCreateConversations($user) ], + 'federation' => [ + 'enabled' => false, + 'incoming-enabled' => false, + 'outgoing-enabled' => false, + 'only-trusted-servers' => true, + ], 'previews' => [ 'max-gif-size' => (int)$this->serverConfig->getAppValue('spreed', 'max-gif-size', '3145728'), ], @@ -173,6 +182,7 @@ class Capabilities implements IPublicCapability { 'version' => $this->appManager->getAppVersion('spreed'), ]; + if ($this->serverConfig->getAppValue('core', 'backgroundjobs_mode', 'ajax') === 'cron') { $capabilities['features'][] = 'message-expiration'; } @@ -182,6 +192,15 @@ class Capabilities implements IPublicCapability { } if ($user instanceof IUser) { + if ($this->talkConfig->isFederationEnabled() && $this->talkConfig->isFederationEnabledForUserId($user)) { + $capabilities['config']['federation'] = [ + 'enabled' => true, + 'incoming-enabled' => $this->appConfig->getAppValueBool('federation_incoming_enabled', true), + 'outgoing-enabled' => $this->appConfig->getAppValueBool('federation_outgoing_enabled', true), + 'only-trusted-servers' => $this->appConfig->getAppValueBool('federation_only_trusted_servers'), + ]; + } + $capabilities['config']['attachments']['folder'] = $this->talkConfig->getAttachmentFolder($user->getUID()); $capabilities['config']['chat']['read-privacy'] = $this->talkConfig->getUserReadPrivacy($user->getUID()); $capabilities['config']['chat']['typing-privacy'] = $this->talkConfig->getUserTypingPrivacy($user->getUID()); diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 1f257d822..522466350 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -308,6 +308,12 @@ namespace OCA\Talk; * conversations: array{ * can-create: bool, * }, + * federation: array{ + * enabled: bool, + * incoming-enabled: bool, + * outgoing-enabled: bool, + * only-trusted-servers: bool, + * }, * previews: array{ * max-gif-size: int, * }, diff --git a/lib/Settings/Admin/AdminSettings.php b/lib/Settings/Admin/AdminSettings.php index 2d3893a4d..ddffc99a9 100644 --- a/lib/Settings/Admin/AdminSettings.php +++ b/lib/Settings/Admin/AdminSettings.php @@ -31,6 +31,7 @@ use OCA\Talk\Participant; use OCA\Talk\Room; use OCA\Talk\Service\CommandService; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Services\IInitialState; use OCP\ICacheFactory; use OCP\IConfig; @@ -49,6 +50,7 @@ class AdminSettings implements ISettings { public function __construct( private Config $talkConfig, private IConfig $ |