Improve force handling

This improves the force argument parsing to keep it from getting glued onto the
reason. It also adjusts tests for the new behaviour.
This commit is contained in:
J. Ryan Stinnett 2021-02-05 16:59:15 +00:00
parent 46192ac6f7
commit 259cdd8c12
2 changed files with 49 additions and 13 deletions

View File

@ -46,7 +46,8 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni
let ruleType = null;
let entity = null;
let list = null;
while (argumentIndex < 6 && argumentIndex < parts.length) {
let force = false;
while (argumentIndex < 7 && argumentIndex < parts.length) {
const arg = parts[argumentIndex++];
if (!arg) break;
if (["user", "room", "server"].includes(arg.toLowerCase())) {
@ -69,6 +70,12 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni
if (entity) break;
}
if (parts[parts.length - 1] === "--force") {
force = true;
// Remove from parts to ease reason handling
parts.pop();
}
if (!entity) {
// It'll be a server at this point - figure out which positional argument is the server
// name and where the reason starts.
@ -89,10 +96,8 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni
else if (!ruleType) replyMessage = "Please specify the type as either 'user', 'room', or 'server'";
else if (!entity) replyMessage = "No entity found";
if (config.commands.confirmWildcardBan && /[*?]/.test(entity)) {
if (!parts.includes("--force")) {
replyMessage = "Wildcard bans require an additional `--force` argument to confirm";
}
if (config.commands.confirmWildcardBan && /[*?]/.test(entity) && !force) {
replyMessage = "Wildcard bans require an additional `--force` argument to confirm";
}
if (replyMessage) {
@ -110,7 +115,7 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni
};
}
// !mjolnir ban <shortcode> <user|server|room> <glob> [reason]
// !mjolnir ban <shortcode> <user|server|room> <glob> [reason] [--force]
export async function execBanCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
const bits = await parseArguments(roomId, event, mjolnir, parts);
if (!bits) return; // error already handled

View File

@ -86,7 +86,7 @@ describe("UnbanBanCommand", () => {
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
};
const command = "!mjolnir ban test *.example.org";
const command = "!mjolnir ban test *.example.org --force";
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
expect(bits).toBeTruthy();
expect(bits.reason).toBeFalsy();
@ -103,7 +103,7 @@ describe("UnbanBanCommand", () => {
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
};
const command = "!mjolnir ban test server @*.example.org";
const command = "!mjolnir ban test server @*.example.org --force";
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
expect(bits).toBeTruthy();
expect(bits.reason).toBeFalsy();
@ -154,7 +154,7 @@ describe("UnbanBanCommand", () => {
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
};
const command = "!mjolnir ban test !*.example.org";
const command = "!mjolnir ban test !*.example.org --force";
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
expect(bits).toBeTruthy();
expect(bits.reason).toBeFalsy();
@ -205,7 +205,7 @@ describe("UnbanBanCommand", () => {
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
};
const command = "!mjolnir ban test #*.example.org";
const command = "!mjolnir ban test #*.example.org --force";
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
expect(bits).toBeTruthy();
expect(bits.reason).toBeFalsy();
@ -222,7 +222,7 @@ describe("UnbanBanCommand", () => {
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
};
const command = "!mjolnir ban test room @*.example.org";
const command = "!mjolnir ban test room @*.example.org --force";
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
expect(bits).toBeTruthy();
expect(bits.reason).toBeFalsy();
@ -273,7 +273,7 @@ describe("UnbanBanCommand", () => {
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
};
const command = "!mjolnir ban test @*.example.org";
const command = "!mjolnir ban test @*.example.org --force";
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
expect(bits).toBeTruthy();
expect(bits.reason).toBeFalsy();
@ -290,7 +290,7 @@ describe("UnbanBanCommand", () => {
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
};
const command = "!mjolnir ban test user #*.example.org";
const command = "!mjolnir ban test user #*.example.org --force";
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
expect(bits).toBeTruthy();
expect(bits.reason).toBeFalsy();
@ -300,6 +300,37 @@ describe("UnbanBanCommand", () => {
expect(bits.list.listShortcode).toBe("test");
});
it("should error if wildcards used without --force", async () => {
const mjolnir = createTestMjolnir();
(<any>mjolnir).lists = [{listShortcode: "test"}];
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
expect(content).toBeDefined();
expect(content['body']).toContain("Wildcard bans require an additional `--force` argument to confirm");
return Promise.resolve("$fake");
};
const command = "!mjolnir ban test *.example.org";
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
expect(bits).toBeFalsy();
});
it("should have correct ban reason with --force after", async () => {
const mjolnir = createTestMjolnir();
(<any>mjolnir).lists = [{listShortcode: "test"}];
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
};
const command = "!mjolnir ban test user #*.example.org reason here --force";
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
expect(bits).toBeTruthy();
expect(bits.reason).toBe("reason here");
expect(bits.ruleType).toBe(RULE_USER);
expect(bits.entity).toBe("#*.example.org");
expect(bits.list).toBeDefined();
expect(bits.list.listShortcode).toBe("test");
});
describe("[without default list]", () => {
it("should error if no list (with type) is specified", async () => {
const mjolnir = createTestMjolnir();