Skip to content

Commit

Permalink
Merge pull request #85 from matrix-org/jryans/ban-safety
Browse files Browse the repository at this point in the history
Improve force handling
  • Loading branch information
turt2live authored Feb 5, 2021
2 parents 34590fa + 259cdd8 commit f8a8360
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 13 deletions.
17 changes: 11 additions & 6 deletions src/commands/UnbanBanCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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())) {
Expand All @@ -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.
Expand All @@ -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) {
Expand All @@ -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
Expand Down
45 changes: 38 additions & 7 deletions test/commands/UnbanBanCommandTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand Down

0 comments on commit f8a8360

Please sign in to comment.