mirror of https://github.com/openclaw/openclaw.git
refactor: share dual text command gating
This commit is contained in:
parent
91d9573b55
commit
b61bc4948e
|
|
@ -9,7 +9,7 @@ import {
|
||||||
evaluateSenderGroupAccessForPolicy,
|
evaluateSenderGroupAccessForPolicy,
|
||||||
resolveSenderScopedGroupPolicy,
|
resolveSenderScopedGroupPolicy,
|
||||||
recordPendingHistoryEntryIfEnabled,
|
recordPendingHistoryEntryIfEnabled,
|
||||||
resolveControlCommandGate,
|
resolveDualTextControlCommandGate,
|
||||||
resolveDefaultGroupPolicy,
|
resolveDefaultGroupPolicy,
|
||||||
isDangerousNameMatchingEnabled,
|
isDangerousNameMatchingEnabled,
|
||||||
readStoreAllowFromForDmPolicy,
|
readStoreAllowFromForDmPolicy,
|
||||||
|
|
@ -297,18 +297,15 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
||||||
senderName,
|
senderName,
|
||||||
allowNameMatching: isDangerousNameMatchingEnabled(msteamsCfg),
|
allowNameMatching: isDangerousNameMatchingEnabled(msteamsCfg),
|
||||||
});
|
});
|
||||||
const hasControlCommandInMessage = core.channel.text.hasControlCommand(text, cfg);
|
const { commandAuthorized, shouldBlock } = resolveDualTextControlCommandGate({
|
||||||
const commandGate = resolveControlCommandGate({
|
|
||||||
useAccessGroups,
|
useAccessGroups,
|
||||||
authorizers: [
|
primaryConfigured: commandDmAllowFrom.length > 0,
|
||||||
{ configured: commandDmAllowFrom.length > 0, allowed: ownerAllowedForCommands },
|
primaryAllowed: ownerAllowedForCommands,
|
||||||
{ configured: effectiveGroupAllowFrom.length > 0, allowed: groupAllowedForCommands },
|
secondaryConfigured: effectiveGroupAllowFrom.length > 0,
|
||||||
],
|
secondaryAllowed: groupAllowedForCommands,
|
||||||
allowTextCommands: true,
|
hasControlCommand: core.channel.text.hasControlCommand(text, cfg),
|
||||||
hasControlCommand: hasControlCommandInMessage,
|
|
||||||
});
|
});
|
||||||
const commandAuthorized = commandGate.commandAuthorized;
|
if (shouldBlock) {
|
||||||
if (commandGate.shouldBlock) {
|
|
||||||
logInboundDrop({
|
logInboundDrop({
|
||||||
log: logVerboseMessage,
|
log: logVerboseMessage,
|
||||||
channel: "msteams",
|
channel: "msteams",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||||
import {
|
import {
|
||||||
resolveCommandAuthorizedFromAuthorizers,
|
resolveCommandAuthorizedFromAuthorizers,
|
||||||
resolveControlCommandGate,
|
resolveControlCommandGate,
|
||||||
|
resolveDualTextControlCommandGate,
|
||||||
} from "./command-gating.js";
|
} from "./command-gating.js";
|
||||||
|
|
||||||
describe("resolveCommandAuthorizedFromAuthorizers", () => {
|
describe("resolveCommandAuthorizedFromAuthorizers", () => {
|
||||||
|
|
@ -94,4 +95,17 @@ describe("resolveControlCommandGate", () => {
|
||||||
});
|
});
|
||||||
expect(result.shouldBlock).toBe(false);
|
expect(result.shouldBlock).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("supports the dual-authorizer text gate helper", () => {
|
||||||
|
const result = resolveDualTextControlCommandGate({
|
||||||
|
useAccessGroups: true,
|
||||||
|
primaryConfigured: true,
|
||||||
|
primaryAllowed: false,
|
||||||
|
secondaryConfigured: true,
|
||||||
|
secondaryAllowed: true,
|
||||||
|
hasControlCommand: true,
|
||||||
|
});
|
||||||
|
expect(result.commandAuthorized).toBe(true);
|
||||||
|
expect(result.shouldBlock).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -43,3 +43,24 @@ export function resolveControlCommandGate(params: {
|
||||||
const shouldBlock = params.allowTextCommands && params.hasControlCommand && !commandAuthorized;
|
const shouldBlock = params.allowTextCommands && params.hasControlCommand && !commandAuthorized;
|
||||||
return { commandAuthorized, shouldBlock };
|
return { commandAuthorized, shouldBlock };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveDualTextControlCommandGate(params: {
|
||||||
|
useAccessGroups: boolean;
|
||||||
|
primaryConfigured: boolean;
|
||||||
|
primaryAllowed: boolean;
|
||||||
|
secondaryConfigured: boolean;
|
||||||
|
secondaryAllowed: boolean;
|
||||||
|
hasControlCommand: boolean;
|
||||||
|
modeWhenAccessGroupsOff?: CommandGatingModeWhenAccessGroupsOff;
|
||||||
|
}): { commandAuthorized: boolean; shouldBlock: boolean } {
|
||||||
|
return resolveControlCommandGate({
|
||||||
|
useAccessGroups: params.useAccessGroups,
|
||||||
|
authorizers: [
|
||||||
|
{ configured: params.primaryConfigured, allowed: params.primaryAllowed },
|
||||||
|
{ configured: params.secondaryConfigured, allowed: params.secondaryAllowed },
|
||||||
|
],
|
||||||
|
allowTextCommands: true,
|
||||||
|
hasControlCommand: params.hasControlCommand,
|
||||||
|
modeWhenAccessGroupsOff: params.modeWhenAccessGroupsOff,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import {
|
||||||
} from "../../auto-reply/reply/history.js";
|
} from "../../auto-reply/reply/history.js";
|
||||||
import { finalizeInboundContext } from "../../auto-reply/reply/inbound-context.js";
|
import { finalizeInboundContext } from "../../auto-reply/reply/inbound-context.js";
|
||||||
import { buildMentionRegexes, matchesMentionPatterns } from "../../auto-reply/reply/mentions.js";
|
import { buildMentionRegexes, matchesMentionPatterns } from "../../auto-reply/reply/mentions.js";
|
||||||
import { resolveControlCommandGate } from "../../channels/command-gating.js";
|
import { resolveDualTextControlCommandGate } from "../../channels/command-gating.js";
|
||||||
import { logInboundDrop } from "../../channels/logging.js";
|
import { logInboundDrop } from "../../channels/logging.js";
|
||||||
import type { OpenClawConfig } from "../../config/config.js";
|
import type { OpenClawConfig } from "../../config/config.js";
|
||||||
import {
|
import {
|
||||||
|
|
@ -310,18 +310,15 @@ export function resolveIMessageInboundDecision(params: {
|
||||||
chatIdentifier,
|
chatIdentifier,
|
||||||
})
|
})
|
||||||
: false;
|
: false;
|
||||||
const hasControlCommandInMessage = hasControlCommand(messageText, params.cfg);
|
const { commandAuthorized, shouldBlock } = resolveDualTextControlCommandGate({
|
||||||
const commandGate = resolveControlCommandGate({
|
|
||||||
useAccessGroups,
|
useAccessGroups,
|
||||||
authorizers: [
|
primaryConfigured: commandDmAllowFrom.length > 0,
|
||||||
{ configured: commandDmAllowFrom.length > 0, allowed: ownerAllowedForCommands },
|
primaryAllowed: ownerAllowedForCommands,
|
||||||
{ configured: effectiveGroupAllowFrom.length > 0, allowed: groupAllowedForCommands },
|
secondaryConfigured: effectiveGroupAllowFrom.length > 0,
|
||||||
],
|
secondaryAllowed: groupAllowedForCommands,
|
||||||
allowTextCommands: true,
|
hasControlCommand: hasControlCommand(messageText, params.cfg),
|
||||||
hasControlCommand: hasControlCommandInMessage,
|
|
||||||
});
|
});
|
||||||
const commandAuthorized = commandGate.commandAuthorized;
|
if (isGroup && shouldBlock) {
|
||||||
if (isGroup && commandGate.shouldBlock) {
|
|
||||||
if (params.logVerbose) {
|
if (params.logVerbose) {
|
||||||
logInboundDrop({
|
logInboundDrop({
|
||||||
log: params.logVerbose,
|
log: params.logVerbose,
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,10 @@ export {
|
||||||
export { isSilentReplyText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
|
export { isSilentReplyText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
|
||||||
export type { ReplyPayload } from "../auto-reply/types.js";
|
export type { ReplyPayload } from "../auto-reply/types.js";
|
||||||
export { mergeAllowlist, summarizeMapping } from "../channels/allowlists/resolve-utils.js";
|
export { mergeAllowlist, summarizeMapping } from "../channels/allowlists/resolve-utils.js";
|
||||||
export { resolveControlCommandGate } from "../channels/command-gating.js";
|
export {
|
||||||
|
resolveControlCommandGate,
|
||||||
|
resolveDualTextControlCommandGate,
|
||||||
|
} from "../channels/command-gating.js";
|
||||||
export { logInboundDrop, logTypingFailure } from "../channels/logging.js";
|
export { logInboundDrop, logTypingFailure } from "../channels/logging.js";
|
||||||
export { resolveMentionGating } from "../channels/mention-gating.js";
|
export { resolveMentionGating } from "../channels/mention-gating.js";
|
||||||
export type { AllowlistMatch } from "../channels/plugins/allowlist-match.js";
|
export type { AllowlistMatch } from "../channels/plugins/allowlist-match.js";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue