mirror of
https://github.com/the-draupnir-project/Draupnir.git
synced 2026-05-15 03:45:22 +00:00
Test room takedown service and add thoughts to FIXME.
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user