implement polling reports in synapse

This commit is contained in:
jesopo 2022-03-23 14:19:19 +00:00
parent d7b846cdb3
commit da2b5e35d5
2 changed files with 76 additions and 3 deletions

View File

@ -43,6 +43,7 @@ import { Healthz } from "./health/healthz";
import { EventRedactionQueue, RedactUserInRoom } from "./queues/EventRedactionQueue";
import { htmlEscape } from "./utils";
import { ReportManager } from "./report/ReportManager";
import { ReportPoll } from "./report/ReportPoll";
import { WebAPIs } from "./webapis/WebAPIs";
import { replaceRoomIdsWithPills } from "./utils";
import RuleServer from "./models/RuleServer";
@ -67,6 +68,7 @@ const ENABLED_PROTECTIONS_EVENT_TYPE = "org.matrix.mjolnir.enabled_protections";
const PROTECTED_ROOMS_EVENT_TYPE = "org.matrix.mjolnir.protected_rooms";
const WARN_UNPROTECTED_ROOM_EVENT_PREFIX = "org.matrix.mjolnir.unprotected_room_warning.for.";
const CONSEQUENCE_EVENT_DATA = "org.matrix.mjolnir.consequence";
const REPORT_POLL_EVENT_TYPE = "org.matrix.mjolnir.report_poll";
export class Mjolnir {
private displayName: string;
@ -97,7 +99,7 @@ export class Mjolnir {
private webapis: WebAPIs;
private protectedRoomActivityTracker: ProtectedRoomActivityTracker;
public taskQueue: ThrottlingQueue;
private reportPoll: ReportPoll;
/**
* Adds a listener to the client that will automatically accept invitations.
* @param {MatrixClient} client
@ -258,11 +260,12 @@ export class Mjolnir {
const reportManager = new ReportManager(this);
reportManager.on("report.new", this.handleReport);
this.webapis = new WebAPIs(reportManager, this.ruleServer);
// Setup join/leave listener
this.roomJoins = new RoomMemberManager(this.client);
this.taskQueue = new ThrottlingQueue(this, config.backgroundDelayMS);
this.reportPoll = new ReportPoll(client, reportManager, async (_from: number) => {
await client.setAccountData(REPORT_POLL_EVENT_TYPE, { from: _from });
});
}
public get lists(): BanList[] {
@ -302,6 +305,9 @@ export class Mjolnir {
console.log("Starting web server");
await this.webapis.start();
const reportPollSetting: { from: number } | null = await this.client.getAccountData(REPORT_POLL_EVENT_TYPE);
this.reportPoll.start(reportPollSetting?.from ?? 0)
// Load the state.
this.currentState = STATE_CHECKING_PERMISSIONS;

67
src/report/ReportPoll.ts Normal file
View File

@ -0,0 +1,67 @@
import { MatrixClient } from "matrix-bot-sdk";
import { ReportManager } from './ReportManager';
class InvalidStateError extends Error {}
export class ReportPoll {
private _client: MatrixClient;
private _manager: ReportManager;
private _save: (a: number) => Promise<any>;
private _from = 0;
private _interval: ReturnType<typeof setInterval> | null = null;
constructor(
client: MatrixClient,
manager: ReportManager,
save: (a: number) => Promise<any>
) {
this._client = client;
this._manager = manager;
this._save = save;
}
private async getAbuseReports(): Promise<any> {
const response = await this._client.doRequest(
"GET",
"/_synapse/admin/v1/event_reports",
{ from: this._from.toString() }
);
for (let report of response.event_reports) {
const event = await this._client.getEvent(report.room_id, report.event_id);
await this._manager.handleServerAbuseReport({
roomId: report.room_id,
reporterId: report.sender,
event: event,
reason: report.event,
});
}
if (response.next_token !== undefined) {
this._from = response.event_reports;
await this._save(response.next_token);
}
}
public start(startFrom: number) {
if (this._interval === null) {
this._from = startFrom;
const self = this;
this._interval = setInterval(
function() { self.getAbuseReports() },
60_000
);
} else {
throw new InvalidStateError();
}
}
public stop() {
if (this._interval !== null) {
clearInterval(this._interval);
this._interval = null;
} else {
throw new InvalidStateError();
}
}
}