mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-10-01 01:36:06 -04:00
Glob kick command (#291)
This pull requests adds for glob support in the `!mjolnir kick` command. ## Example ``` !mjolnir kick @*:domain.tld <reason> --force ``` This command will kick every user having a mxid matching `domain.tld`. You can also still kick a particular user: ``` !mjolnir kick @user:domain.tld <reason> ``` ## Tests: Tested on the Furry Tech room (`vRGLvqJYlFvzpThbxI:matrix.org`) after a spam wave. It kicked over 13k bots in a matter of hours without putting too much strain on the homeserver. For instance, this command was matching `@spam*`: ![image](https://user-images.githubusercontent.com/76598503/167320002-f0575f50-4b54-41d1-8220-f67d72ccaf16.png) Signed-off-by: Jae Lo Presti <me@jae.fi>
This commit is contained in:
parent
0eea04bd69
commit
a876a05520
@ -131,7 +131,7 @@ export async function handleCommand(roomId: string, event: { content: { body: st
|
||||
"!mjolnir unban <list shortcode> <user|room|server> <glob> [apply] - Removes an entity from the ban list. If apply is 'true', the users matching the glob will actually be unbanned\n" +
|
||||
"!mjolnir redact <user ID> [room alias/ID] [limit] - Redacts messages by the sender in the target room (or all rooms), up to a maximum number of events in the backlog (default 1000)\n" +
|
||||
"!mjolnir redact <event permalink> - Redacts a message by permalink\n" +
|
||||
"!mjolnir kick <user ID> [room alias/ID] [reason] - Kicks a user in a particular room or all protected rooms\n" +
|
||||
"!mjolnir kick <glob> [room alias/ID] [reason] - Kicks a user or all of those matching a glob in a particular room or all protected rooms\n" +
|
||||
"!mjolnir rules - Lists the rules currently in use by Mjolnir\n" +
|
||||
"!mjolnir sync - Force updates of all lists and re-apply rules\n" +
|
||||
"!mjolnir verify - Ensures Mjolnir can moderate all your rooms\n" +
|
||||
|
@ -15,14 +15,31 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { Mjolnir } from "../Mjolnir";
|
||||
import { LogLevel } from "matrix-bot-sdk";
|
||||
import { LogLevel, MatrixGlob, RichReply } from "matrix-bot-sdk";
|
||||
import config from "../config";
|
||||
|
||||
// !mjolnir kick <user|filter> [room] [reason]
|
||||
export async function execKickCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
|
||||
const userId = parts[2];
|
||||
let force = false;
|
||||
|
||||
const glob = parts[2];
|
||||
let rooms = [...Object.keys(mjolnir.protectedRooms)];
|
||||
|
||||
if (parts[parts.length - 1] === "--force") {
|
||||
force = true;
|
||||
parts.pop();
|
||||
}
|
||||
|
||||
if (config.commands.confirmWildcardBan && /[*?]/.test(glob) && !force) {
|
||||
let replyMessage = "Wildcard bans require an addition `--force` argument to confirm";
|
||||
const reply = RichReply.createFor(roomId, event, replyMessage, replyMessage);
|
||||
reply["msgtype"] = "m.notice";
|
||||
await mjolnir.client.sendMessage(roomId, reply);
|
||||
return;
|
||||
}
|
||||
|
||||
const kickRule = new MatrixGlob(glob);
|
||||
|
||||
let reason: string | undefined;
|
||||
if (parts.length > 3) {
|
||||
let reasonIndex = 3;
|
||||
@ -32,19 +49,30 @@ export async function execKickCommand(roomId: string, event: any, mjolnir: Mjoln
|
||||
}
|
||||
reason = parts.slice(reasonIndex).join(' ') || '<no reason supplied>';
|
||||
}
|
||||
if (!reason) reason = "<none supplied>";
|
||||
if (!reason) reason = '<none supplied>';
|
||||
|
||||
for (const targetRoomId of rooms) {
|
||||
const joinedUsers = await mjolnir.client.getJoinedRoomMembers(targetRoomId);
|
||||
if (!joinedUsers.includes(userId)) continue; // skip
|
||||
for (const protectedRoomId of rooms) {
|
||||
const members = await mjolnir.client.getRoomMembers(protectedRoomId, undefined, ["join"], ["ban", "leave"]);
|
||||
|
||||
await mjolnir.logMessage(LogLevel.INFO, "KickCommand", `Kicking ${userId} in ${targetRoomId} for ${reason}`, targetRoomId);
|
||||
if (!config.noop) {
|
||||
await mjolnir.taskQueue.push(async () => {
|
||||
return mjolnir.client.kickUser(userId, targetRoomId, reason);
|
||||
});
|
||||
} else {
|
||||
await mjolnir.logMessage(LogLevel.WARN, "KickCommand", `Tried to kick ${userId} in ${targetRoomId} but the bot is running in no-op mode.`, targetRoomId);
|
||||
for (const member of members) {
|
||||
const victim = member.membershipFor;
|
||||
|
||||
if (kickRule.test(victim)) {
|
||||
await mjolnir.logMessage(LogLevel.DEBUG, "KickCommand", `Removing ${victim} in ${protectedRoomId}`, protectedRoomId);
|
||||
|
||||
if (!config.noop) {
|
||||
try {
|
||||
await mjolnir.taskQueue.push(async () => {
|
||||
return mjolnir.client.kickUser(victim, protectedRoomId, reason);
|
||||
});
|
||||
await mjolnir.client.kickUser(victim, protectedRoomId, reason);
|
||||
} catch (e) {
|
||||
await mjolnir.logMessage(LogLevel.WARN, "KickCommand", `An error happened while trying to kick ${victim}: ${e}`);
|
||||
}
|
||||
} else {
|
||||
await mjolnir.logMessage(LogLevel.WARN, "KickCommand", `Tried to kick ${victim} in ${protectedRoomId} but the bot is running in no-op mode.`, protectedRoomId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user