mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-10-01 01:36:06 -04:00
77ad40e27a
* Attempt to factor out protected rooms from Mjolnir. This is useful to the appservice because it means we don't have to wrap a Mjolnir that is designed to sync. It's also useful if we later on want to have specific settings per space. It's also just a nice seperation between Mjolnir's needs while syncing via client-server and the behaviour of syncing policy rooms. ### Things that have changed - `ErrorCache` no longer a static class (phew), gets used by `ProtectedRooms`. - `ManagementRoomOutput` class gets created to handle logging back to the management room. - Responsibilities for syncing member bans and server ACL are handled by `ProtectedRooms`. - Responsibilities for watched lists should be moved to `ProtectedRooms` if they haven't been. - `EventRedactionQueue` is moved to `ProtectedRooms` since this needs to happen after member bans. - ApplyServerAcls moved to `ProtectedRooms` - ApplyMemberBans move to `ProtectedRooms` - `logMessage` and `replaceRoomIdsWithPills` moved to `ManagementRoomOutput`. - `resyncJoinedRooms` has been made a little more clear, though I am concerned about how often it does run because it does seem expensive. * ProtectedRooms is not supposed to track joined rooms. The reason is because it is supposed to represent a specific set of rooms to protect, not do horrible logic for working out what rooms mjolnir is supposed to protect.
162 lines
6.8 KiB
TypeScript
162 lines
6.8 KiB
TypeScript
import { strict as assert } from "assert";
|
|
|
|
import { Mjolnir } from "../../src/Mjolnir";
|
|
import { IProtection } from "../../src/protections/IProtection";
|
|
import { ProtectionSettingValidationError } from "../../src/protections/ProtectionSettings";
|
|
import { NumberProtectionSetting, StringProtectionSetting, StringListProtectionSetting } from "../../src/protections/ProtectionSettings";
|
|
import { newTestUser, noticeListener } from "./clientHelper";
|
|
import { matrixClient, mjolnir } from "./mjolnirSetupUtils";
|
|
|
|
describe("Test: Protection settings", function() {
|
|
let client;
|
|
this.beforeEach(async function () {
|
|
client = await newTestUser(this.config.homeserverUrl, { name: { contains: "protection-settings" }});
|
|
await client.start();
|
|
})
|
|
this.afterEach(async function () {
|
|
await client.stop();
|
|
})
|
|
it("Mjolnir refuses to save invalid protection setting values", async function() {
|
|
this.timeout(20000);
|
|
await assert.rejects(
|
|
async () => await this.mjolnir.protectionManager.setProtectionSettings("BasicFloodingProtection", {"maxPerMinute": "soup"}),
|
|
ProtectionSettingValidationError
|
|
);
|
|
});
|
|
it("Mjolnir successfully saves valid protection setting values", async function() {
|
|
this.timeout(20000);
|
|
|
|
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
|
name = "05OVMS";
|
|
description = "A test protection";
|
|
settings = { test: new NumberProtectionSetting(3) };
|
|
});
|
|
|
|
await this.mjolnir.protectionManager.setProtectionSettings("05OVMS", { test: 123 });
|
|
assert.equal(
|
|
(await this.mjolnir.protectionManager.getProtectionSettings("05OVMS"))["test"],
|
|
123
|
|
);
|
|
});
|
|
it("Mjolnir should accumulate changed settings", async function() {
|
|
this.timeout(20000);
|
|
|
|
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
|
name = "HPUjKN";
|
|
settings = {
|
|
test1: new NumberProtectionSetting(3),
|
|
test2: new NumberProtectionSetting(4)
|
|
};
|
|
});
|
|
|
|
await this.mjolnir.protectionManager.setProtectionSettings("HPUjKN", { test1: 1 });
|
|
await this.mjolnir.protectionManager.setProtectionSettings("HPUjKN", { test2: 2 });
|
|
const settings = await this.mjolnir.protectionManager.getProtectionSettings("HPUjKN");
|
|
assert.equal(settings["test1"], 1);
|
|
assert.equal(settings["test2"], 2);
|
|
});
|
|
it("Mjolnir responds to !set correctly", async function() {
|
|
this.timeout(20000);
|
|
await client.joinRoom(this.config.managementRoom);
|
|
|
|
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
|
name = "JY2TPN";
|
|
description = "A test protection";
|
|
settings = { test: new StringProtectionSetting() };
|
|
});
|
|
|
|
|
|
let reply = new Promise((resolve, reject) => {
|
|
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
|
if (event.content.body.includes("Changed JY2TPN.test ")) {
|
|
resolve(event);
|
|
}
|
|
}))
|
|
});
|
|
|
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config set JY2TPN.test asd"})
|
|
await reply
|
|
|
|
const settings = await this.mjolnir.protectionManager.getProtectionSettings("JY2TPN");
|
|
assert.equal(settings["test"], "asd");
|
|
});
|
|
it("Mjolnir adds a value to a list setting", async function() {
|
|
this.timeout(20000);
|
|
await client.joinRoom(this.config.managementRoom);
|
|
|
|
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
|
name = "r33XyT";
|
|
description = "A test protection";
|
|
settings = { test: new StringListProtectionSetting() };
|
|
});
|
|
|
|
|
|
let reply = new Promise((resolve, reject) => {
|
|
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
|
if (event.content.body.includes("Changed r33XyT.test ")) {
|
|
resolve(event);
|
|
}
|
|
}))
|
|
});
|
|
|
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config add r33XyT.test asd"})
|
|
await reply
|
|
|
|
assert.deepEqual(await this.mjolnir.protectionManager.getProtectionSettings("r33XyT"), { "test": ["asd"] });
|
|
});
|
|
it("Mjolnir removes a value from a list setting", async function() {
|
|
this.timeout(20000);
|
|
await client.joinRoom(this.config.managementRoom);
|
|
|
|
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
|
name = "oXzT0E";
|
|
description = "A test protection";
|
|
settings = { test: new StringListProtectionSetting() };
|
|
});
|
|
|
|
let reply = () => new Promise((resolve, reject) => {
|
|
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
|
if (event.content.body.includes("Changed oXzT0E.test ")) {
|
|
resolve(event);
|
|
}
|
|
}))
|
|
});
|
|
|
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config add oXzT0E.test asd"})
|
|
await reply();
|
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config remove oXzT0E.test asd"})
|
|
await reply();
|
|
|
|
assert.deepEqual(await this.mjolnir.protectionManager.getProtectionSettings("oXzT0E"), { "test": [] });
|
|
});
|
|
it("Mjolnir will change a protection setting in-place", async function() {
|
|
this.timeout(20000);
|
|
await client.joinRoom(this.config.managementRoom);
|
|
|
|
await this.mjolnir.protectionManager.registerProtection(new class implements IProtection {
|
|
name = "d0sNrt";
|
|
description = "A test protection";
|
|
settings = { test: new StringProtectionSetting() };
|
|
});
|
|
|
|
let replyPromise = new Promise((resolve, reject) => {
|
|
let i = 0;
|
|
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
|
if (event.content.body.includes("Changed d0sNrt.test ")) {
|
|
if (++i == 2) {
|
|
resolve(event);
|
|
}
|
|
}
|
|
}))
|
|
});
|
|
|
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config set d0sNrt.test asd1"})
|
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config set d0sNrt.test asd2"})
|
|
assert.equal(
|
|
(await replyPromise).content.body.split("\n", 3)[2],
|
|
"Changed d0sNrt.test to asd2 (was asd1)"
|
|
)
|
|
});
|
|
});
|
|
|