feat(ban): Contract for banning attendees and IP/ranges

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2024-05-03 09:12:01 +02:00
parent f4cae12357
commit 3cda633a5f
No known key found for this signature in database
GPG key ID: C400AAF20C1BB6FC
12 changed files with 1235 additions and 6 deletions

View file

@ -9,6 +9,7 @@ declare(strict_types=1);
return array_merge_recursive(
include(__DIR__ . '/routes/routesAvatarController.php'),
include(__DIR__ . '/routes/routesBanController.php'),
include(__DIR__ . '/routes/routesBotController.php'),
include(__DIR__ . '/routes/routesBreakoutRoomController.php'),
include(__DIR__ . '/routes/routesCallController.php'),

View file

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
$requirements = [
'apiVersion' => '(v1)',
'token' => '[a-z0-9]{4,30}',
];
return [
'ocs' => [
/** @see \OCA\Talk\Controller\BanController::banActor() */
['name' => 'Ban#banActor', 'url' => '/api/{apiVersion}/ban/{token}', 'verb' => 'POST', 'requirements' => $requirements],
/** @see \OCA\Talk\Controller\BanController::listBans() */
['name' => 'Ban#listBans', 'url' => '/api/{apiVersion}/ban/{token}', 'verb' => 'GET', 'requirements' => $requirements],
/** @see \OCA\Talk\Controller\BanController::unbanActor() */
['name' => 'Ban#unbanActor', 'url' => '/api/{apiVersion}/ban/{token}', 'verb' => 'DELETE', 'requirements' => $requirements],
],
];

View file

@ -149,3 +149,6 @@
* `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
## 20
* `ban-v1` - Whether the API to ban attendees is available

View file

@ -125,6 +125,7 @@ class Capabilities implements IPublicCapability {
'silent-send-state',
'chat-read-last',
'federation-v1',
'ban-v1',
],
'config' => [
'attachments' => [

View file

@ -0,0 +1,123 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Controller;
use OCA\Talk\Middleware\Attribute\RequireModeratorParticipant;
use OCA\Talk\Model\Attendee;
use OCA\Talk\ResponseDefinitions;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest;
/**
* @psalm-import-type TalkBan from ResponseDefinitions
*/
class BanController extends AEnvironmentAwareController {
public function __construct(
string $appName,
IRequest $request,
) {
parent::__construct($appName, $request);
}
/**
* Ban an actor or IP address
*
* Required capability: `ban-v1`
*
* @param 'users'|'groups'|'circles'|'emails'|'federated_users'|'phones'|'ip' $actorType Type of actor to ban, or `ip` when banning a clients remote address
* @psalm-param Attendee::ACTOR_*|'ip' $actorType Type of actor to ban, or `ip` when banning a clients remote address
* @param string $actorId Actor ID or the IP address or range in case of type `ip`
* @param string $internalNote Optional internal note
* @return DataResponse<Http::STATUS_OK, TalkBan, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: string}, array{}>
*
* 200: Ban successfully
* 400: Actor information is invalid
*/
#[PublicPage]
#[RequireModeratorParticipant]
public function banActor(string $actorType, string $actorId, string $internalNote = ''): DataResponse {
if ($actorId === 'wrong') {
return new DataResponse([
'error' => 'actor',
], Http::STATUS_BAD_REQUEST);
}
return new DataResponse(
[
'id' => random_int(1, 1337),
'actorType' => $this->participant->getAttendee()->getActorType(),
'actorId' => $this->participant->getAttendee()->getActorId(),
'bannedType' => $actorType,
'bannedId' => $actorId,
'bannedTime' => time(),
'internalNote' => $internalNote ?: 'Lorem ipsum',
],
Http::STATUS_OK
);
}
/**
* List the bans of a conversation
*
* Required capability: `ban-v1`
*
* @return DataResponse<Http::STATUS_OK, list<TalkBan>, array{}>
*
* 200: List all bans
*/
#[PublicPage]
#[RequireModeratorParticipant]
public function listBans(): DataResponse {
return new DataResponse([
$this->randomBan(Attendee::ACTOR_USERS, 'test'),
$this->randomBan(Attendee::ACTOR_USERS, '123456'),
$this->randomBan(Attendee::ACTOR_FEDERATED_USERS, 'admin@nextcloud.local'),
$this->randomBan('ip', '127.0.0.1'),
$this->randomBan('ip', '127.0.0.1/32'),
$this->randomBan('ip', '127.0.0.0/24'),
$this->randomBan('ip', '::1/24'),
$this->randomBan('ip', '2001:0db8:85a3::/48'),
], Http::STATUS_OK);
}
/**
* Unban an actor or IP address
*
* Required capability: `ban-v1`
*
* @param int $banId ID of the ban to be removed
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
*
* 200: Unban successfully or not found
*/
#[PublicPage]
#[RequireModeratorParticipant]
public function unbanActor(int $banId): DataResponse {
return new DataResponse([], Http::STATUS_OK);
}
/**
* @psalm-return TalkBan
*/
protected function randomBan(string $actorType, string $actorId): array {
return [
'id' => random_int(1, 1337),
'actorType' => $this->participant->getAttendee()->getActorType(),
'actorId' => $this->participant->getAttendee()->getActorId(),
'bannedType' => $actorType,
'bannedId' => $actorId,
'bannedTime' => random_int(1514747958, 1714747958),
'internalNote' => '#NOTE#' . $actorType . '#' . $actorId . '#' . sha1($actorType . $actorId),
];
}
}

View file

@ -1474,7 +1474,7 @@ class RoomController extends AEnvironmentAwareController {
* @param string $token Token of the room
* @param string $password Password of the room
* @param bool $force Create a new session if necessary
* @return DataResponse<Http::STATUS_OK, TalkRoom, array{X-Nextcloud-Talk-Proxy-Hash?: string}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, array<empty>, array{}>|DataResponse<Http::STATUS_CONFLICT, array{sessionId: string, inCall: int, lastPing: int}, array{}>
* @return DataResponse<Http::STATUS_OK, TalkRoom, array{X-Nextcloud-Talk-Proxy-Hash?: string}>|DataResponse<Http::STATUS_FORBIDDEN, array{error: 'ban'|'password'}, array<empty>>|DataResponse<Http::STATUS_NOT_FOUND, array<empty>, array<empty>>|DataResponse<Http::STATUS_CONFLICT, array{sessionId: string, inCall: int, lastPing: int}, array<empty>>
*
* 200: Room joined successfully
* 403: Joining room is not allowed
@ -1512,6 +1512,18 @@ class RoomController extends AEnvironmentAwareController {
return $response;
}
if (strtolower($room->getName()) === 'ban user' && $this->userId === 'banned') {
return new DataResponse([
'error' => 'ban',
], Http::STATUS_FORBIDDEN);
}
if (strtolower($room->getName()) === 'ban guest' && !$this->userId) {
return new DataResponse([
'error' => 'ban',
], Http::STATUS_FORBIDDEN);
}
/** @var Participant|null $previousSession */
$previousParticipant = null;
/** @var Session|null $previousSession */
@ -1585,7 +1597,9 @@ class RoomController extends AEnvironmentAwareController {
$this->throttler->resetDelay($this->request->getRemoteAddress(), 'talkRoomPassword', ['token' => $token, 'action' => 'talkRoomPassword']);
$this->throttler->resetDelay($this->request->getRemoteAddress(), 'talkRoomToken', ['token' => $token, 'action' => 'talkRoomToken']);
} catch (InvalidPasswordException $e) {
$response = new DataResponse([], Http::STATUS_FORBIDDEN);
$response = new DataResponse([
'error' => 'password',
], Http::STATUS_FORBIDDEN);
$response->throttle(['token' => $token, 'action' => 'talkRoomPassword']);
return $response;
} catch (UnauthorizedException $e) {

View file

@ -10,6 +10,16 @@ declare(strict_types=1);
namespace OCA\Talk;
/**
* @psalm-type TalkBan = array{
* id: int,
* actorType: string,
* actorId: string,
* bannedType: string,
* bannedId: string,
* bannedTime: int,
* internalNote: string,
* }
*
* @psalm-type TalkBot = array{
* description: ?string,
* id: int,

View file

@ -20,6 +20,43 @@
}
},
"schemas": {
"Ban": {
"type": "object",
"required": [
"id",
"actorType",
"actorId",
"bannedType",
"bannedId",
"bannedTime",
"internalNote"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"actorType": {
"type": "string"
},
"actorId": {
"type": "string"
},
"bannedType": {
"type": "string"
},
"bannedId": {
"type": "string"
},
"bannedTime": {
"type": "integer",
"format": "int64"
},
"internalNote": {
"type": "string"
}
}
},
"BaseMessage": {
"type": "object",
"required": [
@ -1883,6 +1920,339 @@
}
}
},
"/ocs/v2.php/apps/spreed/api/{apiVersion}/ban/{token}": {
"post": {
"operationId": "ban-ban-actor",
"summary": "Ban an actor or IP address",
"description": "Required capability: `ban-v1`",
"tags": [
"ban"
],
"security": [
{},
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "actorType",
"in": "query",
"description": "Type of actor to ban, or `ip` when banning a clients remote address",
"required": true,
"schema": {
"type": "string",
"enum": [
"users",
"groups",
"circles",
"emails",
"federated_users",
"phones",
"ip"
]
}
},
{
"name": "actorId",
"in": "query",
"description": "Actor ID or the IP address or range in case of type `ip`",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "internalNote",
"in": "query",
"description": "Optional internal note",
"schema": {
"type": "string",
"default": ""
}
},
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v1"
],
"default": "v1"
}
},
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-z0-9]{4,30}$"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Ban successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"$ref": "#/components/schemas/Ban"
}
}
}
}
}
}
}
},
"400": {
"description": "Actor information is invalid",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
},
"get": {
"operationId": "ban-list-bans",
"summary": "List the bans of a conversation",
"description": "Required capability: `ban-v1`",
"tags": [
"ban"
],
"security": [
{},
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v1"
],
"default": "v1"
}
},
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-z0-9]{4,30}$"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "List all bans",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Ban"
}
}
}
}
}
}
}
}
}
}
},
"delete": {
"operationId": "ban-unban-actor",
"summary": "Unban an actor or IP address",
"description": "Required capability: `ban-v1`",
"tags": [
"ban"
],
"security": [
{},
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "banId",
"in": "query",
"description": "ID of the ban to be removed",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v1"
],
"default": "v1"
}
},
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-z0-9]{4,30}$"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Unban successfully or not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
}
},
"/ocs/v2.php/apps/spreed/api/{apiVersion}/bot/{token}": {
"get": {
"operationId": "bot-list-bots",
@ -12399,7 +12769,21 @@
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
"data": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string",
"enum": [
"ban",
"password"
]
}
}
}
}
}
}

View file

@ -20,6 +20,43 @@
}
},
"schemas": {
"Ban": {
"type": "object",
"required": [
"id",
"actorType",
"actorId",
"bannedType",
"bannedId",
"bannedTime",
"internalNote"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"actorType": {
"type": "string"
},
"actorId": {
"type": "string"
},
"bannedType": {
"type": "string"
},
"bannedId": {
"type": "string"
},
"bannedTime": {
"type": "integer",
"format": "int64"
},
"internalNote": {
"type": "string"
}
}
},
"BaseMessage": {
"type": "object",
"required": [
@ -1770,6 +1807,339 @@
}
}
},
"/ocs/v2.php/apps/spreed/api/{apiVersion}/ban/{token}": {
"post": {
"operationId": "ban-ban-actor",
"summary": "Ban an actor or IP address",
"description": "Required capability: `ban-v1`",
"tags": [
"ban"
],
"security": [
{},
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "actorType",
"in": "query",
"description": "Type of actor to ban, or `ip` when banning a clients remote address",
"required": true,
"schema": {
"type": "string",
"enum": [
"users",
"groups",
"circles",
"emails",
"federated_users",
"phones",
"ip"
]
}
},
{
"name": "actorId",
"in": "query",
"description": "Actor ID or the IP address or range in case of type `ip`",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "internalNote",
"in": "query",
"description": "Optional internal note",
"schema": {
"type": "string",
"default": ""
}
},
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v1"
],
"default": "v1"
}
},
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-z0-9]{4,30}$"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Ban successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"$ref": "#/components/schemas/Ban"
}
}
}
}
}
}
}
},
"400": {
"description": "Actor information is invalid",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
},
"get": {
"operationId": "ban-list-bans",
"summary": "List the bans of a conversation",
"description": "Required capability: `ban-v1`",
"tags": [
"ban"
],
"security": [
{},
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v1"
],
"default": "v1"
}
},
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-z0-9]{4,30}$"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "List all bans",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Ban"
}
}
}
}
}
}
}
}
}
}
},
"delete": {
"operationId": "ban-unban-actor",
"summary": "Unban an actor or IP address",
"description": "Required capability: `ban-v1`",
"tags": [
"ban"
],
"security": [
{},
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "banId",
"in": "query",
"description": "ID of the ban to be removed",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v1"
],
"default": "v1"
}
},
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^[a-z0-9]{4,30}$"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Unban successfully or not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
}
},
"/ocs/v2.php/apps/spreed/api/{apiVersion}/bot/{token}": {
"get": {
"operationId": "bot-list-bots",
@ -12509,7 +12879,21 @@
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
"data": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string",
"enum": [
"ban",
"password"
]
}
}
}
}
}
}

View file

@ -26,6 +26,23 @@ export type paths = {
/** Get the dark mode avatar of a room */
get: operations["avatar-get-avatar-dark"];
};
"/ocs/v2.php/apps/spreed/api/{apiVersion}/ban/{token}": {
/**
* List the bans of a conversation
* @description Required capability: `ban-v1`
*/
get: operations["ban-list-bans"];
/**
* Ban an actor or IP address
* @description Required capability: `ban-v1`
*/
post: operations["ban-ban-actor"];
/**
* Unban an actor or IP address
* @description Required capability: `ban-v1`
*/
delete: operations["ban-unban-actor"];
};
"/ocs/v2.php/apps/spreed/api/{apiVersion}/bot/{token}": {
/** List bots */
get: operations["bot-list-bots"];
@ -532,6 +549,17 @@ export type webhooks = Record<string, never>;
export type components = {
schemas: {
Ban: {
/** Format: int64 */
id: number;
actorType: string;
actorId: string;
bannedType: string;
bannedId: string;
/** Format: int64 */
bannedTime: number;
internalNote: string;
};
BaseMessage: {
actorDisplayName: string;
actorId: string;
@ -1095,6 +1123,118 @@ export type operations = {
};
};
};
/**
* List the bans of a conversation
* @description Required capability: `ban-v1`
*/
"ban-list-bans": {
parameters: {
header: {
/** @description Required to be true for the API request to pass */
"OCS-APIRequest": boolean;
};
path: {
apiVersion: "v1";
token: string;
};
};
responses: {
/** @description List all bans */
200: {
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: components["schemas"]["Ban"][];
};
};
};
};
};
};
/**
* Ban an actor or IP address
* @description Required capability: `ban-v1`
*/
"ban-ban-actor": {
parameters: {
query: {
/** @description Type of actor to ban, or `ip` when banning a clients remote address */
actorType: "users" | "groups" | "circles" | "emails" | "federated_users" | "phones" | "ip";
/** @description Actor ID or the IP address or range in case of type `ip` */
actorId: string;
/** @description Optional internal note */
internalNote?: string;
};
header: {
/** @description Required to be true for the API request to pass */
"OCS-APIRequest": boolean;
};
path: {
apiVersion: "v1";
token: string;
};
};
responses: {
/** @description Ban successfully */
200: {
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: components["schemas"]["Ban"];
};
};
};
};
/** @description Actor information is invalid */
400: {
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: {
error: string;
};
};
};
};
};
};
};
/**
* Unban an actor or IP address
* @description Required capability: `ban-v1`
*/
"ban-unban-actor": {
parameters: {
query: {
/** @description ID of the ban to be removed */
banId: number;
};
header: {
/** @description Required to be true for the API request to pass */
"OCS-APIRequest": boolean;
};
path: {
apiVersion: "v1";
token: string;
};
};
responses: {
/** @description Unban successfully or not found */
200: {
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: unknown;
};
};
};
};
};
};
/** List bots */
"bot-list-bots": {
parameters: {
@ -4599,7 +4739,10 @@ export type operations = {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: unknown;
data: {
/** @enum {string} */
error: "ban" | "password";
};
};
};
};

View file

@ -26,6 +26,23 @@ export type paths = {
/** Get the dark mode avatar of a room */
get: operations["avatar-get-avatar-dark"];
};
"/ocs/v2.php/apps/spreed/api/{apiVersion}/ban/{token}": {
/**
* List the bans of a conversation
* @description Required capability: `ban-v1`
*/
get: operations["ban-list-bans"];
/**
* Ban an actor or IP address
* @description Required capability: `ban-v1`
*/
post: operations["ban-ban-actor"];
/**
* Unban an actor or IP address
* @description Required capability: `ban-v1`
*/
delete: operations["ban-unban-actor"];
};
"/ocs/v2.php/apps/spreed/api/{apiVersion}/bot/{token}": {
/** List bots */
get: operations["bot-list-bots"];
@ -385,6 +402,17 @@ export type webhooks = Record<string, never>;
export type components = {
schemas: {
Ban: {
/** Format: int64 */
id: number;
actorType: string;
actorId: string;
bannedType: string;
bannedId: string;
/** Format: int64 */
bannedTime: number;
internalNote: string;
};
BaseMessage: {
actorDisplayName: string;
actorId: string;
@ -918,6 +946,118 @@ export type operations = {
};
};
};
/**
* List the bans of a conversation
* @description Required capability: `ban-v1`
*/
"ban-list-bans": {
parameters: {
header: {
/** @description Required to be true for the API request to pass */
"OCS-APIRequest": boolean;
};
path: {
apiVersion: "v1";
token: string;
};
};
responses: {
/** @description List all bans */
200: {
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: components["schemas"]["Ban"][];
};
};
};
};
};
};
/**
* Ban an actor or IP address
* @description Required capability: `ban-v1`
*/
"ban-ban-actor": {
parameters: {
query: {
/** @description Type of actor to ban, or `ip` when banning a clients remote address */
actorType: "users" | "groups" | "circles" | "emails" | "federated_users" | "phones" | "ip";
/** @description Actor ID or the IP address or range in case of type `ip` */
actorId: string;
/** @description Optional internal note */
internalNote?: string;
};
header: {
/** @description Required to be true for the API request to pass */
"OCS-APIRequest": boolean;
};
path: {
apiVersion: "v1";
token: string;
};
};
responses: {
/** @description Ban successfully */
200: {
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: components["schemas"]["Ban"];
};
};
};
};
/** @description Actor information is invalid */
400: {
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: {
error: string;
};
};
};
};
};
};
};
/**
* Unban an actor or IP address
* @description Required capability: `ban-v1`
*/
"ban-unban-actor": {
parameters: {
query: {
/** @description ID of the ban to be removed */
banId: number;
};
header: {
/** @description Required to be true for the API request to pass */
"OCS-APIRequest": boolean;
};
path: {
apiVersion: "v1";
token: string;
};
};
responses: {
/** @description Unban successfully or not found */
200: {
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: unknown;
};
};
};
};
};
};
/** List bots */
"bot-list-bots": {
parameters: {
@ -4500,7 +4640,10 @@ export type operations = {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: unknown;
data: {
/** @enum {string} */
error: "ban" | "password";
};
};
};
};

View file

@ -135,6 +135,7 @@ class CapabilitiesTest extends TestCase {
'silent-send-state',
'chat-read-last',
'federation-v1',
'ban-v1',
'message-expiration',
'reactions',
];