Begin process of creating top level stores.

We now need to move the roomStateBackingStore into this thingy.
This commit is contained in:
gnuxie
2025-03-12 18:30:43 +00:00
parent b50033ba4a
commit 4ae5e5f63a
8 changed files with 87 additions and 3 deletions
+5
View File
@@ -82,6 +82,7 @@ import {
makeConfirmationPromptListener,
} from "./commands/interface-manager/MatrixPromptForConfirmation";
import { SynapseHttpAntispam } from "./webapis/SynapseHTTPAntispam/SynapseHttpAntispam";
import { DraupnirStores } from "./backingstore/DraupnirStores";
const log = new Logger("Draupnir");
// webAPIS should not be included on the Draupnir class.
@@ -145,6 +146,7 @@ export class Draupnir implements Client, MatrixAdaptorContext {
public readonly acceptInvitesFromRoom: MatrixRoomID,
public readonly acceptInvitesFromRoomIssuer: RoomMembershipRevisionIssuer,
public readonly safeModeToggle: SafeModeToggle,
public readonly stores: DraupnirStores,
public readonly synapseAdminClient: SynapseAdminClient | undefined,
public readonly synapseHTTPAntispam: SynapseHttpAntispam | undefined
) {
@@ -212,6 +214,7 @@ export class Draupnir implements Client, MatrixAdaptorContext {
config: IConfig,
loggableConfigTracker: LoggableConfigTracker,
safeModeToggle: SafeModeToggle,
stores: DraupnirStores,
synapseHTTPAntispam: SynapseHttpAntispam | undefined
): Promise<ActionResult<Draupnir>> {
const acceptInvitesFromRoom = await (async () => {
@@ -270,6 +273,7 @@ export class Draupnir implements Client, MatrixAdaptorContext {
acceptInvitesFromRoom.ok,
acceptInvitesFromRoomIssuer.ok,
safeModeToggle,
stores,
new SynapseAdminClient(client, clientUserID),
synapseHTTPAntispam
);
@@ -388,6 +392,7 @@ export class Draupnir implements Client, MatrixAdaptorContext {
this.clientRooms.off("timeline", this.timelineEventListener);
this.reportPoller?.stop();
this.protectedRoomsSet.unregisterListeners();
this.stores.dispose();
}
public createRoomReference(roomID: StringRoomID): MatrixRoomID {
+4 -1
View File
@@ -49,6 +49,7 @@ import { ResultError } from "@gnuxie/typescript-result";
import { SafeModeCause, SafeModeReason } from "./safemode/SafeModeCause";
import { SafeModeBootOption } from "./safemode/BootOption";
import { SynapseHttpAntispam } from "./webapis/SynapseHTTPAntispam/SynapseHttpAntispam";
import { TopLevelStores } from "./backingstore/DraupnirStores";
const log = new Logger("DraupnirBotMode");
@@ -113,6 +114,7 @@ export class DraupnirBotModeToggle implements BotModeTogle {
client: MatrixSendClient,
matrixEmitter: SafeMatrixEmitter,
config: IConfig,
stores: TopLevelStores,
backingStore?: RoomStateBackingStore
): Promise<DraupnirBotModeToggle> {
const clientUserID = await client.getUserId();
@@ -169,7 +171,8 @@ export class DraupnirBotModeToggle implements BotModeTogle {
clientsInRoomMap,
clientCapabilityFactory,
clientProvider,
roomStateManagerFactory
roomStateManagerFactory,
stores
);
return new DraupnirBotModeToggle(
clientUserID,
+6
View File
@@ -49,6 +49,9 @@ import {
StringUserID,
} from "@the-draupnir-project/matrix-basic-types";
import { SqliteRoomStateBackingStore } from "../backingstore/better-sqlite3/SqliteRoomStateBackingStore";
import { TopLevelStores } from "../backingstore/DraupnirStores";
// FIXME: Move roomStateBacking store into top level stores.
const log = new Logger("AppService");
/**
@@ -100,6 +103,7 @@ export class MjolnirAppService {
dataStore: DataStore,
eventDecoder: EventDecoder,
registrationFilePath: string,
stores: TopLevelStores,
backingStore?: RoomStateBackingStore
) {
const bridge = new Bridge({
@@ -190,6 +194,7 @@ export class MjolnirAppService {
bridge,
accessControl,
roomStateManagerFactory,
stores,
clientCapabilityFactory,
clientProvider,
instanceCountGauge
@@ -239,6 +244,7 @@ export class MjolnirAppService {
dataStore,
DefaultEventDecoder,
registrationFilePath,
{}, // we don't support any stores in appservice atm except backing store.
backingStore
);
// The call to `start` MUST happen last. As it needs the datastore, and the mjolnir manager to be initialized before it can process events from the homeserver.
+6 -1
View File
@@ -45,6 +45,7 @@ import {
userLocalpart,
isStringRoomID,
} from "@the-draupnir-project/matrix-basic-types";
import { TopLevelStores } from "../backingstore/DraupnirStores";
const log = new Logger("AppServiceDraupnirManager");
@@ -63,6 +64,7 @@ export class AppServiceDraupnirManager {
private readonly bridge: Bridge,
private readonly accessControl: AccessControl,
private readonly roomStateManagerFactory: RoomStateManagerFactory,
stores: TopLevelStores,
private readonly clientCapabilityFactory: ClientCapabilityFactory,
clientProvider: ClientForUserID,
private readonly instanceCountGauge: Gauge<"status" | "uuid">
@@ -71,7 +73,8 @@ export class AppServiceDraupnirManager {
this.roomStateManagerFactory.clientsInRoomMap,
this.clientCapabilityFactory,
clientProvider,
this.roomStateManagerFactory
this.roomStateManagerFactory,
stores
);
this.baseManager = new StandardDraupnirManager(draupnirFactory);
}
@@ -93,6 +96,7 @@ export class AppServiceDraupnirManager {
bridge: Bridge,
accessControl: AccessControl,
roomStateManagerFactory: RoomStateManagerFactory,
stores: TopLevelStores,
clientCapabilityFactory: ClientCapabilityFactory,
clientProvider: ClientForUserID,
instanceCountGauge: Gauge<"status" | "uuid">
@@ -103,6 +107,7 @@ export class AppServiceDraupnirManager {
bridge,
accessControl,
roomStateManagerFactory,
stores,
clientCapabilityFactory,
clientProvider,
instanceCountGauge
+46
View File
@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2025 Gnuxie <Gnuxie@protonmail.com>
//
// SPDX-License-Identifier: Apache-2.0
import {
SHA256RoomHashStore,
StandardSHA256RoomHashStore,
} from "matrix-protection-suite";
import { RoomAuditLog } from "../protections/RoomTakedown/RoomAuditLog";
export type TopLevelStores = {
hashStore?: Omit<SHA256RoomHashStore, "on" | "off">;
roomAuditLog?: RoomAuditLog;
};
/**
* These stores will usually be created at the entrypoint of the draupnir
* application or attenuated for each draupnir.
*
* No i don't like it. Some of these stores ARE specific to the draupnir
* such as the hasStore's event emitter... that just can't be mixed.
*
* We could create a wrapper that disposes of only the stores that
* have been attenuated... but i don't know about it.
*/
export type DraupnirStores = {
hashStore?: SHA256RoomHashStore | undefined;
roomAuditLog?: RoomAuditLog | undefined;
/**
* Dispose of stores relevant to a specific draupnir instance.
* For example, the hash store is usually specific to a single draupnir.
*/
dispose(): void;
};
export function createDraupnirStores(
topLevelStores: TopLevelStores
): DraupnirStores {
return Object.freeze({
roomAudditLog: topLevelStores.roomAuditLog,
hashStore: topLevelStores.hashStore
? new StandardSHA256RoomHashStore(topLevelStores.hashStore)
: undefined,
dispose() {},
});
}
+7 -1
View File
@@ -30,6 +30,10 @@ import { SafeModeCause } from "../safemode/SafeModeCause";
import { SafeModeToggle } from "../safemode/SafeModeToggle";
import { StandardManagementRoomDetail } from "../managementroom/ManagementRoomDetail";
import { DraupnirBotModeToggle } from "../DraupnirBotMode";
import {
createDraupnirStores,
TopLevelStores,
} from "../backingstore/DraupnirStores";
const log = new Logger("DraupnirFactory");
@@ -59,7 +63,8 @@ export class DraupnirFactory {
private readonly clientsInRoomMap: ClientsInRoomMap,
private readonly clientCapabilityFactory: ClientCapabilityFactory,
private readonly clientProvider: ClientForUserID,
private readonly roomStateManagerFactory: RoomStateManagerFactory
private readonly roomStateManagerFactory: RoomStateManagerFactory,
private readonly stores: TopLevelStores
) {
// nothing to do.
}
@@ -143,6 +148,7 @@ export class DraupnirFactory {
config,
configLogTracker,
toggle,
createDraupnirStores(this.stores),
// synapseHTTPAntispam is only available in bot mode.
toggle instanceof DraupnirBotModeToggle
? toggle.synapseHTTPAntispam
@@ -14,8 +14,10 @@ import {
import {
BetterSqliteOptions,
BetterSqliteStore,
makeBetterSqliteDB,
} from "../../backingstore/better-sqlite3/BetterSqliteStore";
import { Database } from "better-sqlite3";
import path from "path";
// NOTE: This should only be used to check in bulk whether rooms are taken down
// upon getting a policy, you probably always want to try again or
@@ -67,6 +69,16 @@ export class SqliteRoomAuditLog
this.takedownRooms = new Set(this.loadTakendownRooms());
}
public static createToplevel(storagePath: string): SqliteRoomAuditLog {
const options = {
path: path.join(storagePath, "room-audit-log.db"),
WALMode: true,
foreignKeys: true,
fileMustExist: false,
};
return new SqliteRoomAuditLog(options, makeBetterSqliteDB(options));
}
public async takedownRoom(policy: LiteralPolicyRule): Promise<Result<void>> {
if (policy.kind !== PolicyRuleType.Room) {
throw new TypeError(
+1
View File
@@ -165,6 +165,7 @@ export async function makeBotModeToggle(
client,
new SafeMatrixEmitterWrapper(client, DefaultEventDecoder),
config,
{}, // we don't support top level stores for now.
backingStore
);
// we don't want to send status on startup incase we want to test e2ee from the manual launch script.