Test room takedown service and add thoughts to FIXME.

This commit is contained in:
gnuxie
2025-03-17 11:39:27 +00:00
parent d15322dff6
commit 1e581d7394
2 changed files with 147 additions and 2 deletions
+9 -2
View File
@@ -20,7 +20,10 @@ import { RoomTakedownCapability } from "../../capabilities/RoomTakedownCapabilit
const log = new Logger("RoomTakedown");
type RoomTakedown = {
// FIXME: How can we segment this so that rooms are takendown on prompt in
// the abscence of policy approval?
export type RoomTakedownService = {
handleDiscoveredRooms(rooms: StringRoomID[]): Promise<Result<void>>;
handlePolicyChange(
revision: PolicyListRevision,
@@ -35,7 +38,7 @@ type RoomTakedown = {
* moving discovered rooms into the hashStore. Although it's not clear
* whether we need to do that?
*/
export class StandardRoomTakedown implements RoomTakedown {
export class StandardRoomTakedown implements RoomTakedownService {
public constructor(
private readonly hashStore: SHA256RoomHashStore,
private readonly auditLog: RoomAuditLog,
@@ -43,6 +46,7 @@ export class StandardRoomTakedown implements RoomTakedown {
) {
// nothing to do
}
// FIXME: We don't use this
public async handleDiscoveredRooms(
rooms: StringRoomID[]
): Promise<Result<void>> {
@@ -85,6 +89,8 @@ export class StandardRoomTakedown implements RoomTakedown {
change.rule.matchType === PolicyRuleMatchType.Literal &&
change.rule.recommendation === Recommendation.Takedown
) {
// FIXME: We probably do not want check the audit log for new policies
// and instead let the capability decide
if (
!this.auditLog.isRoomTakendown(change.rule.entity as StringRoomID)
) {
@@ -114,6 +120,7 @@ export class StandardRoomTakedown implements RoomTakedown {
const roomPolicies = revision
.allRulesOfType(PolicyRuleType.Room, Recommendation.Takedown)
.filter((policy) => policy.matchType === PolicyRuleMatchType.Literal);
// FIXME: We don't seem to check the audit log
for (const policy of roomPolicies) {
const takedownResult = await this.takedownRoom(
policy.entity as StringRoomID,
@@ -0,0 +1,138 @@
// SPDX-FileCopyrightText: 2025 Gnuxie <Gnuxie@protonmail.com>
//
// SPDX-License-Identifier: AFL-3.0
import { createMock } from "ts-auto-mock";
import { StandardRoomTakedown } from "../../../src/protections/RoomTakedown/RoomTakedown";
import {
describePolicyRule,
describeProtectedRoomsSet,
Ok,
parsePolicyRule,
PolicyRuleType,
randomRoomID,
Recommendation,
SHA256RoomHashStore,
SimpleChangeType,
StandardPolicyListRevision,
} from "matrix-protection-suite";
import { RoomAuditLog } from "../../../src/protections/RoomTakedown/RoomAuditLog";
import { RoomTakedownCapability } from "../../../src/capabilities/RoomTakedownCapability";
import { StringRoomID } from "@the-draupnir-project/matrix-basic-types";
import expect from "expect";
function makeServiceMocks(): {
auditLogItems: Parameters<RoomAuditLog["takedownRoom"]>[];
auditLog: RoomAuditLog;
takedownCapabilityItems: StringRoomID[];
takedownCapability: RoomTakedownCapability;
} {
const auditLogItems: Parameters<RoomAuditLog["takedownRoom"]>[] = [];
const takedownCapabilityItems: StringRoomID[] = [];
return {
auditLogItems,
auditLog: createMock<RoomAuditLog>({
async takedownRoom(...args: Parameters<RoomAuditLog["takedownRoom"]>) {
auditLogItems.push(args);
return Ok(undefined);
},
}),
takedownCapabilityItems,
takedownCapability: createMock<RoomTakedownCapability>({
async takedownRoom(roomID: StringRoomID) {
takedownCapabilityItems.push(roomID);
return Ok({
room_id: roomID,
});
},
async isRoomTakendown(_roomID) {
return Ok(false);
},
}),
};
}
describe("", function () {
const storeFake = createMock<SHA256RoomHashStore>({});
it("Test rooms are takendown when policies are added", async function () {
const policyRoom = randomRoomID([]);
const bannedRoom = randomRoomID([]);
const policy = parsePolicyRule(
describePolicyRule({
room_id: policyRoom.toRoomIDOrAlias(),
entity: bannedRoom.toRoomIDOrAlias(),
reason: "spam",
recommendation: Recommendation.Takedown,
type: PolicyRuleType.Room,
}) as never
).expect("Should be able to parse the policy rule.");
const {
auditLog,
takedownCapability,
auditLogItems,
takedownCapabilityItems,
} = makeServiceMocks();
const takedownService = new StandardRoomTakedown(
storeFake,
auditLog,
takedownCapability
);
// we give a blank revision because i haven't updated the describeProtectedRoomsSet code
// to use hashed policies... although thinking about it we don't use them here either lol
(
await takedownService.handlePolicyChange(
StandardPolicyListRevision.blankRevision(),
[
{
changeType: SimpleChangeType.Added,
rule: policy,
event: policy.sourceEvent,
sender: policy.sourceEvent.sender,
},
]
)
).expect("Should have run just fine");
expect(auditLogItems.length).toBe(1);
expect(takedownCapabilityItems.length).toBe(1);
});
it("Test rooms are takendown at startup", async function () {
const policyRoom = randomRoomID([]);
const { protectedRoomsSet } = await describeProtectedRoomsSet({
lists: [
{
room: policyRoom,
policyDescriptions: [
{
entity: randomRoomID([]).toRoomIDOrAlias(),
recommendation: Recommendation.Takedown,
type: PolicyRuleType.Room,
},
{
entity: randomRoomID([]).toRoomIDOrAlias(),
recommendation: Recommendation.Takedown,
type: PolicyRuleType.Room,
},
],
},
],
});
const {
auditLog,
takedownCapability,
auditLogItems,
takedownCapabilityItems,
} = makeServiceMocks();
const takedownService = new StandardRoomTakedown(
storeFake,
auditLog,
takedownCapability
);
(
await takedownService.checkAllRooms(
protectedRoomsSet.watchedPolicyRooms.currentRevision
)
).expect("Should be able to check all rooms");
expect(auditLogItems.length).toBe(2);
expect(takedownCapabilityItems.length).toBe(2);
});
});