mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 00:17:27 +00:00
fix(security): keep DM pairing allowlists out of group auth
This commit is contained in:
37
extensions/mattermost/src/mattermost/monitor.authz.test.ts
Normal file
37
extensions/mattermost/src/mattermost/monitor.authz.test.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveMattermostEffectiveAllowFromLists } from "./monitor.js";
|
||||
|
||||
describe("mattermost monitor authz", () => {
|
||||
it("keeps DM allowlist merged with pairing-store entries", () => {
|
||||
const resolved = resolveMattermostEffectiveAllowFromLists({
|
||||
dmPolicy: "pairing",
|
||||
allowFrom: ["@trusted-user"],
|
||||
groupAllowFrom: ["@group-owner"],
|
||||
storeAllowFrom: ["user:attacker"],
|
||||
});
|
||||
|
||||
expect(resolved.effectiveAllowFrom).toEqual(["trusted-user", "attacker"]);
|
||||
});
|
||||
|
||||
it("uses explicit groupAllowFrom without pairing-store inheritance", () => {
|
||||
const resolved = resolveMattermostEffectiveAllowFromLists({
|
||||
dmPolicy: "pairing",
|
||||
allowFrom: ["@trusted-user"],
|
||||
groupAllowFrom: ["@group-owner"],
|
||||
storeAllowFrom: ["user:attacker"],
|
||||
});
|
||||
|
||||
expect(resolved.effectiveGroupAllowFrom).toEqual(["group-owner"]);
|
||||
});
|
||||
|
||||
it("does not inherit pairing-store entries into group allowlist", () => {
|
||||
const resolved = resolveMattermostEffectiveAllowFromLists({
|
||||
dmPolicy: "pairing",
|
||||
allowFrom: ["@trusted-user"],
|
||||
storeAllowFrom: ["user:attacker"],
|
||||
});
|
||||
|
||||
expect(resolved.effectiveAllowFrom).toEqual(["trusted-user", "attacker"]);
|
||||
expect(resolved.effectiveGroupAllowFrom).toEqual(["trusted-user"]);
|
||||
});
|
||||
});
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
isDangerousNameMatchingEnabled,
|
||||
resolveControlCommandGate,
|
||||
resolveDmGroupAccessWithLists,
|
||||
resolveEffectiveAllowFromLists,
|
||||
resolveAllowlistProviderRuntimeGroupPolicy,
|
||||
resolveDefaultGroupPolicy,
|
||||
resolveChannelMediaMaxBytes,
|
||||
@@ -150,6 +151,23 @@ function normalizeAllowList(entries: Array<string | number>): string[] {
|
||||
return Array.from(new Set(normalized));
|
||||
}
|
||||
|
||||
export function resolveMattermostEffectiveAllowFromLists(params: {
|
||||
allowFrom?: Array<string | number> | null;
|
||||
groupAllowFrom?: Array<string | number> | null;
|
||||
storeAllowFrom?: Array<string | number> | null;
|
||||
dmPolicy?: string | null;
|
||||
}): {
|
||||
effectiveAllowFrom: string[];
|
||||
effectiveGroupAllowFrom: string[];
|
||||
} {
|
||||
return resolveEffectiveAllowFromLists({
|
||||
allowFrom: normalizeAllowList(params.allowFrom ?? []),
|
||||
groupAllowFrom: normalizeAllowList(params.groupAllowFrom ?? []),
|
||||
storeAllowFrom: normalizeAllowList(params.storeAllowFrom ?? []),
|
||||
dmPolicy: params.dmPolicy,
|
||||
});
|
||||
}
|
||||
|
||||
function isSenderAllowed(params: {
|
||||
senderId: string;
|
||||
senderName?: string;
|
||||
@@ -400,20 +418,18 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
senderId;
|
||||
const rawText = post.message?.trim() || "";
|
||||
const dmPolicy = account.config.dmPolicy ?? "pairing";
|
||||
const configAllowFrom = normalizeAllowList(account.config.allowFrom ?? []);
|
||||
const configGroupAllowFrom = normalizeAllowList(account.config.groupAllowFrom ?? []);
|
||||
const storeAllowFrom = normalizeAllowList(
|
||||
dmPolicy === "allowlist"
|
||||
? []
|
||||
: await core.channel.pairing.readAllowFromStore("mattermost").catch(() => []),
|
||||
);
|
||||
const effectiveAllowFrom = Array.from(new Set([...configAllowFrom, ...storeAllowFrom]));
|
||||
const effectiveGroupAllowFrom = Array.from(
|
||||
new Set([
|
||||
...(configGroupAllowFrom.length > 0 ? configGroupAllowFrom : configAllowFrom),
|
||||
...storeAllowFrom,
|
||||
]),
|
||||
);
|
||||
const { effectiveAllowFrom, effectiveGroupAllowFrom } =
|
||||
resolveMattermostEffectiveAllowFromLists({
|
||||
dmPolicy,
|
||||
allowFrom: account.config.allowFrom,
|
||||
groupAllowFrom: account.config.groupAllowFrom,
|
||||
storeAllowFrom,
|
||||
});
|
||||
const allowTextCommands = core.channel.commands.shouldHandleTextCommands({
|
||||
cfg,
|
||||
surface: "mattermost",
|
||||
|
||||
Reference in New Issue
Block a user