From dea6f8cbf12a3bf6786c0df7327e5bb2d0bd03ea Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 13 Feb 2020 13:56:03 -0700 Subject: [PATCH] Add a command to shut down a room Fixes https://github.com/matrix-org/mjolnir/issues/21 --- src/Mjolnir.ts | 7 ++++++ src/commands/CommandHandler.ts | 4 ++++ src/commands/ShutdownRoomCommand.ts | 34 +++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 src/commands/ShutdownRoomCommand.ts diff --git a/src/Mjolnir.ts b/src/Mjolnir.ts index c478a182..f6967732 100644 --- a/src/Mjolnir.ts +++ b/src/Mjolnir.ts @@ -574,4 +574,11 @@ export class Mjolnir { const endpoint = `/_synapse/admin/v1/deactivate/${userId}`; return await this.client.doRequest("POST", endpoint); } + + public async shutdownSynapseRoom(roomId: string): Promise { + const endpoint = `/_synapse/admin/v1/shutdown_room/${roomId}`; + return await this.client.doRequest("POST", endpoint, null, { + new_room_user_id: await this.client.getUserId(), + }); + } } diff --git a/src/commands/CommandHandler.ts b/src/commands/CommandHandler.ts index b48f289f..34caf78b 100644 --- a/src/commands/CommandHandler.ts +++ b/src/commands/CommandHandler.ts @@ -34,6 +34,7 @@ import { execAddProtectedRoom, execRemoveProtectedRoom } from "./AddRemoveProtec import { execMoveAliasCommand } from "./MoveAliasCommand"; import { execAddRoomToDirectoryCommand, execRemoveRoomFromDirectoryCommand } from "./AddRemoveRoomFromDirectoryCommand"; import { execSetPowerLevelCommand } from "./SetPowerLevelCommand"; +import { execShutdownRoomCommand } from "./ShutdownRoomCommand"; export const COMMAND_PREFIX = "!mjolnir"; @@ -88,6 +89,8 @@ export async function handleCommand(roomId: string, event: any, mjolnir: Mjolnir return await execRemoveRoomFromDirectoryCommand(roomId, event, mjolnir, parts); } else if (parts[1] === 'powerlevel' && parts.length > 3) { return await execSetPowerLevelCommand(roomId, event, mjolnir, parts); + } else if (parts[1] === 'shutdown' && parts[2] === 'room' && parts.length > 3) { + return await execShutdownRoomCommand(roomId, event, mjolnir, parts); } else { // Help menu const menu = "" + @@ -114,6 +117,7 @@ export async function handleCommand(roomId: string, event: any, mjolnir: Mjolnir "!mjolnir move - Moves a to a new \n" + "!mjolnir directory add - Publishes a room in the server's room directory\n" + "!mjolnir directory remove - Removes a room from the server's room directory\n" + + "!mjolnir shutdown room - Uses the bot's account to shut down a room, preventing access to the room on this server\n" + "!mjolnir powerlevel [room alias/ID] - Sets the power level of the user in the specified room (or all protected rooms)\n" + "!mjolnir help - This menu\n"; const html = `Mjolnir help:
${htmlEscape(menu)}
`; diff --git a/src/commands/ShutdownRoomCommand.ts b/src/commands/ShutdownRoomCommand.ts new file mode 100644 index 00000000..71990c5f --- /dev/null +++ b/src/commands/ShutdownRoomCommand.ts @@ -0,0 +1,34 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { Mjolnir } from "../Mjolnir"; +import { RichReply } from "matrix-bot-sdk"; + +// !mjolnir shutdown room +export async function execShutdownRoomCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) { + const victim = parts[3]; + + const isAdmin = await mjolnir.isSynapseAdmin(); + if (!isAdmin) { + const message = "I am not a Synapse administrator, or the endpoint is blocked"; + const reply = RichReply.createFor(roomId, event, message, message); + reply['msgtype'] = "m.notice"; + return mjolnir.client.sendMessage(roomId, reply); + } + + await mjolnir.shutdownSynapseRoom(await mjolnir.client.resolveRoom(victim)); + await mjolnir.client.unstableApis.addReactionToEvent(roomId, event['event_id'], '✅'); +}