Files
Draupnir/apps/draupnir/src/draupnirfactory/DraupnirProtectedRoomsSet.ts
2026-05-05 12:31:43 +02:00

236 lines
6.6 KiB
TypeScript

// Copyright 2022 - 2023 Gnuxie <Gnuxie@protonmail.com>
// Copyright 2019 - 2021 The Matrix.org Foundation C.I.C.
//
// SPDX-License-Identifier: Apache-2.0
//
// SPDX-FileAttributionText: <text>
// This modified file incorporates work from mjolnir
// https://github.com/matrix-org/mjolnir
// </text>
import {
ActionResult,
ClientPlatform,
DefaultMixinExtractor,
LoggableConfigTracker,
Logger,
MJOLNIR_PROTECTED_ROOMS_EVENT_TYPE,
MJOLNIR_WATCHED_POLICY_ROOMS_EVENT_TYPE,
MissingProtectionCB,
MjolnirEnabledProtectionsEventType,
MjolnirPolicyRoomsConfig,
MjolnirProtectedRoomsConfig,
MjolnirProtectionSettingsConfig,
MjolnirProtectionSettingsEventType,
MjolnirProtectionsConfig,
Ok,
PolicyListConfig,
PolicyRoomManager,
ProtectedRoomsConfig,
ProtectedRoomsSet,
ProtectionHandleRegistryDescription,
ProtectionsManager,
RoomJoiner,
RoomMembershipManager,
RoomResolver,
RoomStateManager,
StandardProtectedRoomsManager,
StandardProtectedRoomsSet,
StandardProtectionCapabilityProviderSetConfig,
StandardProtectionsManager,
StandardSetRoomMembership,
StandardSetRoomState,
StandardWatchedPolicyRooms,
isError,
} from "matrix-protection-suite";
import {
BotSDKAccountDataConfigBackend,
BotSDKRoomStateConfigBackend,
MatrixSendClient,
} from "matrix-protection-suite-for-matrix-bot-sdk";
import { DefaultEnabledProtectionsMigration } from "../protections/ConfigMigration/DefaultEnabledProtectionsMigration";
import "../protections/DraupnirProtectionsIndex";
import { IConfig } from "../config";
import { runProtectionConfigHooks } from "../protections/ConfigHooks";
import { makeHandleMissingProtectionPermissions } from "../protections/MissingProtectionPermissions";
import {
MatrixRoomID,
StringUserID,
} from "@the-draupnir-project/matrix-basic-types";
import { CapabilitySetProviderMigration } from "../protections/ConfigMigration/CapabilitySetProviderMigration";
const log = new Logger("DraupnirProtectedRoomsSet");
async function makePolicyListConfig(
client: MatrixSendClient,
roomJoiner: RoomJoiner
): Promise<ActionResult<PolicyListConfig>> {
const result = await MjolnirPolicyRoomsConfig.createFromStore(
new BotSDKAccountDataConfigBackend(
client,
MJOLNIR_WATCHED_POLICY_ROOMS_EVENT_TYPE
),
roomJoiner
);
return result;
}
async function makeProtectedRoomsConfig(
client: MatrixSendClient,
roomResolver: RoomResolver,
loggableConfigTracker: LoggableConfigTracker
): Promise<ActionResult<ProtectedRoomsConfig>> {
return await MjolnirProtectedRoomsConfig.createFromStore(
new BotSDKAccountDataConfigBackend(
client,
MJOLNIR_PROTECTED_ROOMS_EVENT_TYPE
),
roomResolver,
loggableConfigTracker
);
}
function missingProtectionCB(protectionName: string): void {
log.warn(
`Unable to find a protection description for the protection named`,
protectionName
);
}
// FIXME: https://github.com/the-draupnir-project/Draupnir/issues/338
function makeMissingProtectionCB(): MissingProtectionCB {
return missingProtectionCB;
}
async function makeProtectionsManager(
client: MatrixSendClient,
roomStateManager: RoomStateManager,
managementRoom: MatrixRoomID,
config: IConfig,
loggableConfigTracker: LoggableConfigTracker
): Promise<ActionResult<ProtectionsManager>> {
const result =
await roomStateManager.getRoomStateRevisionIssuer(managementRoom);
if (isError(result)) {
return result;
}
const protectionsConfigResult = await MjolnirProtectionsConfig.create(
new BotSDKAccountDataConfigBackend(
client,
MjolnirEnabledProtectionsEventType
),
loggableConfigTracker,
{
migrationHandler: DefaultEnabledProtectionsMigration,
missingProtectionCB: makeMissingProtectionCB(),
}
);
if (isError(protectionsConfigResult)) {
return protectionsConfigResult;
}
const hookResult = await runProtectionConfigHooks(
config,
protectionsConfigResult.ok
);
if (isError(hookResult)) {
return hookResult;
}
return Ok(
new StandardProtectionsManager(
protectionsConfigResult.ok,
new StandardProtectionCapabilityProviderSetConfig(
(description) =>
Ok(
new BotSDKRoomStateConfigBackend(
client,
managementRoom.toRoomIDOrAlias(),
"me.marewolf.draupnir.set_capability_provider",
description.name
)
),
CapabilitySetProviderMigration
),
new MjolnirProtectionSettingsConfig((description) =>
Ok(
new BotSDKRoomStateConfigBackend(
client,
managementRoom.toRoomIDOrAlias(),
MjolnirProtectionSettingsEventType,
description.name
)
)
),
ProtectionHandleRegistryDescription
)
);
}
export async function makeProtectedRoomsSet(
managementRoom: MatrixRoomID,
roomStateManager: RoomStateManager,
policyRoomManager: PolicyRoomManager,
roomMembershipManager: RoomMembershipManager,
client: MatrixSendClient,
clientPlatform: ClientPlatform,
userID: StringUserID,
config: IConfig,
loggableConfigTracker: LoggableConfigTracker
): Promise<ActionResult<ProtectedRoomsSet>> {
const protectedRoomsConfig = await makeProtectedRoomsConfig(
client,
clientPlatform.toRoomResolver(),
loggableConfigTracker
);
if (isError(protectedRoomsConfig)) {
return protectedRoomsConfig;
}
const protectedRoomsManager = await StandardProtectedRoomsManager.create(
protectedRoomsConfig.ok,
roomStateManager,
roomMembershipManager,
clientPlatform.toRoomJoiner(),
StandardSetRoomMembership.blankSet(),
StandardSetRoomState.blankSet()
);
if (isError(protectedRoomsManager)) {
return protectedRoomsManager;
}
const policyListConfig = await makePolicyListConfig(
client,
clientPlatform.toRoomJoiner()
);
if (isError(policyListConfig)) {
return policyListConfig;
}
const watchedPolicyRooms = await StandardWatchedPolicyRooms.create(
policyListConfig.ok,
policyRoomManager,
clientPlatform.toRoomJoiner()
);
if (isError(watchedPolicyRooms)) {
return watchedPolicyRooms;
}
const protectionsConfig = await makeProtectionsManager(
client,
roomStateManager,
managementRoom,
config,
loggableConfigTracker
);
if (isError(protectionsConfig)) {
return protectionsConfig;
}
const protectedRoomsSet = new StandardProtectedRoomsSet(
watchedPolicyRooms.ok,
protectedRoomsManager.ok,
protectionsConfig.ok,
userID,
DefaultMixinExtractor,
makeHandleMissingProtectionPermissions(
clientPlatform.toRoomMessageSender(),
managementRoom.toRoomIDOrAlias()
)
);
return Ok(protectedRoomsSet);
}