mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-10-01 01:36:06 -04: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
|
||||
# protected rooms to protect it.
|
||||
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 T***** 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");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -38,6 +38,11 @@ interface IConfig {
|
||||
fasterMembershipChecks: boolean;
|
||||
automaticallyRedactForReasons: string[]; // case-insensitive globs
|
||||
protectAllJoinedRooms: boolean;
|
||||
banListServer: {
|
||||
enabled: boolean;
|
||||
bind: string;
|
||||
port: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 { logMessage } from "./LogProxy";
|
||||
import { MembershipEvent } from "matrix-bot-sdk/lib/models/events/MembershipEvent";
|
||||
import {BanListServer} from "./server/BanListServer";
|
||||
|
||||
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.");
|
||||
|
||||
const bot = new Mjolnir(client, protectedRooms, banLists);
|
||||
|
||||
if (config.banListServer && config.banListServer.enabled) {
|
||||
const server = new BanListServer(bot);
|
||||
await server.start();
|
||||
}
|
||||
|
||||
await bot.start();
|
||||
})();
|
||||
|
@ -67,6 +67,10 @@ export default class BanList {
|
||||
return this.rules.filter(r => r.kind === RULE_ROOM);
|
||||
}
|
||||
|
||||
public get allRules(): ListRule[] {
|
||||
return [...this.serverRules, ...this.userRules, ...this.roomRules];
|
||||
}
|
||||
|
||||
public async updateList() {
|
||||
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