From 551321b5429852d4463a66656a824e3878697dde Mon Sep 17 00:00:00 2001 From: matevip Date: Sun, 31 May 2026 07:58:59 +0800 Subject: [PATCH] fix(wiki): make pageType permission service a mandatory dependency --- .../java/vip/mate/wiki/tool/WikiTool.java | 23 +++++++++---------- .../wiki/tool/WikiToolKbNameRoutingTest.java | 8 ++++++- .../wiki/tool/WikiToolPermissionTest.java | 4 +--- .../wiki/tool/WikiToolSpringBindingTest.java | 8 ++++++- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/mateclaw-server/src/main/java/vip/mate/wiki/tool/WikiTool.java b/mateclaw-server/src/main/java/vip/mate/wiki/tool/WikiTool.java index cd225274..fe8dca56 100644 --- a/mateclaw-server/src/main/java/vip/mate/wiki/tool/WikiTool.java +++ b/mateclaw-server/src/main/java/vip/mate/wiki/tool/WikiTool.java @@ -79,22 +79,24 @@ public class WikiTool { private WikiTransformationAggregator transformationAggregator; /** - * Per-agent pageType permission gate. When absent (e.g. in isolated unit - * tests), every page is readable — preserving pre-permission behaviour. + * Per-agent pageType permission gate. Mandatory: this is a security control, + * so it is a required constructor dependency rather than an optional bean — + * a missing gate must fail loudly at startup, never silently fail open. */ - @Autowired(required = false) - private WikiPageTypePermissionService pageTypePermissionService; + private final WikiPageTypePermissionService pageTypePermissionService; public WikiTool(WikiPageService pageService, WikiKnowledgeBaseService kbService, WikiRawMaterialService rawService, HybridRetriever hybridRetriever, - ObjectMapper objectMapper) { + ObjectMapper objectMapper, + WikiPageTypePermissionService pageTypePermissionService) { this.pageService = pageService; this.kbService = kbService; this.rawService = rawService; this.hybridRetriever = hybridRetriever; this.objectMapper = objectMapper; + this.pageTypePermissionService = pageTypePermissionService; } // ==================== Knowledge-base discovery ==================== @@ -1054,12 +1056,12 @@ public class WikiTool { /** * Resolve the agent's pageType read/write permission view for a KB once, - * so a tool call can filter a whole result set without re-querying. Returns - * {@code null} when the permission service is absent (isolated unit tests), - * in which case all reads are allowed. + * so a tool call can filter a whole result set without re-querying. Never + * null — the service is a mandatory dependency, so there is no fail-open + * path; an agent with no rows still resolves to the KB's default policy. */ private WikiPageTypePermissionService.Access pageTypeAccess(Long agentId, Long kbId) { - return pageTypePermissionService == null ? null : pageTypePermissionService.resolve(agentId, kbId); + return pageTypePermissionService.resolve(agentId, kbId); } /** Whether the resolved access permits reading {@code page}. Null-safe. */ @@ -1100,9 +1102,6 @@ public class WikiTool { */ private String checkWrite(Long agentId, Long kbId, String pageType, WikiPageTypePermissionService.WriteOp op) { - if (pageTypePermissionService == null) { - return null; - } WikiPageTypePermissionService.WriteDecision decision = pageTypePermissionService.resolveWrite(agentId, kbId, pageType, op); String typeLabel = (pageType == null || pageType.isBlank()) ? "(default)" : pageType; diff --git a/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolKbNameRoutingTest.java b/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolKbNameRoutingTest.java index df3a435f..bde61503 100644 --- a/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolKbNameRoutingTest.java +++ b/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolKbNameRoutingTest.java @@ -62,8 +62,14 @@ class WikiToolKbNameRoutingTest { private final HybridRetriever hybridRetriever = mock(HybridRetriever.class); private final ObjectMapper objectMapper = new ObjectMapper(); + // Allow-all permission service (no rows configured) — this test exercises + // KB-name routing, not permissions. + private final vip.mate.wiki.service.WikiPageTypePermissionService permissionService = + new vip.mate.wiki.service.WikiPageTypePermissionService( + mock(vip.mate.wiki.repository.WikiAgentPageTypePermissionMapper.class), kbService, objectMapper); + private final WikiTool tool = new WikiTool(pageService, kbService, rawService, - hybridRetriever, objectMapper); + hybridRetriever, objectMapper, permissionService); private static WikiKnowledgeBaseEntity kb(long id, String name, Long agentId) { WikiKnowledgeBaseEntity entity = new WikiKnowledgeBaseEntity(); diff --git a/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolPermissionTest.java b/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolPermissionTest.java index b9831ffd..30425919 100644 --- a/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolPermissionTest.java +++ b/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolPermissionTest.java @@ -2,7 +2,6 @@ package vip.mate.wiki.tool; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; -import org.springframework.test.util.ReflectionTestUtils; import vip.mate.wiki.model.WikiAgentPageTypePermissionEntity; import vip.mate.wiki.model.WikiKnowledgeBaseEntity; import vip.mate.wiki.model.WikiPageEntity; @@ -56,8 +55,7 @@ class WikiToolPermissionTest { WikiPageTypePermissionService permService = new WikiPageTypePermissionService(permMapper, kbService, om); - WikiTool tool = new WikiTool(pageService, kbService, rawService, retriever, om); - ReflectionTestUtils.setField(tool, "pageTypePermissionService", permService); + WikiTool tool = new WikiTool(pageService, kbService, rawService, retriever, om, permService); return new Harness(tool, pageService, permMapper); } diff --git a/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolSpringBindingTest.java b/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolSpringBindingTest.java index ae1c9d18..dc0c777c 100644 --- a/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolSpringBindingTest.java +++ b/mateclaw-server/src/test/java/vip/mate/wiki/tool/WikiToolSpringBindingTest.java @@ -61,8 +61,14 @@ class WikiToolSpringBindingTest { private final HybridRetriever hybridRetriever = mock(HybridRetriever.class); private final ObjectMapper objectMapper = new ObjectMapper(); + // Allow-all permission service (no rows configured) — this test exercises + // tool binding, not permissions. + private final vip.mate.wiki.service.WikiPageTypePermissionService permissionService = + new vip.mate.wiki.service.WikiPageTypePermissionService( + mock(vip.mate.wiki.repository.WikiAgentPageTypePermissionMapper.class), kbService, objectMapper); + private final WikiTool tool = new WikiTool(pageService, kbService, rawService, - hybridRetriever, objectMapper); + hybridRetriever, objectMapper, permissionService); private ToolCallback callbackFor(String functionName) { return Arrays.stream(ToolCallbacks.from(tool))