Skip to content

Commit

Permalink
allow check to be overriden with --force argument
Browse files Browse the repository at this point in the history
  • Loading branch information
H-Shay committed Oct 28, 2024
1 parent 72b2025 commit 9b4c806
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/commands/CommandHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export async function handleCommand(roomId: string, event: { content: { body: st
"!mjolnir resolve <room alias> - Resolves a room alias to a room ID\n" +
"!mjolnir since <date>/<duration> <action> <limit> [rooms...] [reason] - Apply an action ('kick', 'ban', 'mute', 'unmute' or 'show') to all users who joined a room since <date>/<duration> (up to <limit> users)\n" +
"!mjolnir shutdown room <room alias/ID> [message] - Uses the bot's account to shut down a room, preventing access to the room on this server\n" +
"!mjolnir powerlevel <user ID> <power level> [room alias/ID] - Sets the power level of the user in the specified room (or all protected rooms)\n" +
"!mjolnir powerlevel <user ID> <power level> [room alias/ID] - Sets the power level of the user in the specified room (or all protected rooms) - mjolnir will resist lowering the power level of the bot/users in the moderation room unless a --force argument is added\n" +
"!mjolnir make admin <room alias> [user alias/ID] - Make the specified user or the bot itself admin of the room\n" +
"!mjolnir suspend <user ID> - Suspend the specified user\n" +
"!mjolnir unsuspend <user ID> - Unsuspend the specified user\n" +
Expand Down
32 changes: 22 additions & 10 deletions src/commands/SetPowerLevelCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,31 @@ export async function execSetPowerLevelCommand(roomId: string, event: any, mjoln
? [await mjolnir.client.resolveRoom(inRoom)]
: mjolnir.protectedRoomsTracker.getProtectedRooms();

let force = false;
if (parts[parts.length - 1] === "--force") {
force = true;
parts.pop();
}

for (const targetRoomId of targetRooms) {
try {
if (target === mjolnirId || mjolnir.moderators.checkMembership(target)) {
// don't let the bot demote itself
const currentLevels = await mjolnir.client.getRoomStateEvent(targetRoomId, "m.room.power_levels", "");
const targetLevel = currentLevels["users"][mjolnirId];
if (level < targetLevel) {
await mjolnir.managementRoomOutput.logMessage(
LogLevel.INFO,
"PowerLevelCommand",
`You are attempting to lower the bot/a moderator's power level: current level ${targetLevel}, requested level ${level}, aborting.`,
if (!force) {
if (target === mjolnirId || mjolnir.moderators.checkMembership(target)) {
// don't let the bot demote itself or members of moderation room
const currentLevels = await mjolnir.client.getRoomStateEvent(
targetRoomId,
"m.room.power_levels",
"",
);
return;
const targetLevel = currentLevels["users"][mjolnirId];
if (level < targetLevel) {
await mjolnir.managementRoomOutput.logMessage(
LogLevel.INFO,
"PowerLevelCommand",
`You are attempting to lower the bot/a moderator's power level: current level ${targetLevel}, requested level ${level}, aborting. This check can be overriden with a --force argument at the end of the command.`,
);
return;
}
}
}
await mjolnir.client.setUserPowerLevel(target, targetRoomId, level);
Expand Down
45 changes: 45 additions & 0 deletions test/integration/commands/powerLevelCommandTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.

import { strict as assert } from "assert";
import { newTestUser } from "../clientHelper";
import { getFirstReaction } from "./commandUtils";

describe("Test: power levels", function () {
it("Does not allow the bot to demote itself or members of management room in a protected room.", async function () {
Expand Down Expand Up @@ -83,4 +84,48 @@ describe("Test: power levels", function () {

mod.stop();
});

it("Does allow the bot to demote itself or members of management room in a protected room with a --force argument.", async function () {
this.timeout(60000);
const mod = await newTestUser(this.config.homeserverUrl, { name: { contains: "force-moderator" } });
const mod2 = await newTestUser(this.config.homeserverUrl, { name: { contains: "force-moderator2" } });
await mod.joinRoom(this.config.managementRoom);
await mod2.joinRoom(this.config.managementRoom);

const targetRoom = await mod.createRoom({ preset: "public_chat" });
await this.mjolnir.client.joinRoom(targetRoom);
await mod2.joinRoom(targetRoom);
const botId = await this.mjolnir.client.getUserId();
await mod.setUserPowerLevel(botId, targetRoom, 100);
const mod2Id = await mod2.getUserId();
await mod.setUserPowerLevel(mod2Id, targetRoom, 75);

await mod.sendMessage(this.mjolnir.managementRoomId, {
msgtype: "m.text.",
body: `!mjolnir rooms add ${targetRoom}`,
});

mod.start();
await getFirstReaction(mod, this.mjolnir.managementRoomId, "✅", async () => {
return await mod.sendMessage(this.mjolnir.managementRoomId, {
msgtype: "m.text",
body: `!mjolnir powerlevel ${mod2Id} 50 ${targetRoom} --force`,
});
});
let currentLevels = await mod.getRoomStateEvent(targetRoom, "m.room.power_levels", "");
const mod2Level = currentLevels["users"][mod2Id];
assert.equal(mod2Level, 50);

await getFirstReaction(mod, this.mjolnir.managementRoomId, "✅", async () => {
return await mod.sendMessage(this.mjolnir.managementRoomId, {
msgtype: "m.text",
body: `!mjolnir powerlevel ${botId} 50 ${targetRoom} --force`,
});
});
currentLevels = await mod.getRoomStateEvent(targetRoom, "m.room.power_levels", "");
const botLevel = currentLevels["users"][botId];
assert.equal(botLevel, 50);

mod.stop();
});
});

0 comments on commit 9b4c806

Please sign in to comment.