mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
refactor: share matched group policy evaluation
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveNextcloudTalkAllowlistMatch } from "./policy.js";
|
||||
import { resolveNextcloudTalkAllowlistMatch, resolveNextcloudTalkGroupAllow } from "./policy.js";
|
||||
|
||||
describe("nextcloud-talk policy", () => {
|
||||
describe("resolveNextcloudTalkAllowlistMatch", () => {
|
||||
@@ -30,4 +30,109 @@ describe("nextcloud-talk policy", () => {
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveNextcloudTalkGroupAllow", () => {
|
||||
it("blocks disabled policy", () => {
|
||||
expect(
|
||||
resolveNextcloudTalkGroupAllow({
|
||||
groupPolicy: "disabled",
|
||||
outerAllowFrom: ["owner"],
|
||||
innerAllowFrom: ["room-user"],
|
||||
senderId: "owner",
|
||||
}),
|
||||
).toEqual({
|
||||
allowed: false,
|
||||
outerMatch: { allowed: false },
|
||||
innerMatch: { allowed: false },
|
||||
});
|
||||
});
|
||||
|
||||
it("allows open policy", () => {
|
||||
expect(
|
||||
resolveNextcloudTalkGroupAllow({
|
||||
groupPolicy: "open",
|
||||
outerAllowFrom: [],
|
||||
innerAllowFrom: [],
|
||||
senderId: "owner",
|
||||
}),
|
||||
).toEqual({
|
||||
allowed: true,
|
||||
outerMatch: { allowed: true },
|
||||
innerMatch: { allowed: true },
|
||||
});
|
||||
});
|
||||
|
||||
it("blocks allowlist mode when both outer and inner allowlists are empty", () => {
|
||||
expect(
|
||||
resolveNextcloudTalkGroupAllow({
|
||||
groupPolicy: "allowlist",
|
||||
outerAllowFrom: [],
|
||||
innerAllowFrom: [],
|
||||
senderId: "owner",
|
||||
}),
|
||||
).toEqual({
|
||||
allowed: false,
|
||||
outerMatch: { allowed: false },
|
||||
innerMatch: { allowed: false },
|
||||
});
|
||||
});
|
||||
|
||||
it("requires inner match when only room-specific allowlist is configured", () => {
|
||||
expect(
|
||||
resolveNextcloudTalkGroupAllow({
|
||||
groupPolicy: "allowlist",
|
||||
outerAllowFrom: [],
|
||||
innerAllowFrom: ["room-user"],
|
||||
senderId: "room-user",
|
||||
}),
|
||||
).toEqual({
|
||||
allowed: true,
|
||||
outerMatch: { allowed: false },
|
||||
innerMatch: { allowed: true, matchKey: "room-user", matchSource: "id" },
|
||||
});
|
||||
});
|
||||
|
||||
it("blocks when outer allowlist misses even if inner allowlist matches", () => {
|
||||
expect(
|
||||
resolveNextcloudTalkGroupAllow({
|
||||
groupPolicy: "allowlist",
|
||||
outerAllowFrom: ["team-owner"],
|
||||
innerAllowFrom: ["room-user"],
|
||||
senderId: "room-user",
|
||||
}),
|
||||
).toEqual({
|
||||
allowed: false,
|
||||
outerMatch: { allowed: false },
|
||||
innerMatch: { allowed: true, matchKey: "room-user", matchSource: "id" },
|
||||
});
|
||||
});
|
||||
|
||||
it("allows when both outer and inner allowlists match", () => {
|
||||
expect(
|
||||
resolveNextcloudTalkGroupAllow({
|
||||
groupPolicy: "allowlist",
|
||||
outerAllowFrom: ["team-owner"],
|
||||
innerAllowFrom: ["room-user"],
|
||||
senderId: "team-owner",
|
||||
}),
|
||||
).toEqual({
|
||||
allowed: false,
|
||||
outerMatch: { allowed: true, matchKey: "team-owner", matchSource: "id" },
|
||||
innerMatch: { allowed: false },
|
||||
});
|
||||
|
||||
expect(
|
||||
resolveNextcloudTalkGroupAllow({
|
||||
groupPolicy: "allowlist",
|
||||
outerAllowFrom: ["shared-user"],
|
||||
innerAllowFrom: ["shared-user"],
|
||||
senderId: "shared-user",
|
||||
}),
|
||||
).toEqual({
|
||||
allowed: true,
|
||||
outerMatch: { allowed: true, matchKey: "shared-user", matchSource: "id" },
|
||||
innerMatch: { allowed: true, matchKey: "shared-user", matchSource: "id" },
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
} from "openclaw/plugin-sdk/nextcloud-talk";
|
||||
import {
|
||||
buildChannelKeyCandidates,
|
||||
evaluateMatchedGroupAccessForPolicy,
|
||||
normalizeChannelSlug,
|
||||
resolveChannelEntryMatchWithFallback,
|
||||
resolveMentionGatingWithBypass,
|
||||
@@ -128,19 +129,8 @@ export function resolveNextcloudTalkGroupAllow(params: {
|
||||
innerAllowFrom: Array<string | number> | undefined;
|
||||
senderId: string;
|
||||
}): { allowed: boolean; outerMatch: AllowlistMatch; innerMatch: AllowlistMatch } {
|
||||
if (params.groupPolicy === "disabled") {
|
||||
return { allowed: false, outerMatch: { allowed: false }, innerMatch: { allowed: false } };
|
||||
}
|
||||
if (params.groupPolicy === "open") {
|
||||
return { allowed: true, outerMatch: { allowed: true }, innerMatch: { allowed: true } };
|
||||
}
|
||||
|
||||
const outerAllow = normalizeNextcloudTalkAllowlist(params.outerAllowFrom);
|
||||
const innerAllow = normalizeNextcloudTalkAllowlist(params.innerAllowFrom);
|
||||
if (outerAllow.length === 0 && innerAllow.length === 0) {
|
||||
return { allowed: false, outerMatch: { allowed: false }, innerMatch: { allowed: false } };
|
||||
}
|
||||
|
||||
const outerMatch = resolveNextcloudTalkAllowlistMatch({
|
||||
allowFrom: params.outerAllowFrom,
|
||||
senderId: params.senderId,
|
||||
@@ -149,14 +139,32 @@ export function resolveNextcloudTalkGroupAllow(params: {
|
||||
allowFrom: params.innerAllowFrom,
|
||||
senderId: params.senderId,
|
||||
});
|
||||
const allowed = resolveNestedAllowlistDecision({
|
||||
outerConfigured: outerAllow.length > 0 || innerAllow.length > 0,
|
||||
outerMatched: outerAllow.length > 0 ? outerMatch.allowed : true,
|
||||
innerConfigured: innerAllow.length > 0,
|
||||
innerMatched: innerMatch.allowed,
|
||||
const access = evaluateMatchedGroupAccessForPolicy({
|
||||
groupPolicy: params.groupPolicy,
|
||||
allowlistConfigured: outerAllow.length > 0 || innerAllow.length > 0,
|
||||
allowlistMatched: resolveNestedAllowlistDecision({
|
||||
outerConfigured: outerAllow.length > 0 || innerAllow.length > 0,
|
||||
outerMatched: outerAllow.length > 0 ? outerMatch.allowed : true,
|
||||
innerConfigured: innerAllow.length > 0,
|
||||
innerMatched: innerMatch.allowed,
|
||||
}),
|
||||
});
|
||||
|
||||
return { allowed, outerMatch, innerMatch };
|
||||
return {
|
||||
allowed: access.allowed,
|
||||
outerMatch:
|
||||
params.groupPolicy === "open"
|
||||
? { allowed: true }
|
||||
: params.groupPolicy === "disabled"
|
||||
? { allowed: false }
|
||||
: outerMatch,
|
||||
innerMatch:
|
||||
params.groupPolicy === "open"
|
||||
? { allowed: true }
|
||||
: params.groupPolicy === "disabled"
|
||||
? { allowed: false }
|
||||
: innerMatch,
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveNextcloudTalkMentionGate(params: {
|
||||
|
||||
Reference in New Issue
Block a user