mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 17:01:22 +00:00
refactor(security): centralize channel allowlist auth policy
This commit is contained in:
@@ -55,6 +55,16 @@ describe("resolveGroupAllowFromSources", () => {
|
||||
}),
|
||||
).toEqual(["owner", "owner2"]);
|
||||
});
|
||||
|
||||
it("can disable fallback to DM allowlist", () => {
|
||||
expect(
|
||||
resolveGroupAllowFromSources({
|
||||
allowFrom: ["owner", "owner2"],
|
||||
groupAllowFrom: [],
|
||||
fallbackToAllowFrom: false,
|
||||
}),
|
||||
).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("firstDefined", () => {
|
||||
|
||||
@@ -12,10 +12,16 @@ export function mergeDmAllowFromSources(params: {
|
||||
export function resolveGroupAllowFromSources(params: {
|
||||
allowFrom?: Array<string | number>;
|
||||
groupAllowFrom?: Array<string | number>;
|
||||
fallbackToAllowFrom?: boolean;
|
||||
}): string[] {
|
||||
const scoped =
|
||||
params.groupAllowFrom && params.groupAllowFrom.length > 0
|
||||
const explicitGroupAllowFrom =
|
||||
Array.isArray(params.groupAllowFrom) && params.groupAllowFrom.length > 0
|
||||
? params.groupAllowFrom
|
||||
: undefined;
|
||||
const scoped = explicitGroupAllowFrom
|
||||
? explicitGroupAllowFrom
|
||||
: params.fallbackToAllowFrom === false
|
||||
? []
|
||||
: (params.allowFrom ?? []);
|
||||
return scoped.map((value) => String(value).trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
resolveChannelGroupRequireMention,
|
||||
} from "../../config/group-policy.js";
|
||||
import { resolveAgentRoute } from "../../routing/resolve-route.js";
|
||||
import { resolveEffectiveAllowFromLists } from "../../security/dm-policy-shared.js";
|
||||
import { truncateUtf16Safe } from "../../utils.js";
|
||||
import {
|
||||
formatIMessageChatTarget,
|
||||
@@ -138,14 +139,14 @@ export function resolveIMessageInboundDecision(params: {
|
||||
}
|
||||
|
||||
const groupId = isGroup ? groupIdCandidate : undefined;
|
||||
const storeAllowFrom = params.dmPolicy === "allowlist" ? [] : params.storeAllowFrom;
|
||||
const effectiveDmAllowFrom = Array.from(new Set([...params.allowFrom, ...storeAllowFrom]))
|
||||
.map((v) => String(v).trim())
|
||||
.filter(Boolean);
|
||||
// Keep DM pairing-store authorization scoped to DMs; group access must come from explicit group allowlist config.
|
||||
const effectiveGroupAllowFrom = Array.from(new Set(params.groupAllowFrom))
|
||||
.map((v) => String(v).trim())
|
||||
.filter(Boolean);
|
||||
const { effectiveAllowFrom: effectiveDmAllowFrom, effectiveGroupAllowFrom } =
|
||||
resolveEffectiveAllowFromLists({
|
||||
allowFrom: params.allowFrom,
|
||||
groupAllowFrom: params.groupAllowFrom,
|
||||
storeAllowFrom: params.storeAllowFrom,
|
||||
dmPolicy: params.dmPolicy,
|
||||
groupAllowFromFallbackToAllowFrom: false,
|
||||
});
|
||||
|
||||
if (isGroup) {
|
||||
if (params.groupPolicy === "disabled") {
|
||||
|
||||
@@ -54,6 +54,17 @@ describe("security/dm-policy-shared", () => {
|
||||
expect(lists.effectiveGroupAllowFrom).toEqual(["owner"]);
|
||||
});
|
||||
|
||||
it("can keep group allowlist empty when fallback is disabled", () => {
|
||||
const lists = resolveEffectiveAllowFromLists({
|
||||
allowFrom: ["owner"],
|
||||
groupAllowFrom: [],
|
||||
storeAllowFrom: ["paired-user"],
|
||||
groupAllowFromFallbackToAllowFrom: false,
|
||||
});
|
||||
expect(lists.effectiveAllowFrom).toEqual(["owner", "paired-user"]);
|
||||
expect(lists.effectiveGroupAllowFrom).toEqual([]);
|
||||
});
|
||||
|
||||
it("excludes storeAllowFrom when dmPolicy is allowlist", () => {
|
||||
const lists = resolveEffectiveAllowFromLists({
|
||||
allowFrom: ["+1111"],
|
||||
|
||||
@@ -8,6 +8,7 @@ export function resolveEffectiveAllowFromLists(params: {
|
||||
groupAllowFrom?: Array<string | number> | null;
|
||||
storeAllowFrom?: Array<string | number> | null;
|
||||
dmPolicy?: string | null;
|
||||
groupAllowFromFallbackToAllowFrom?: boolean | null;
|
||||
}): {
|
||||
effectiveAllowFrom: string[];
|
||||
effectiveGroupAllowFrom: string[];
|
||||
@@ -27,6 +28,7 @@ export function resolveEffectiveAllowFromLists(params: {
|
||||
resolveGroupAllowFromSources({
|
||||
allowFrom,
|
||||
groupAllowFrom,
|
||||
fallbackToAllowFrom: params.groupAllowFromFallbackToAllowFrom ?? undefined,
|
||||
}),
|
||||
);
|
||||
return { effectiveAllowFrom, effectiveGroupAllowFrom };
|
||||
@@ -87,6 +89,7 @@ export function resolveDmGroupAccessWithLists(params: {
|
||||
allowFrom?: Array<string | number> | null;
|
||||
groupAllowFrom?: Array<string | number> | null;
|
||||
storeAllowFrom?: Array<string | number> | null;
|
||||
groupAllowFromFallbackToAllowFrom?: boolean | null;
|
||||
isSenderAllowed: (allowFrom: string[]) => boolean;
|
||||
}): {
|
||||
decision: DmGroupAccessDecision;
|
||||
@@ -99,6 +102,7 @@ export function resolveDmGroupAccessWithLists(params: {
|
||||
groupAllowFrom: params.groupAllowFrom,
|
||||
storeAllowFrom: params.storeAllowFrom,
|
||||
dmPolicy: params.dmPolicy,
|
||||
groupAllowFromFallbackToAllowFrom: params.groupAllowFromFallbackToAllowFrom,
|
||||
});
|
||||
const access = resolveDmGroupAccessDecision({
|
||||
isGroup: params.isGroup,
|
||||
|
||||
@@ -61,5 +61,6 @@ export async function buildTelegramMessageContextForTest(
|
||||
groupConfig: { requireMention: false },
|
||||
topicConfig: undefined,
|
||||
})),
|
||||
sendChatActionHandler: { sendChatAction: vi.fn() } as never,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user