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 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 <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 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 rules - Lists the rules currently in use by Mjolnir\n" +
|
||||||
"!mjolnir sync - Force updates of all lists and re-apply rules\n" +
|
"!mjolnir sync - Force updates of all lists and re-apply rules\n" +
|
||||||
"!mjolnir verify - Ensures Mjolnir can moderate all your rooms\n" +
|
"!mjolnir verify - Ensures Mjolnir can moderate all your rooms\n" +
|
||||||
|
@ -15,14 +15,31 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Mjolnir } from "../Mjolnir";
|
import { Mjolnir } from "../Mjolnir";
|
||||||
import { LogLevel } from "matrix-bot-sdk";
|
import { LogLevel, MatrixGlob, RichReply } from "matrix-bot-sdk";
|
||||||
import config from "../config";
|
import config from "../config";
|
||||||
|
|
||||||
// !mjolnir kick <user|filter> [room] [reason]
|
// !mjolnir kick <user|filter> [room] [reason]
|
||||||
export async function execKickCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
|
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)];
|
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;
|
let reason: string | undefined;
|
||||||
if (parts.length > 3) {
|
if (parts.length > 3) {
|
||||||
let reasonIndex = 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>';
|
reason = parts.slice(reasonIndex).join(' ') || '<no reason supplied>';
|
||||||
}
|
}
|
||||||
if (!reason) reason = "<none supplied>";
|
if (!reason) reason = '<none supplied>';
|
||||||
|
|
||||||
for (const targetRoomId of rooms) {
|
for (const protectedRoomId of rooms) {
|
||||||
const joinedUsers = await mjolnir.client.getJoinedRoomMembers(targetRoomId);
|
const members = await mjolnir.client.getRoomMembers(protectedRoomId, undefined, ["join"], ["ban", "leave"]);
|
||||||
if (!joinedUsers.includes(userId)) continue; // skip
|
|
||||||
|
for (const member of members) {
|
||||||
|
const victim = member.membershipFor;
|
||||||
|
|
||||||
|
if (kickRule.test(victim)) {
|
||||||
|
await mjolnir.logMessage(LogLevel.DEBUG, "KickCommand", `Removing ${victim} in ${protectedRoomId}`, protectedRoomId);
|
||||||
|
|
||||||
await mjolnir.logMessage(LogLevel.INFO, "KickCommand", `Kicking ${userId} in ${targetRoomId} for ${reason}`, targetRoomId);
|
|
||||||
if (!config.noop) {
|
if (!config.noop) {
|
||||||
|
try {
|
||||||
await mjolnir.taskQueue.push(async () => {
|
await mjolnir.taskQueue.push(async () => {
|
||||||
return mjolnir.client.kickUser(userId, targetRoomId, reason);
|
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 {
|
} else {
|
||||||
await mjolnir.logMessage(LogLevel.WARN, "KickCommand", `Tried to kick ${userId} in ${targetRoomId} but the bot is running in no-op mode.`, targetRoomId);
|
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