Apply user bans

This commit is contained in:
Travis Ralston 2019-09-27 19:54:13 -06:00
parent 149cbcfbd2
commit 834abc97dd
3 changed files with 90 additions and 16 deletions

View File

@ -7,7 +7,7 @@ A moderation tool for Matrix.
TODO: Describe what all this means.
Phase 1:
* [ ] Ban users
* [x] Ban users
* [x] ACL servers
* [x] Update lists with new bans/ACLs

View File

@ -19,6 +19,7 @@ import BanList, { ALL_RULE_TYPES } from "./models/BanList";
import { applyServerAcls } from "./actions/ApplyAcl";
import { RoomUpdateError } from "./models/RoomUpdateError";
import { COMMAND_PREFIX, handleCommand } from "./commands/CommandHandler";
import { applyUserBans } from "./actions/ApplyBan";
export class Mjolnir {
@ -74,30 +75,41 @@ export class Mjolnir {
}
if (!updated) return;
const errors = await applyServerAcls(this.banLists, Object.keys(this.protectedRooms), this.client);
return this.printActionResult(errors);
let errors = await applyServerAcls(this.banLists, Object.keys(this.protectedRooms), this.client);
await this.printActionResult(errors);
errors = await applyUserBans(this.banLists, Object.keys(this.protectedRooms), this.client);
await this.printActionResult(errors);
} else if (event['type'] === "m.room.member") {
// TODO: Check membership against ban banLists
const errors = await applyUserBans(this.banLists, Object.keys(this.protectedRooms), this.client);
await this.printActionResult(errors);
}
const html = `<font color="#00cc00"><b>Updated all protected rooms with new rules successfully.</b></font>`;
const text = "Updated all protected rooms with new rules successfully";
await this.client.sendMessage(this.managementRoomId, {
msgtype: "m.notice",
body: text,
format: "org.matrix.custom.html",
formatted_body: html,
});
}
private async printActionResult(errors: RoomUpdateError[]) {
if (errors.length <= 0) return;
let html = "";
let text = "";
if (errors.length > 0) {
html += `<font color="#ff0000"><b>${errors.length} errors updating protected rooms!</b></font><br /><ul>`;
text += `${errors.length} errors updating protected rooms!\n`;
for (const error of errors) {
const url = this.protectedRooms[error.roomId] ? this.protectedRooms[error.roomId] : `https://matrix.to/#/${error.roomId}`;
html += `<li><a href="${url}">${error.roomId}</a> - ${error.errorMessage}</li>`;
text += `${url} - ${error.errorMessage}\n`;
}
html += "</ul>";
} else {
html += `<font color="#00cc00"><b>Updated all protected rooms with new rules successfully.</b></font>`;
text += "Updated all protected rooms with new rules successfully";
html += `<font color="#ff0000"><b>${errors.length} errors updating protected rooms!</b></font><br /><ul>`;
text += `${errors.length} errors updating protected rooms!\n`;
for (const error of errors) {
const url = this.protectedRooms[error.roomId] ? this.protectedRooms[error.roomId] : `https://matrix.to/#/${error.roomId}`;
html += `<li><a href="${url}">${error.roomId}</a> - ${error.errorMessage}</li>`;
text += `${url} - ${error.errorMessage}\n`;
}
html += "</ul>";
const message = {
msgtype: "m.notice",

62
src/actions/ApplyBan.ts Normal file
View File

@ -0,0 +1,62 @@
/*
Copyright 2019 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 BanList from "../models/BanList";
import { MatrixClient } from "matrix-bot-sdk";
import { RoomUpdateError } from "../models/RoomUpdateError";
/**
* Applies the member bans represented by the ban lists to the provided rooms, returning the
* room IDs that could not be updated and their error.
* @param {BanList[]} lists The lists to determine bans from.
* @param {string[]} roomIds The room IDs to apply the bans in.
* @param {MatrixClient} client The Matrix client to apply the bans with.
*/
export async function applyUserBans(lists: BanList[], roomIds: string[], client: MatrixClient): Promise<RoomUpdateError[]> {
// We can only ban people who are not already banned, and who match the rules.
const errors: RoomUpdateError[] = [];
for (const roomId of roomIds) {
try {
const state = await client.getRoomState(roomId);
const members = state.filter(s => s['type'] === 'm.room.member' && !!s['state_key']);
for (const member of members) {
const content = member['content'];
if (!content) continue; // Invalid, but whatever.
if (content['membership'] === 'ban') {
continue; // user already banned
}
let banned = false;
for (const list of lists) {
for (const userRule of list.userRules) {
if (userRule.isMatch(member['state_key'])) {
// User needs to be banned
await client.banUser(member['state_key'], roomId, userRule.reason);
banned = true;
break;
}
}
if (banned) break;
}
}
} catch (e) {
errors.push({roomId, errorMessage: e.message || (e.body ? e.body.error : '<no message>')});
}
}
return errors;
}