156 lines
3.8 KiB
TypeScript
156 lines
3.8 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
import type { OpenClawConfig } from "../config/config.js";
|
|
import { setActivePluginRegistry } from "../plugins/runtime.js";
|
|
import { createOutboundTestPlugin, createTestRegistry } from "../test-utils/channel-plugins.js";
|
|
import { resolveCommandAuthorization } from "./command-auth.js";
|
|
import type { MsgContext } from "./templating.js";
|
|
|
|
const createRegistry = () =>
|
|
createTestRegistry([
|
|
{
|
|
pluginId: "discord",
|
|
plugin: createOutboundTestPlugin({ id: "discord", outbound: { deliveryMode: "direct" } }),
|
|
source: "test",
|
|
},
|
|
]);
|
|
|
|
beforeEach(() => {
|
|
setActivePluginRegistry(createRegistry());
|
|
});
|
|
|
|
afterEach(() => {
|
|
setActivePluginRegistry(createRegistry());
|
|
});
|
|
|
|
describe("senderIsOwner only reflects explicit owner authorization", () => {
|
|
it("does not treat direct-message senders as owners when no ownerAllowFrom is configured", () => {
|
|
const cfg = {
|
|
channels: { discord: {} },
|
|
} as OpenClawConfig;
|
|
|
|
const ctx = {
|
|
Provider: "discord",
|
|
Surface: "discord",
|
|
ChatType: "direct",
|
|
From: "discord:123",
|
|
SenderId: "123",
|
|
} as MsgContext;
|
|
|
|
const auth = resolveCommandAuthorization({
|
|
ctx,
|
|
cfg,
|
|
commandAuthorized: true,
|
|
});
|
|
|
|
expect(auth.senderIsOwner).toBe(false);
|
|
expect(auth.isAuthorizedSender).toBe(true);
|
|
});
|
|
|
|
it("does not treat group-chat senders as owners when no ownerAllowFrom is configured", () => {
|
|
const cfg = {
|
|
channels: { discord: {} },
|
|
} as OpenClawConfig;
|
|
|
|
const ctx = {
|
|
Provider: "discord",
|
|
Surface: "discord",
|
|
ChatType: "group",
|
|
From: "discord:123",
|
|
SenderId: "123",
|
|
} as MsgContext;
|
|
|
|
const auth = resolveCommandAuthorization({
|
|
ctx,
|
|
cfg,
|
|
commandAuthorized: true,
|
|
});
|
|
|
|
expect(auth.senderIsOwner).toBe(false);
|
|
expect(auth.isAuthorizedSender).toBe(true);
|
|
});
|
|
|
|
it("senderIsOwner is false when ownerAllowFrom is configured and sender does not match", () => {
|
|
const cfg = {
|
|
channels: { discord: {} },
|
|
commands: { ownerAllowFrom: ["456"] },
|
|
} as OpenClawConfig;
|
|
|
|
const ctx = {
|
|
Provider: "discord",
|
|
Surface: "discord",
|
|
From: "discord:789",
|
|
SenderId: "789",
|
|
} as MsgContext;
|
|
|
|
const auth = resolveCommandAuthorization({
|
|
ctx,
|
|
cfg,
|
|
commandAuthorized: true,
|
|
});
|
|
|
|
expect(auth.senderIsOwner).toBe(false);
|
|
});
|
|
|
|
it("senderIsOwner is true when ownerAllowFrom matches sender", () => {
|
|
const cfg = {
|
|
channels: { discord: {} },
|
|
commands: { ownerAllowFrom: ["456"] },
|
|
} as OpenClawConfig;
|
|
|
|
const ctx = {
|
|
Provider: "discord",
|
|
Surface: "discord",
|
|
From: "discord:456",
|
|
SenderId: "456",
|
|
} as MsgContext;
|
|
|
|
const auth = resolveCommandAuthorization({
|
|
ctx,
|
|
cfg,
|
|
commandAuthorized: true,
|
|
});
|
|
|
|
expect(auth.senderIsOwner).toBe(true);
|
|
});
|
|
|
|
it("senderIsOwner is true when ownerAllowFrom is wildcard (*)", () => {
|
|
const cfg = {
|
|
channels: { discord: {} },
|
|
commands: { ownerAllowFrom: ["*"] },
|
|
} as OpenClawConfig;
|
|
|
|
const ctx = {
|
|
Provider: "discord",
|
|
Surface: "discord",
|
|
From: "discord:anyone",
|
|
SenderId: "anyone",
|
|
} as MsgContext;
|
|
|
|
const auth = resolveCommandAuthorization({
|
|
ctx,
|
|
cfg,
|
|
commandAuthorized: true,
|
|
});
|
|
|
|
expect(auth.senderIsOwner).toBe(true);
|
|
});
|
|
|
|
it("senderIsOwner is true for internal operator.admin sessions", () => {
|
|
const cfg = {} as OpenClawConfig;
|
|
|
|
const ctx = {
|
|
Provider: "webchat",
|
|
Surface: "webchat",
|
|
GatewayClientScopes: ["operator.admin"],
|
|
} as MsgContext;
|
|
|
|
const auth = resolveCommandAuthorization({
|
|
ctx,
|
|
cfg,
|
|
commandAuthorized: true,
|
|
});
|
|
|
|
expect(auth.senderIsOwner).toBe(true);
|
|
});
|
|
});
|