Skip to content

Commit

Permalink
Fix report poller (#662)
Browse files Browse the repository at this point in the history
Fixes #258
Fixes #408
Fixes #409

* Create a way to only forward reports in WebAPIs.

Honestly, I'm going to revert this because I think I have found a
better way of testing the report poller.

* Begin improving and fixing the report poller.

We need to change the ReportManager so that we can interface it out
for testing. The reason being that the report poller is inactive
in the harness and so we can't use that with a protection handle
to test. Instead I want to instantiate a report poller with
a mocked report manager.

* Update integration test nginx to mirror reports to synapse.

We need this so that we can test the report poller without needing to
do gymnastics to selectively forward reports.

* Interface out ReportManager.

Needed so we can test the report poller without doing gymnastics with
setting up fake protections.

* Fix report poller from paginating over the same reports.

the-draupnir-project/planning#38.

* Revert "Create a way to only forward reports in WebAPIs."

This reverts commit 59b335f.
We don't need this anymore.

* Update for MPS v2.4.0

Gives us the synapse admin client, updates schema, and gives us the fix for #560
  • Loading branch information
Gnuxie authored Jan 10, 2025
1 parent 2655572 commit fa5ce9a
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 163 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@
"jsdom": "^24.0.0",
"matrix-appservice-bridge": "^10.3.1",
"matrix-bot-sdk": "npm:@vector-im/matrix-bot-sdk@^0.7.1-element.6",
"matrix-protection-suite": "npm:@gnuxie/matrix-protection-suite@2.3.0",
"matrix-protection-suite-for-matrix-bot-sdk": "npm:@gnuxie/matrix-protection-suite-for-matrix-bot-sdk@2.3.2",
"matrix-protection-suite": "npm:@gnuxie/matrix-protection-suite@2.4.0",
"matrix-protection-suite-for-matrix-bot-sdk": "npm:@gnuxie/matrix-protection-suite-for-matrix-bot-sdk@2.4.0",
"parse-duration": "^1.0.2",
"pg": "^8.8.0",
"shell-quote": "^1.7.3",
Expand Down
6 changes: 3 additions & 3 deletions src/Draupnir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { UnlistedUserRedactionQueue } from "./queues/UnlistedUserRedactionQueue"
import { ThrottlingQueue } from "./queues/ThrottlingQueue";
import ManagementRoomOutput from "./managementroom/ManagementRoomOutput";
import { ReportPoller } from "./report/ReportPoller";
import { ReportManager } from "./report/ReportManager";
import { StandardReportManager } from "./report/ReportManager";
import { MatrixReactionHandler } from "./commands/interface-manager/MatrixReactionHandler";
import {
MatrixSendClient,
Expand Down Expand Up @@ -106,7 +106,7 @@ export class Draupnir implements Client, MatrixAdaptorContext {
* Handle user reports from the homeserver.
* FIXME: ReportManager should be a protection.
*/
public readonly reportManager: ReportManager;
public readonly reportManager: StandardReportManager;

public readonly reactionHandler: MatrixReactionHandler;

Expand Down Expand Up @@ -157,7 +157,7 @@ export class Draupnir implements Client, MatrixAdaptorContext {
clientUserID,
clientPlatform
);
this.reportManager = new ReportManager(this);
this.reportManager = new StandardReportManager(this);
if (config.pollReports) {
this.reportPoller = new ReportPoller(this, this.reportManager);
}
Expand Down
105 changes: 71 additions & 34 deletions src/report/ReportManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,32 @@ enum Kind {
ESCALATED_REPORT,
}

export interface ReportManager {
handleTimelineEvent(roomID: StringRoomID, event: RoomEvent): void;
handleServerAbuseReport({
roomID,
reporterId,
event,
reason,
}: {
roomID: StringRoomID;
reporterId: string;
event: RoomEvent;
reason?: string;
}): Promise<void>;
handleReaction({
roomID,
event,
}: {
roomID: StringRoomID;
event: RoomEvent;
}): Promise<void>;
}

/**
* A class designed to respond to abuse reports.
*/
export class ReportManager {
export class StandardReportManager {
private displayManager: DisplayManager;
constructor(public draupnir: Draupnir) {
this.displayManager = new DisplayManager(this);
Expand Down Expand Up @@ -580,7 +602,7 @@ interface IUIAction {
* @param report Details on the abuse report.
*/
canExecute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport,
moderationroomID: string
): Promise<boolean>;
Expand All @@ -590,20 +612,20 @@ interface IUIAction {
*
* @param report Details on the abuse report.
*/
title(manager: ReportManager, report: IReport): Promise<string>;
title(manager: StandardReportManager, report: IReport): Promise<string>;

/**
* A human-readable help message to display for the end-user.
*
* @param report Details on the abuse report.
*/
help(manager: ReportManager, report: IReport): Promise<string>;
help(manager: StandardReportManager, report: IReport): Promise<string>;

/**
* Attempt to execute the action.
*/
execute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport,
moderationroomID: string,
displayManager: DisplayManager
Expand All @@ -618,25 +640,25 @@ class IgnoreBadReport implements IUIAction {
public emoji = "🚯";
public needsConfirmation = true;
public async canExecute(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<boolean> {
return true;
}
public async title(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<string> {
return "Ignore";
}
public async help(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<string> {
return "Ignore bad report";
}
public async execute(
manager: ReportManager,
manager: StandardReportManager,
report: IReportWithAction
): Promise<string | undefined> {
await manager.draupnir.client.sendEvent(
Expand Down Expand Up @@ -667,7 +689,7 @@ class RedactMessage implements IUIAction {
public emoji = "🗍";
public needsConfirmation = true;
public async canExecute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport
): Promise<boolean> {
try {
Expand All @@ -681,16 +703,19 @@ class RedactMessage implements IUIAction {
}
}
public async title(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<string> {
return "Redact";
}
public async help(_manager: ReportManager, report: IReport): Promise<string> {
public async help(
_manager: StandardReportManager,
report: IReport
): Promise<string> {
return `Redact event ${report.event_id}`;
}
public async execute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport,
_moderationroomID: string
): Promise<string | undefined> {
Expand All @@ -707,7 +732,7 @@ class KickAccused implements IUIAction {
public emoji = "⚽";
public needsConfirmation = true;
public async canExecute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport
): Promise<boolean> {
try {
Expand All @@ -721,16 +746,19 @@ class KickAccused implements IUIAction {
}
}
public async title(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<string> {
return "Kick";
}
public async help(_manager: ReportManager, report: IReport): Promise<string> {
public async help(
_manager: StandardReportManager,
report: IReport
): Promise<string> {
return `Kick ${htmlEscape(report.accused_id)} from room ${htmlEscape(report.room_alias_or_id)}`;
}
public async execute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport
): Promise<string | undefined> {
await manager.draupnir.client.kickUser(report.accused_id, report.room_id);
Expand All @@ -746,7 +774,7 @@ class MuteAccused implements IUIAction {
public emoji = "🤐";
public needsConfirmation = true;
public async canExecute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport
): Promise<boolean> {
try {
Expand All @@ -761,16 +789,19 @@ class MuteAccused implements IUIAction {
}
}
public async title(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<string> {
return "Mute";
}
public async help(_manager: ReportManager, report: IReport): Promise<string> {
public async help(
_manager: StandardReportManager,
report: IReport
): Promise<string> {
return `Mute ${htmlEscape(report.accused_id)} in room ${htmlEscape(report.room_alias_or_id)}`;
}
public async execute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport
): Promise<string | undefined> {
await manager.draupnir.client.setUserPowerLevel(
Expand All @@ -790,7 +821,7 @@ class BanAccused implements IUIAction {
public emoji = "🚫";
public needsConfirmation = true;
public async canExecute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport
): Promise<boolean> {
try {
Expand All @@ -804,16 +835,19 @@ class BanAccused implements IUIAction {
}
}
public async title(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<string> {
return "Ban";
}
public async help(_manager: ReportManager, report: IReport): Promise<string> {
public async help(
_manager: StandardReportManager,
report: IReport
): Promise<string> {
return `Ban ${htmlEscape(report.accused_id)} from room ${htmlEscape(report.room_alias_or_id)}`;
}
public async execute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport
): Promise<string | undefined> {
await manager.draupnir.client.banUser(report.accused_id, report.room_id);
Expand All @@ -829,25 +863,25 @@ class Help implements IUIAction {
public emoji = "❓";
public needsConfirmation = false;
public async canExecute(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<boolean> {
return true;
}
public async title(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<string> {
return "Help";
}
public async help(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<string> {
return "This help";
}
public async execute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport,
moderationroomID: string
): Promise<string | undefined> {
Expand Down Expand Up @@ -884,7 +918,7 @@ class EscalateToServerModerationRoom implements IUIAction {
public emoji = "⏫";
public needsConfirmation = true;
public async canExecute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport,
moderationroomID: string
): Promise<boolean> {
Expand All @@ -901,16 +935,19 @@ class EscalateToServerModerationRoom implements IUIAction {
return true;
}
public async title(
_manager: ReportManager,
_manager: StandardReportManager,
_report: IReport
): Promise<string> {
return "Escalate";
}
public async help(manager: ReportManager, _report: IReport): Promise<string> {
public async help(
manager: StandardReportManager,
_report: IReport
): Promise<string> {
return `Escalate report to ${getHomeserver(await manager.draupnir.client.getUserId())} server moderators`;
}
public async execute(
manager: ReportManager,
manager: StandardReportManager,
report: IReport,
_moderationroomID: string,
displayManager: DisplayManager
Expand Down Expand Up @@ -939,7 +976,7 @@ class EscalateToServerModerationRoom implements IUIAction {
}

class DisplayManager {
constructor(private owner: ReportManager) {}
constructor(private owner: StandardReportManager) {}

/**
* Display the report and any UI button.
Expand Down
Loading

0 comments on commit fa5ce9a

Please sign in to comment.