import type { OpenClawConfig, PluginRuntime } from "openclaw/plugin-sdk"; import type { WecomAgentConfig, WecomBotConfig } from "../types/index.js"; import { isWecomSenderAllowed, normalizeWecomAllowFromEntry } from "../domain/policies.js"; type WecomCommandAuthAccountConfig = Pick | Pick; export async function resolveWecomCommandAuthorization(params: { core: PluginRuntime; cfg: OpenClawConfig; accountConfig: WecomCommandAuthAccountConfig; rawBody: string; senderUserId: string; }): Promise<{ shouldComputeAuth: boolean; dmPolicy: "pairing" | "allowlist" | "open" | "disabled"; senderAllowed: boolean; authorizerConfigured: boolean; commandAuthorized: boolean | undefined; effectiveAllowFrom: string[]; }> { const { core, cfg, accountConfig, rawBody, senderUserId } = params; const dmPolicy = (accountConfig.dm?.policy ?? "pairing") as "pairing" | "allowlist" | "open" | "disabled"; const configAllowFrom = (accountConfig.dm?.allowFrom ?? []).map((v) => String(v)); const shouldComputeAuth = core.channel.commands.shouldComputeCommandAuthorized(rawBody, cfg); // WeCom channel currently does NOT support the `openclaw pairing` CLI workflow // ("Channel wecom does not support pairing"). So we must not rely on pairing // store approvals for command authorization here. // // Policy semantics: // - open: commands are allowed for everyone by default (unless higher-level access-groups deny). // - allowlist: commands require allowFrom entries. // - pairing: treated the same as allowlist for WeCom (since pairing CLI is unsupported). const effectiveAllowFrom = dmPolicy === "open" ? ["*"] : configAllowFrom; const senderAllowed = isWecomSenderAllowed(senderUserId, effectiveAllowFrom); const allowAllConfigured = effectiveAllowFrom.some((entry) => normalizeWecomAllowFromEntry(entry) === "*"); const authorizerConfigured = allowAllConfigured || effectiveAllowFrom.length > 0; const useAccessGroups = cfg.commands?.useAccessGroups !== false; const commandAuthorized = shouldComputeAuth ? core.channel.commands.resolveCommandAuthorizedFromAuthorizers({ useAccessGroups, authorizers: [{ configured: authorizerConfigured, allowed: senderAllowed }], }) : undefined; return { shouldComputeAuth, dmPolicy, senderAllowed, authorizerConfigured, commandAuthorized, effectiveAllowFrom, }; } export function buildWecomUnauthorizedCommandPrompt(params: { senderUserId: string; dmPolicy: "pairing" | "allowlist" | "open" | "disabled"; scope: "bot" | "agent"; }): string { const user = params.senderUserId || "unknown"; const policy = params.dmPolicy; const scopeLabel = params.scope === "bot" ? "Bot(智能机器人)" : "Agent(自建应用)"; const dmPrefix = params.scope === "bot" ? "channels.wecom.bot.dm" : "channels.wecom.agent.dm"; const allowCmd = (value: string) => `openclaw config set ${dmPrefix}.allowFrom '${value}'`; const policyCmd = (value: string) => `openclaw config set ${dmPrefix}.policy "${value}"`; if (policy === "disabled") { return [ `无权限执行命令(${scopeLabel} 已禁用:dm.policy=disabled)`, `触发者:${user}`, `管理员:${policyCmd("open")}(全放开)或 ${policyCmd("allowlist")}(白名单)`, ].join("\n"); } // WeCom 不支持 pairing CLI,因此这里统一给出“open / allowlist”两种明确的配置指令 return [ `无权限执行命令(入口:${scopeLabel},userid:${user})`, `管理员全放开:${policyCmd("open")}`, `管理员放行该用户:${policyCmd("allowlist")}`, `然后设置白名单:${allowCmd(JSON.stringify([user]))}`, `如果仍被拦截:检查 commands.useAccessGroups/访问组`, ].join("\n"); }