mirror of https://github.com/openclaw/openclaw.git
fix: honor allowlist default account
This commit is contained in:
parent
42ffdf882f
commit
cc0987f7b1
|
|
@ -58,6 +58,22 @@ type AllowlistCommand =
|
|||
const ACTIONS = new Set(["list", "add", "remove"]);
|
||||
const SCOPES = new Set<AllowlistScope>(["dm", "group", "all"]);
|
||||
|
||||
function resolveAllowlistAccountId(params: {
|
||||
cfg: OpenClawConfig;
|
||||
channelId: ChannelId;
|
||||
parsedAccount?: string;
|
||||
ctxAccountId?: string;
|
||||
}): string {
|
||||
const explicitAccountId = normalizeOptionalAccountId(params.parsedAccount);
|
||||
if (explicitAccountId) {
|
||||
return explicitAccountId;
|
||||
}
|
||||
const plugin = getChannelPlugin(params.channelId);
|
||||
const configuredDefaultAccountId = plugin?.config.defaultAccountId?.(params.cfg)?.trim();
|
||||
const ctxAccountId = normalizeOptionalAccountId(params.ctxAccountId);
|
||||
return configuredDefaultAccountId || ctxAccountId || DEFAULT_ACCOUNT_ID;
|
||||
}
|
||||
|
||||
function parseAllowlistCommand(raw: string): AllowlistCommand | null {
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed.toLowerCase().startsWith("/allowlist")) {
|
||||
|
|
@ -276,7 +292,12 @@ export const handleAllowlistCommand: CommandHandler = async (params, allowTextCo
|
|||
},
|
||||
};
|
||||
}
|
||||
const accountId = normalizeAccountId(parsed.account ?? params.ctx.AccountId);
|
||||
const accountId = resolveAllowlistAccountId({
|
||||
cfg: params.cfg,
|
||||
channelId,
|
||||
parsedAccount: parsed.account,
|
||||
ctxAccountId: params.ctx.AccountId,
|
||||
});
|
||||
const plugin = getChannelPlugin(channelId);
|
||||
|
||||
if (parsed.action === "list") {
|
||||
|
|
@ -464,7 +485,7 @@ export const handleAllowlistCommand: CommandHandler = async (params, allowTextCo
|
|||
cfg: params.cfg,
|
||||
channel: params.command.channel,
|
||||
channelId,
|
||||
accountId: params.ctx.AccountId,
|
||||
accountId,
|
||||
gatewayClientScopes: params.ctx.GatewayClientScopes,
|
||||
target: editResult.writeTarget,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2169,6 +2169,48 @@ describe("handleCommands /allowlist", () => {
|
|||
}
|
||||
});
|
||||
|
||||
it("uses the configured default account for omitted-account /allowlist list", async () => {
|
||||
setActivePluginRegistry(
|
||||
createTestRegistry([
|
||||
{
|
||||
pluginId: "telegram",
|
||||
source: "test",
|
||||
plugin: {
|
||||
...telegramCommandTestPlugin,
|
||||
config: {
|
||||
...telegramCommandTestPlugin.config,
|
||||
defaultAccountId: (cfg) =>
|
||||
((cfg.channels?.telegram as { defaultAccount?: string } | undefined)?.defaultAccount ??
|
||||
DEFAULT_ACCOUNT_ID),
|
||||
},
|
||||
},
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
const cfg = {
|
||||
commands: { text: true, config: true },
|
||||
channels: {
|
||||
telegram: {
|
||||
defaultAccount: "work",
|
||||
accounts: { work: { allowFrom: ["123"] } },
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
readChannelAllowFromStoreMock.mockResolvedValueOnce([]);
|
||||
|
||||
const params = buildPolicyParams("/allowlist list dm", cfg, {
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
AccountId: undefined,
|
||||
});
|
||||
const result = await handleCommands(params);
|
||||
|
||||
expect(result.shouldContinue).toBe(false);
|
||||
expect(result.reply?.text).toContain("Channel: telegram (account work)");
|
||||
expect(result.reply?.text).toContain("DM allowFrom (config): 123");
|
||||
});
|
||||
|
||||
it("blocks config-targeted /allowlist edits when the target account disables writes", async () => {
|
||||
const previousWriteCount = writeConfigFileMock.mock.calls.length;
|
||||
const cfg = {
|
||||
|
|
@ -2199,6 +2241,55 @@ describe("handleCommands /allowlist", () => {
|
|||
expect(writeConfigFileMock.mock.calls.length).toBe(previousWriteCount);
|
||||
});
|
||||
|
||||
it("honors the configured default account when gating omitted-account /allowlist config edits", async () => {
|
||||
setActivePluginRegistry(
|
||||
createTestRegistry([
|
||||
{
|
||||
pluginId: "telegram",
|
||||
source: "test",
|
||||
plugin: {
|
||||
...telegramCommandTestPlugin,
|
||||
config: {
|
||||
...telegramCommandTestPlugin.config,
|
||||
defaultAccountId: (cfg) =>
|
||||
((cfg.channels?.telegram as { defaultAccount?: string } | undefined)?.defaultAccount ??
|
||||
DEFAULT_ACCOUNT_ID),
|
||||
},
|
||||
},
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
const previousWriteCount = writeConfigFileMock.mock.calls.length;
|
||||
const cfg = {
|
||||
commands: { text: true, config: true },
|
||||
channels: {
|
||||
telegram: {
|
||||
defaultAccount: "work",
|
||||
configWrites: true,
|
||||
accounts: {
|
||||
work: { configWrites: false, allowFrom: ["123"] },
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
readConfigFileSnapshotMock.mockResolvedValueOnce({
|
||||
valid: true,
|
||||
parsed: structuredClone(cfg),
|
||||
});
|
||||
const params = buildPolicyParams("/allowlist add dm --config 789", cfg, {
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
AccountId: undefined,
|
||||
});
|
||||
params.command.senderIsOwner = true;
|
||||
const result = await handleCommands(params);
|
||||
|
||||
expect(result.shouldContinue).toBe(false);
|
||||
expect(result.reply?.text).toContain("channels.telegram.accounts.work.configWrites=true");
|
||||
expect(writeConfigFileMock.mock.calls.length).toBe(previousWriteCount);
|
||||
});
|
||||
|
||||
it("blocks allowlist writes from authorized non-owner senders, including cross-channel targets", async () => {
|
||||
const cfg = {
|
||||
commands: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue