Check if ACLs match before applying them

Fixes https://github.com/matrix-org/mjolnir/issues/9
This commit is contained in:
Travis Ralston 2019-10-30 14:47:43 -06:00
parent 4434b5440e
commit eccbac9ccf
2 changed files with 50 additions and 0 deletions

View File

@ -46,6 +46,22 @@ export async function applyServerAcls(lists: BanList[], roomIds: string[], mjoln
const errors: RoomUpdateError[] = []; const errors: RoomUpdateError[] = [];
for (const roomId of roomIds) { for (const roomId of roomIds) {
try { try {
if (config.verboseLogging) {
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Checking ACLs for ${roomId}`);
}
try {
const currentAcl = await mjolnir.client.getRoomStateEvent(roomId, "m.room.server_acl", "");
if (acl.matches(currentAcl)) {
if (config.verboseLogging) {
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Skipping ACLs for ${roomId} because they are already the right ones`);
}
continue;
}
} catch (e) {
// ignore - assume no ACL
}
if (config.verboseLogging) { if (config.verboseLogging) {
// We specifically use sendNotice to avoid having to escape HTML // We specifically use sendNotice to avoid having to escape HTML
await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Applying ACL in ${roomId}`); await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Applying ACL in ${roomId}`);

View File

@ -76,4 +76,38 @@ export class ServerAcl {
allow_ip_literals: this.allowIps, allow_ip_literals: this.allowIps,
}; };
} }
public matches(acl: any): boolean {
if (!acl) return false;
const allow = acl['allow'];
const deny = acl['deny'];
const ips = acl['allow_ip_literals'];
let allowMatches = true; // until proven false
let denyMatches = true; // until proven false
let ipsMatch = ips === this.allowIps;
const currentAllowed = setToArray(this.allowedServers);
if (allow.length === currentAllowed.length) {
for (const s of allow) {
if (!currentAllowed.includes(s)) {
allowMatches = false;
break;
}
}
} else allowMatches = false;
const currentDenied = setToArray(this.deniedServers);
if (deny.length === currentDenied.length) {
for (const s of deny) {
if (!currentDenied.includes(s)) {
denyMatches = false;
break;
}
}
} else denyMatches = false;
return denyMatches && allowMatches && ipsMatch;
}
} }