Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(federation): Add capabilities for the federation feature and con… #11730

Merged
merged 1 commit into from
Mar 6, 2024
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
2 changes: 2 additions & 0 deletions docs/avatar.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
## Get conversations avatar (binary)

* Required capability: `avatar`
* Federation capability: `federation-v1`
* Method: `GET`
* Endpoint: `/room/{token}/avatar`

Expand All @@ -82,6 +83,7 @@
## Get dark mode conversations avatar (binary)

* Required capability: `avatar`
* Federation capability: `federation-v1`
* Method: `GET`
* Endpoint: `/room/{token}/avatar/dark`

Expand Down
5 changes: 5 additions & 0 deletions docs/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 8 additions & 0 deletions docs/chat.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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}`

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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`

Expand All @@ -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:
Expand Down
23 changes: 23 additions & 0 deletions docs/conversation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand All @@ -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`

Expand All @@ -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:
Expand Down Expand Up @@ -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)
16 changes: 16 additions & 0 deletions docs/global.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
5 changes: 5 additions & 0 deletions docs/participant.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

## Get list of participants in a conversation

* Federation capability: `federation-v1`
* Method: `GET`
* Endpoint: `/room/{token}/participants`
* Data:
Expand Down Expand Up @@ -108,6 +109,7 @@

## Remove yourself from a conversation

* Federation capability: `federation-v1`
* Method: `DELETE`
* Endpoint: `/room/{token}/participants/self`

Expand All @@ -119,6 +121,7 @@

## Join a conversation (available for call and chat)

* Federation capability: `federation-v1`
* Method: `POST`
* Endpoint: `/room/{token}/participants/active`
* Data:
Expand Down Expand Up @@ -165,6 +168,7 @@
## Set session state

* Required capability: `session-state`
* Federation capability: `federation-v1`
* Method: `PUT`
* Endpoint: `/room/{token}/participants/state`

Expand All @@ -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`

Expand Down
3 changes: 3 additions & 0 deletions docs/reaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
19 changes: 19 additions & 0 deletions lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

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;
Expand All @@ -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,
Expand Down Expand Up @@ -140,6 +142,7 @@ public function getCapabilities(): array {
'edit-messages',
'silent-send-state',
'chat-read-last',
'federation-v1',
],
'config' => [
'attachments' => [
Expand All @@ -163,6 +166,12 @@ public function getCapabilities(): array {
'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'),
],
Expand All @@ -173,6 +182,7 @@ public function getCapabilities(): array {
'version' => $this->appManager->getAppVersion('spreed'),
];


if ($this->serverConfig->getAppValue('core', 'backgroundjobs_mode', 'ajax') === 'cron') {
$capabilities['features'][] = 'message-expiration';
}
Expand All @@ -182,6 +192,15 @@ public function getCapabilities(): array {
}

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());
Expand Down
6 changes: 6 additions & 0 deletions lib/ResponseDefinitions.php
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,12 @@
* 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,
* },
Expand Down
12 changes: 7 additions & 5 deletions lib/Settings/Admin/AdminSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
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;
Expand All @@ -49,6 +50,7 @@ class AdminSettings implements ISettings {
public function __construct(
private Config $talkConfig,
private IConfig $serverConfig,
private IAppConfig $appConfig,
private CommandService $commandService,
private IInitialState $initialState,
private ICacheFactory $memcacheFactory,
Expand Down Expand Up @@ -111,11 +113,11 @@ protected function initCommands(): void {
}

protected function initFederation(): void {
$this->initialState->provideInitialState('federation_enabled', $this->serverConfig->getAppValue('spreed', 'federation_enabled', 'no'));
$this->initialState->provideInitialState('federation_incoming_enabled', $this->serverConfig->getAppValue('spreed', 'federation_incoming_enabled', '1'));
$this->initialState->provideInitialState('federation_outgoing_enabled', $this->serverConfig->getAppValue('spreed', 'federation_outgoing_enabled', '1'));
$this->initialState->provideInitialState('federation_only_trusted_servers', $this->serverConfig->getAppValue('spreed', 'federation_only_trusted_servers', '0'));
$this->initialState->provideInitialState('federation_allowed_groups', $this->serverConfig->getAppValue('spreed', 'federation_allowed_groups', '[]'));
$this->initialState->provideInitialState('federation_enabled', $this->talkConfig->isFederationEnabled());
$this->initialState->provideInitialState('federation_incoming_enabled', $this->appConfig->getAppValueBool('federation_incoming_enabled', true));
$this->initialState->provideInitialState('federation_outgoing_enabled', $this->appConfig->getAppValueBool('federation_outgoing_enabled', true));
$this->initialState->provideInitialState('federation_only_trusted_servers', $this->appConfig->getAppValueBool('federation_only_trusted_servers'));
$this->initialState->provideInitialState('federation_allowed_groups', $this->appConfig->getAppValueArray('federation_allowed_groups'));
}

protected function initMatterbridge(): void {
Expand Down
24 changes: 24 additions & 0 deletions openapi-administration.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"call",
"chat",
"conversations",
"federation",
"previews",
"signaling"
],
Expand Down Expand Up @@ -217,6 +218,29 @@
}
}
},
"federation": {
"type": "object",
"required": [
"enabled",
"incoming-enabled",
"outgoing-enabled",
"only-trusted-servers"
],
"properties": {
"enabled": {
"type": "boolean"
},
"incoming-enabled": {
"type": "boolean"
},
"outgoing-enabled": {
"type": "boolean"
},
"only-trusted-servers": {
"type": "boolean"
}
}
},
"previews": {
"type": "object",
"required": [
Expand Down
Loading
Loading