From b952ee1042a0a184c1f078feef74c424eb0583e7 Mon Sep 17 00:00:00 2001 From: Gnuxie <50846879+Gnuxie@users.noreply.github.com> Date: Wed, 4 Dec 2024 12:11:06 +0000 Subject: [PATCH] Add a command to switch a protection's active capability provider. (#632) * Add command to change the active capability provider of a protection. * Update MPS for persistent capability set config. The command will actually persist the chosen capabilities across startup. --- package.json | 4 +- src/commands/DraupnirCommands.ts | 5 + .../ProtectionsCapabilitiesCommand.tsx | 123 ++++++++++++++++++ .../DraupnirProtectedRoomsSet.ts | 11 +- yarn.lock | 16 +-- 5 files changed, 148 insertions(+), 11 deletions(-) create mode 100644 src/commands/ProtectionsCapabilitiesCommand.tsx diff --git a/package.json b/package.json index 84fb9a2f..0decb163 100644 --- a/package.json +++ b/package.json @@ -70,8 +70,8 @@ "jsdom": "^24.0.0", "matrix-appservice-bridge": "^10.3.1", "matrix-bot-sdk": "npm:@vector-im/matrix-bot-sdk@^0.7.1-element.6", - "matrix-protection-suite": "npm:@gnuxie/matrix-protection-suite@2.0.0", - "matrix-protection-suite-for-matrix-bot-sdk": "npm:@gnuxie/matrix-protection-suite-for-matrix-bot-sdk@2.0.0", + "matrix-protection-suite": "npm:@gnuxie/matrix-protection-suite@2.1.0", + "matrix-protection-suite-for-matrix-bot-sdk": "npm:@gnuxie/matrix-protection-suite-for-matrix-bot-sdk@2.1.0", "parse-duration": "^1.0.2", "pg": "^8.8.0", "shell-quote": "^1.7.3", diff --git a/src/commands/DraupnirCommands.ts b/src/commands/DraupnirCommands.ts index eba85da8..185a1d31 100644 --- a/src/commands/DraupnirCommands.ts +++ b/src/commands/DraupnirCommands.ts @@ -50,6 +50,7 @@ import { import { DraupnirTopLevelCommands } from "./DraupnirCommandTable"; import { DraupnirSafeModeCommand } from "./SafeModeCommand"; import { DraupnirProtectionsShowCommand } from "./ProtectionsShowCommand"; +import { DraupnirProtectionsCapabilityCommand } from "./ProtectionsCapabilitiesCommand"; // TODO: These commands should all be moved to subdirectories tbh and this // should be split like an index file for each subdirectory. @@ -67,6 +68,10 @@ const DraupnirCommands = new StandardCommandTable("draupnir") .internCommand(DraupnirImportCommand, ["import"]) .internCommand(DraupnirKickCommand, ["kick"]) .internCommand(DraupnirListProtectionsCommand, ["protections"]) + .internCommand(DraupnirProtectionsCapabilityCommand, [ + "protections", + "capability", + ]) .internCommand(DraupnirProtectionsEnableCommand, ["protections", "enable"]) .internCommand(DraupnirProtectionsDisableCommand, ["protections", "disable"]) .internCommand(DraupnirProtectionsConfigAddCommand, [ diff --git a/src/commands/ProtectionsCapabilitiesCommand.tsx b/src/commands/ProtectionsCapabilitiesCommand.tsx new file mode 100644 index 00000000..5f360d46 --- /dev/null +++ b/src/commands/ProtectionsCapabilitiesCommand.tsx @@ -0,0 +1,123 @@ +// SPDX-FileCopyrightText: 2024 Gnuxie +// +// SPDX-License-Identifier: AFL-3.0 + +import { Ok, Result, ResultError, isError } from "@gnuxie/typescript-result"; +import { + DeadDocumentJSX, + StringPresentationType, + describeCommand, + tuple, +} from "@the-draupnir-project/interface-manager"; +import { + CapabilityProviderDescription, + ProtectionDescription, + findCapabilityProvider, + findProtection, +} from "matrix-protection-suite"; +import { Draupnir } from "../Draupnir"; +import { DraupnirInterfaceAdaptor } from "./DraupnirCommandPrerequisites"; + +// ahh bitch, getting the prompts for capability provider name is going +// to require arguments to be passed through to the prompt function. + +type CapabilityProviderChange = { + protectionDescription: ProtectionDescription; + oldCapabilityProvider: CapabilityProviderDescription; + newCapabilityProvider: CapabilityProviderDescription; + capabilityName: string; +}; + +export const DraupnirProtectionsCapabilityCommand = describeCommand({ + summary: + "Change the active capability provider for a specific protection capability.", + parameters: tuple( + { + name: "protection name", + acceptor: StringPresentationType, + }, + { + name: "capability name", + acceptor: StringPresentationType, + }, + { + name: "capability provider name", + acceptor: StringPresentationType, + } + ), + async executor( + draupnir: Draupnir, + _info, + _keywords, + _rest, + protectionName, + capabilityName, + capabilityProviderName + ): Promise> { + const protectionDescription = findProtection(protectionName); + if (protectionDescription === undefined) { + return ResultError.Result( + `Cannot find a protection named ${protectionName}` + ); + } + const capabilityProvider = findCapabilityProvider(capabilityProviderName); + if (capabilityProvider === undefined) { + return ResultError.Result( + `Cannot find a capability provider named ${capabilityProviderName}` + ); + } + const oldCapabilitySet = + await draupnir.protectedRoomsSet.protections.getCapabilityProviderSet( + protectionDescription + ); + if (isError(oldCapabilitySet)) { + return oldCapabilitySet.elaborate( + "Unable to get the current capability provider" + ); + } + const oldCapabilityProvider = oldCapabilitySet.ok[capabilityName]; + if (oldCapabilityProvider === undefined) { + return ResultError.Result( + `Unable to find the current capability provider for ${capabilityName}` + ); + } + const changeResult = + await draupnir.protectedRoomsSet.protections.changeCapabilityProvider( + draupnir, + draupnir.protectedRoomsSet, + protectionDescription, + capabilityName, + capabilityProvider + ); + if (isError(changeResult)) { + return changeResult.elaborate( + "Unable to change the active capability provider" + ); + } + return Ok({ + protectionDescription, + oldCapabilityProvider: oldCapabilityProvider, + newCapabilityProvider: capabilityProvider, + capabilityName, + }); + }, +}); + +DraupnirInterfaceAdaptor.describeRenderer( + DraupnirProtectionsCapabilityCommand, + { + JSXRenderer(commandResult) { + if (isError(commandResult)) { + return Ok(undefined); + } + return Ok( + + Changed the capability provider for{" "} + {commandResult.ok.capabilityName} from{" "} + {commandResult.ok.oldCapabilityProvider.name} to{" "} + {commandResult.ok.newCapabilityProvider.name} + + ); + }, + } +); diff --git a/src/draupnirfactory/DraupnirProtectedRoomsSet.ts b/src/draupnirfactory/DraupnirProtectedRoomsSet.ts index 93718b4a..0ddae310 100644 --- a/src/draupnirfactory/DraupnirProtectedRoomsSet.ts +++ b/src/draupnirfactory/DraupnirProtectedRoomsSet.ts @@ -136,7 +136,16 @@ async function makeProtectionsManager( return Ok( new StandardProtectionsManager( protectionsConfigResult.ok, - new StandardProtectionCapabilityProviderSetConfig(), + new StandardProtectionCapabilityProviderSetConfig((description) => + Ok( + new BotSDKRoomStateConfigBackend( + client, + managementRoom.toRoomIDOrAlias(), + "me.marewolf.draupnir.set_capability_provider", + description.name + ) + ) + ), new MjolnirProtectionSettingsConfig((description) => Ok( new BotSDKRoomStateConfigBackend( diff --git a/yarn.lock b/yarn.lock index bbbc0ab5..b949d107 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2645,17 +2645,17 @@ matrix-appservice@^2.0.0: request-promise "^4.2.6" sanitize-html "^2.11.0" -"matrix-protection-suite-for-matrix-bot-sdk@npm:@gnuxie/matrix-protection-suite-for-matrix-bot-sdk@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@gnuxie/matrix-protection-suite-for-matrix-bot-sdk/-/matrix-protection-suite-for-matrix-bot-sdk-2.0.0.tgz#4c5256e99f575bbff53392f1e04008edffeefe32" - integrity sha512-V03teGAAPLcIwrVcGz6GALSWIJ+fuJ8vWI8jfKI6OyE5YLuQcXxHUagsoyYZRE/mmKfLGmHA+5woZcXAbnDfEQ== +"matrix-protection-suite-for-matrix-bot-sdk@npm:@gnuxie/matrix-protection-suite-for-matrix-bot-sdk@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@gnuxie/matrix-protection-suite-for-matrix-bot-sdk/-/matrix-protection-suite-for-matrix-bot-sdk-2.1.0.tgz#a95b2045cba89799839467bc23c0e2d88a51b377" + integrity sha512-ki6gSPhXyD/v7veOya/34KBTCG7SPusxDDJRx7fdkNn3UPoGxqGIvrH+rGn3meOSbJkYHkr4zZ+HO+sJ6VpJkg== dependencies: "@gnuxie/typescript-result" "^1.0.0" -"matrix-protection-suite@npm:@gnuxie/matrix-protection-suite@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@gnuxie/matrix-protection-suite/-/matrix-protection-suite-2.0.0.tgz#423e205919eaac7f9edbae4ddc7dac266dd4119b" - integrity sha512-fjpfKtQKuBrZTvWcpeNbpJcU6zqN9DKKjKqfEoz9jeJ/uwj/nQ6ZtrxRjiQxVHJV3/b3vJKUEqu796IyEDhDEQ== +"matrix-protection-suite@npm:@gnuxie/matrix-protection-suite@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@gnuxie/matrix-protection-suite/-/matrix-protection-suite-2.1.0.tgz#5bd19d07400ef35c29a3fd18f33196d5f814e65f" + integrity sha512-mQrpyoJulflfkyDB6BZI3SGCqW3sMemKRKMSSkp3TA+RM+sIWfocaMLrUBVdMSzPKFzs2vanJHx2qQzNFteUZw== dependencies: "@gnuxie/typescript-result" "^1.0.0" await-lock "^2.2.2"