fix(routing): require ids for slack and msteams allowlists

This commit is contained in:
Peter Steinberger
2026-03-13 01:43:48 +00:00
parent f36d8c09f1
commit de3e6a8c5b
12 changed files with 87 additions and 18 deletions

View File

@@ -175,6 +175,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
teamName,
conversationId,
channelName,
allowNameMatching: isDangerousNameMatchingEnabled(msteamsCfg),
});
const senderGroupPolicy = resolveSenderScopedGroupPolicy({
groupPolicy,

View File

@@ -50,7 +50,7 @@ describe("msteams policy", () => {
expect(res.allowed).toBe(false);
});
it("matches team and channel by name", () => {
it("blocks team and channel name matches by default", () => {
const cfg: MSTeamsConfig = {
teams: {
"My Team": {
@@ -69,6 +69,31 @@ describe("msteams policy", () => {
conversationId: "ignored",
});
expect(res.teamConfig).toBeUndefined();
expect(res.channelConfig).toBeUndefined();
expect(res.allowed).toBe(false);
});
it("matches team and channel by name when dangerous name matching is enabled", () => {
const cfg: MSTeamsConfig = {
teams: {
"My Team": {
requireMention: true,
channels: {
"General Chat": { requireMention: false },
},
},
},
};
const res = resolveMSTeamsRouteConfig({
cfg,
teamName: "My Team",
channelName: "General Chat",
conversationId: "ignored",
allowNameMatching: true,
});
expect(res.teamConfig?.requireMention).toBe(true);
expect(res.channelConfig?.requireMention).toBe(false);
expect(res.allowed).toBe(true);

View File

@@ -16,6 +16,7 @@ import {
resolveToolsBySender,
resolveChannelEntryMatchWithFallback,
resolveNestedAllowlistDecision,
isDangerousNameMatchingEnabled,
} from "openclaw/plugin-sdk/msteams";
export type MSTeamsResolvedRouteConfig = {
@@ -35,6 +36,7 @@ export function resolveMSTeamsRouteConfig(params: {
teamName?: string | null | undefined;
conversationId?: string | null | undefined;
channelName?: string | null | undefined;
allowNameMatching?: boolean;
}): MSTeamsResolvedRouteConfig {
const teamId = params.teamId?.trim();
const teamName = params.teamName?.trim();
@@ -44,8 +46,8 @@ export function resolveMSTeamsRouteConfig(params: {
const allowlistConfigured = Object.keys(teams).length > 0;
const teamCandidates = buildChannelKeyCandidates(
teamId,
teamName,
teamName ? normalizeChannelSlug(teamName) : undefined,
params.allowNameMatching ? teamName : undefined,
params.allowNameMatching && teamName ? normalizeChannelSlug(teamName) : undefined,
);
const teamMatch = resolveChannelEntryMatchWithFallback({
entries: teams,
@@ -58,8 +60,8 @@ export function resolveMSTeamsRouteConfig(params: {
const channelAllowlistConfigured = Object.keys(channels).length > 0;
const channelCandidates = buildChannelKeyCandidates(
conversationId,
channelName,
channelName ? normalizeChannelSlug(channelName) : undefined,
params.allowNameMatching ? channelName : undefined,
params.allowNameMatching && channelName ? normalizeChannelSlug(channelName) : undefined,
);
const channelMatch = resolveChannelEntryMatchWithFallback({
entries: channels,
@@ -101,6 +103,7 @@ export function resolveMSTeamsGroupToolPolicy(
const groupId = params.groupId?.trim();
const groupChannel = params.groupChannel?.trim();
const groupSpace = params.groupSpace?.trim();
const allowNameMatching = isDangerousNameMatchingEnabled(cfg);
const resolved = resolveMSTeamsRouteConfig({
cfg,
@@ -108,6 +111,7 @@ export function resolveMSTeamsGroupToolPolicy(
teamName: groupSpace,
conversationId: groupId,
channelName: groupChannel,
allowNameMatching,
});
if (resolved.channelConfig) {
@@ -158,8 +162,8 @@ export function resolveMSTeamsGroupToolPolicy(
const channelCandidates = buildChannelKeyCandidates(
groupId,
groupChannel,
groupChannel ? normalizeChannelSlug(groupChannel) : undefined,
allowNameMatching ? groupChannel : undefined,
allowNameMatching && groupChannel ? normalizeChannelSlug(groupChannel) : undefined,
);
for (const teamConfig of Object.values(cfg.teams ?? {})) {
const match = resolveChannelEntryMatchWithFallback({