fix(wiki): make pageType permission service a mandatory dependency

This commit is contained in:
matevip 2026-05-31 07:58:59 +08:00
parent 6583aa1e42
commit 551321b542
4 changed files with 26 additions and 17 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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);
}

View File

@ -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))