Skip to content

Commit

Permalink
feat(federation): Add capabilities for the federation feature and con…
Browse files Browse the repository at this point in the history
…figs

Signed-off-by: Joas Schilling <coding@schilljs.com>
  • Loading branch information
nickvergessen committed Mar 6, 2024
1 parent b575675 commit d79e791
Show file tree
Hide file tree
Showing 29 changed files with 365 additions and 10 deletions.
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 basic chatting is enabled
* `config => federation => incoming` - Boolean, whether users are allowed to be invited into federated conversations on other servers
* `config => federation => outgoing` - Boolean, whether users are allowed to invited federated users of other servers into conversations
* `config => federation => 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
18 changes: 18 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' => false,
'outgoing' => false,
'trusted-servers' => true,
],
'previews' => [
'max-gif-size' => (int)$this->serverConfig->getAppValue('spreed', 'max-gif-size', '3145728'),
],
Expand All @@ -173,6 +182,15 @@ public function getCapabilities(): array {
'version' => $this->appManager->getAppVersion('spreed'),
];

if ($this->talkConfig->isFederationEnabled() && $this->talkConfig->isFederationEnabledForUserId($user)) {
$capabilities['config']['federation'] = [
'enabled' => true,
'incoming' => $this->appConfig->getAppValueBool('federation_incoming_enabled', true),
'outgoing' => $this->appConfig->getAppValueBool('federation_outgoing_enabled', true),
'trusted-servers' => $this->appConfig->getAppValueBool('federation_only_trusted_servers'),
];
}

if ($this->serverConfig->getAppValue('core', 'backgroundjobs_mode', 'ajax') === 'cron') {
$capabilities['features'][] = 'message-expiration';
}
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: bool,
* outgoing: bool,
* 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",
"outgoing",
"trusted-servers"
],
"properties": {
"enabled": {
"type": "boolean"
},
"incoming": {
"type": "boolean"
},
"outgoing": {
"type": "boolean"
},
"trusted-servers": {
"type": "boolean"
}
}
},
"previews": {
"type": "object",
"required": [
Expand Down
24 changes: 24 additions & 0 deletions openapi-backend-recording.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"call",
"chat",
"conversations",
"federation",
"previews",
"signaling"
],
Expand Down Expand Up @@ -150,6 +151,29 @@
}
}
},
"federation": {
"type": "object",
"required": [
"enabled",
"incoming",
"outgoing",
"trusted-servers"
],
"properties": {
"enabled": {
"type": "boolean"
},
"incoming": {
"type": "boolean"
},
"outgoing": {
"type": "boolean"
},
"trusted-servers": {
"type": "boolean"
}
}
},
"previews": {
"type": "object",
"required": [
Expand Down
Loading

0 comments on commit d79e791

Please sign in to comment.