Add a config option to reduce homeserver load during ban checks

This commit is contained in:
Travis Ralston 2019-11-06 18:54:59 -07:00
parent 84135c5ff5
commit 30e186ca9c
3 changed files with 25 additions and 10 deletions

View File

@ -51,6 +51,12 @@ verifyPermissionsOnStartup: true
# bot might not be trusted fully, yet. Default false (do bans/ACLs).
noop: false
# Set to true to use /joined_members instead of /state to figure out who is
# in the room. Using /state is preferred because it means that users are
# banned when they are invited instead of just when they join, though if your
# server struggles with /state requests then set this to true.
fasterMembershipChecks: false
# A list of rooms to protect (matrix.to URLs)
protectedRooms:
- "https://matrix.to/#/#yourroom:example.org"

View File

@ -37,30 +37,38 @@ export async function applyUserBans(lists: BanList[], roomIds: string[], mjolnir
// We specifically use sendNotice to avoid having to escape HTML
await logMessage(LogLevel.DEBUG, "ApplyBan", `Updating member bans in ${roomId}`);
const state = await mjolnir.client.getRoomState(roomId);
const members = state.filter(s => s['type'] === 'm.room.member' && !!s['state_key']);
let members: { userId: string, membership: string }[];
if (config.fasterMembershipChecks) {
const memberIds = await mjolnir.client.getJoinedRoomMembers(roomId);
members = memberIds.map(u => {
return {userId: u, membership: "join"};
});
} else {
const state = await mjolnir.client.getRoomState(roomId);
members = state.filter(s => s['type'] === 'm.room.member' && !!s['state_key']).map(s => {
return {userId: s['state_key'], membership: s['content'] ? s['content']['membership'] : 'leave'};
});
}
for (const member of members) {
const content = member['content'];
if (!content) continue; // Invalid, but whatever.
if (content['membership'] === 'ban') {
if (member.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'])) {
if (userRule.isMatch(member.userId)) {
// User needs to be banned
// We specifically use sendNotice to avoid having to escape HTML
await logMessage(LogLevel.DEBUG, "ApplyBan", `Banning ${member['state_key']} in ${roomId} for: ${userRule.reason}`);
await logMessage(LogLevel.DEBUG, "ApplyBan", `Banning ${member.userId} in ${roomId} for: ${userRule.reason}`);
if (!config.noop) {
await mjolnir.client.banUser(member['state_key'], roomId, userRule.reason);
await mjolnir.client.banUser(member.userId, roomId, userRule.reason);
} else {
await logMessage(LogLevel.WARN, "ApplyBan", `Tried to ban ${member['state_key']} in ${roomId} but Mjolnir is running in no-op mode`);
await logMessage(LogLevel.WARN, "ApplyBan", `Tried to ban ${member.userId} in ${roomId} but Mjolnir is running in no-op mode`);
}
bansApplied++;

View File

@ -34,6 +34,7 @@ interface IConfig {
verifyPermissionsOnStartup: boolean;
noop: boolean;
protectedRooms: string[]; // matrix.to urls
fasterMembershipChecks: boolean;
/**
* Config options only set at runtime. Try to avoid using the objects