mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-06-30 16:41:29 +00:00
Add very basic subscription server for Synapse module
This commit is contained in:
parent
4e4a6e0b56
commit
fa6a6547ee
|
@ -82,3 +82,14 @@ protectedRooms:
|
||||||
# Note: the management room is *excluded* from this condition. Add it to the
|
# Note: the management room is *excluded* from this condition. Add it to the
|
||||||
# protected rooms to protect it.
|
# protected rooms to protect it.
|
||||||
protectAllJoinedRooms: false
|
protectAllJoinedRooms: false
|
||||||
|
|
||||||
|
# An optional server for the Synapse Mjolnir plugin to connect to. This is
|
||||||
|
# recommended if you're running the Synapse module in a worker environment,
|
||||||
|
# particularly if you're running a federation reader.
|
||||||
|
#
|
||||||
|
# It is not recommended to expose this to the wider internet. Connections
|
||||||
|
# are over TCP only.
|
||||||
|
banListServer:
|
||||||
|
enabled: false
|
||||||
|
bind: "0.0.0.0"
|
||||||
|
port: 24465
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -38,6 +38,11 @@ interface IConfig {
|
||||||
fasterMembershipChecks: boolean;
|
fasterMembershipChecks: boolean;
|
||||||
automaticallyRedactForReasons: string[]; // case-insensitive globs
|
automaticallyRedactForReasons: string[]; // case-insensitive globs
|
||||||
protectAllJoinedRooms: boolean;
|
protectAllJoinedRooms: boolean;
|
||||||
|
banListServer: {
|
||||||
|
enabled: boolean;
|
||||||
|
bind: string;
|
||||||
|
port: number;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config options only set at runtime. Try to avoid using the objects
|
* Config options only set at runtime. Try to avoid using the objects
|
||||||
|
|
|
@ -30,6 +30,7 @@ import BanList from "./models/BanList";
|
||||||
import { Mjolnir } from "./Mjolnir";
|
import { Mjolnir } from "./Mjolnir";
|
||||||
import { logMessage } from "./LogProxy";
|
import { logMessage } from "./LogProxy";
|
||||||
import { MembershipEvent } from "matrix-bot-sdk/lib/models/events/MembershipEvent";
|
import { MembershipEvent } from "matrix-bot-sdk/lib/models/events/MembershipEvent";
|
||||||
|
import {BanListServer} from "./server/BanListServer";
|
||||||
|
|
||||||
config.RUNTIME = {client: null};
|
config.RUNTIME = {client: null};
|
||||||
|
|
||||||
|
@ -94,5 +95,11 @@ LogService.info("index", "Starting bot...");
|
||||||
await logMessage(LogLevel.INFO, "index", "Mjolnir is starting up. Use !mjolnir to query status.");
|
await logMessage(LogLevel.INFO, "index", "Mjolnir is starting up. Use !mjolnir to query status.");
|
||||||
|
|
||||||
const bot = new Mjolnir(client, protectedRooms, banLists);
|
const bot = new Mjolnir(client, protectedRooms, banLists);
|
||||||
|
|
||||||
|
if (config.banListServer && config.banListServer.enabled) {
|
||||||
|
const server = new BanListServer(bot);
|
||||||
|
await server.start();
|
||||||
|
}
|
||||||
|
|
||||||
await bot.start();
|
await bot.start();
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -67,6 +67,10 @@ export default class BanList {
|
||||||
return this.rules.filter(r => r.kind === RULE_ROOM);
|
return this.rules.filter(r => r.kind === RULE_ROOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get allRules(): ListRule[] {
|
||||||
|
return [...this.serverRules, ...this.userRules, ...this.roomRules];
|
||||||
|
}
|
||||||
|
|
||||||
public async updateList() {
|
public async updateList() {
|
||||||
this.rules = [];
|
this.rules = [];
|
||||||
|
|
||||||
|
|
46
src/server/BanListServer.ts
Normal file
46
src/server/BanListServer.ts
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Mjolnir} from "../Mjolnir";
|
||||||
|
import * as net from "net";
|
||||||
|
import {Socket} from "net";
|
||||||
|
import config from "../config";
|
||||||
|
import {LogService} from "matrix-bot-sdk";
|
||||||
|
import {Connection} from "./Connection";
|
||||||
|
|
||||||
|
export class BanListServer {
|
||||||
|
|
||||||
|
private connections: Connection[] = [];
|
||||||
|
|
||||||
|
constructor(private mjolnir: Mjolnir) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public async start() {
|
||||||
|
LogService.info("BanListServer", `Starting server on ${config.banListServer.bind}:${config.banListServer.port}`);
|
||||||
|
const server = net.createServer(this.onConnect.bind(this));
|
||||||
|
server.listen(config.banListServer.port, config.banListServer.bind);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDisconnect(connection: Connection): void {
|
||||||
|
const index = this.connections.indexOf(connection);
|
||||||
|
if (index >= 0) this.connections.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onConnect(socket: Socket) {
|
||||||
|
LogService.info("BanListServer", `New client connection from ${socket.address().toString()}`);
|
||||||
|
this.connections.push(new Connection(socket, this.mjolnir, this.onDisconnect.bind(this)));
|
||||||
|
}
|
||||||
|
}
|
78
src/server/Connection.ts
Normal file
78
src/server/Connection.ts
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Socket} from "net";
|
||||||
|
import {Mjolnir} from "../Mjolnir";
|
||||||
|
import {LogService} from "matrix-bot-sdk";
|
||||||
|
import BanList from "../models/BanList";
|
||||||
|
|
||||||
|
const COMMAND_PREFIX = "|C,";
|
||||||
|
const COMMAND_SUFFIX = ",C|";
|
||||||
|
const SUBSCRIBE_PREFIX = `${COMMAND_PREFIX}SUBSCRIBE,`;
|
||||||
|
const RESET_PREFIX = `${COMMAND_PREFIX}RESET,`;
|
||||||
|
const RULE_PREFIX = `${COMMAND_PREFIX}RULE,`;
|
||||||
|
|
||||||
|
export class Connection {
|
||||||
|
|
||||||
|
private currentCommand = "";
|
||||||
|
private subscribedRooms: string[] = [];
|
||||||
|
|
||||||
|
constructor(private socket: Socket, private mjolnir: Mjolnir, private disconnectFn: (Socket) => void) {
|
||||||
|
socket.on("data", this.onData.bind(this));
|
||||||
|
socket.on("close", this.onClose.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private onListUpdate(list: BanList) {
|
||||||
|
if (!this.subscribedRooms.includes(list.roomId)) {
|
||||||
|
return; // Ignore list update
|
||||||
|
}
|
||||||
|
|
||||||
|
this.socket.write(`${RESET_PREFIX}${list.roomId}${COMMAND_SUFFIX}`);
|
||||||
|
for (const rule of list.allRules) {
|
||||||
|
this.socket.write(`${RULE_PREFIX}${rule.kind},${rule.entity}${COMMAND_SUFFIX}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onClose() {
|
||||||
|
this.disconnectFn(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onData(b: Buffer) {
|
||||||
|
this.currentCommand += b.toString("ascii");
|
||||||
|
|
||||||
|
// Try and parse the command
|
||||||
|
const commandStart = this.currentCommand.indexOf(COMMAND_PREFIX);
|
||||||
|
if (commandStart < 0) return; // No command yet
|
||||||
|
|
||||||
|
let command = this.currentCommand.slice(commandStart);
|
||||||
|
let idx = command.indexOf(COMMAND_SUFFIX);
|
||||||
|
if (idx < 0) return; // incomplete command
|
||||||
|
command = command.substring(0, idx);
|
||||||
|
this.currentCommand = this.currentCommand.substring(commandStart + command.length);
|
||||||
|
|
||||||
|
LogService.info("Running " + command);
|
||||||
|
if (command.startsWith(SUBSCRIBE_PREFIX)) {
|
||||||
|
const roomId = command.substring(SUBSCRIBE_PREFIX.length, (command.length - COMMAND_SUFFIX.length - 1) + SUBSCRIBE_PREFIX.length);
|
||||||
|
const banList = this.mjolnir.lists.find(i => i.roomId === roomId);
|
||||||
|
if (!banList) {
|
||||||
|
LogService.warn("Connection", `Connection tried to subscribe to unknown ban list ${roomId}`);
|
||||||
|
} else {
|
||||||
|
this.subscribedRooms.push(roomId);
|
||||||
|
this.onListUpdate(banList);
|
||||||
|
}
|
||||||
|
} // else unknown command
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user