diff --git a/src/actions/ApplyAcl.ts b/src/actions/ApplyAcl.ts index cac1006..dda4927 100644 --- a/src/actions/ApplyAcl.ts +++ b/src/actions/ApplyAcl.ts @@ -46,6 +46,22 @@ export async function applyServerAcls(lists: BanList[], roomIds: string[], mjoln const errors: RoomUpdateError[] = []; for (const roomId of roomIds) { 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) { // We specifically use sendNotice to avoid having to escape HTML await mjolnir.client.sendNotice(mjolnir.managementRoomId, `Applying ACL in ${roomId}`); diff --git a/src/models/ServerAcl.ts b/src/models/ServerAcl.ts index 746438c..657f170 100644 --- a/src/models/ServerAcl.ts +++ b/src/models/ServerAcl.ts @@ -76,4 +76,38 @@ export class ServerAcl { 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; + } }