feat: 支持智能体可见范围管理

- 未分类智能体按可见范围绕过分类白名单

- 提供个人、部门、公开范围配置及列表状态标签
This commit is contained in:
2026-07-31 16:45:41 +08:00
parent 527336bfc9
commit 6df3dd9981
13 changed files with 725 additions and 44 deletions

View File

@@ -75,7 +75,12 @@ public class ResourceAccessServiceImpl implements ResourceAccessService {
&& categoryPermissionService.getAccess(resourceType.getCode(), loginAccount).isAllAccess()) {
return true;
}
if (!categoryPermissionService.canAccessCategory(loginAccount, resourceType.getCode(), resource.getCreatedBy(), resource.getCategoryId())) {
// Agent 的未分类语义为“全部分类可访问”,只跳过分类白名单,不能跳过可见范围校验。
boolean agentWithoutCategoryRestriction = CategoryResourceType.AGENT == resourceType
&& resource.getCategoryId() == null;
if (!agentWithoutCategoryRestriction
&& !categoryPermissionService.canAccessCategory(
loginAccount, resourceType.getCode(), resource.getCreatedBy(), resource.getCategoryId())) {
return false;
}
VisibilityScope scope = VisibilityScope.fromOrDefault(resource.getVisibilityScope(), VisibilityScope.PRIVATE);

View File

@@ -129,6 +129,36 @@ public class ResourceAccessServiceImplTest {
assertFalse(service.canAccess(account, CategoryResourceType.SKILL, resource, ResourceAction.MANAGE));
}
/**
* 验证未分类公开 Agent 不受角色分类白名单限制,但不会影响其它资源类型。
*/
@Test
public void unclassifiedPublicAgentShouldBypassCategoryWhitelist() {
LoginAccount account = account(8, 80);
VisibilityResource resource = new TestVisibilityResource(
BigInteger.ONE, BigInteger.valueOf(7), BigInteger.valueOf(90), null,
VisibilityScope.PUBLIC.name());
assertTrue(service.canAccess(account, CategoryResourceType.AGENT, resource, ResourceAction.USE));
Mockito.verify(categoryPermissionService, Mockito.never()).canAccessCategory(
Mockito.any(), Mockito.anyString(), Mockito.any(), Mockito.any());
}
/**
* 验证未分类 Agent 仍受可见范围约束,私有 Agent 不会因分类放开而被读取。
*/
@Test
public void unclassifiedPrivateAgentShouldRemainPrivate() {
LoginAccount account = account(8, 80);
VisibilityResource resource = new TestVisibilityResource(
BigInteger.ONE, BigInteger.valueOf(7), BigInteger.valueOf(90), null,
VisibilityScope.PRIVATE.name());
assertFalse(service.canAccess(account, CategoryResourceType.AGENT, resource, ResourceAction.READ));
Mockito.verify(categoryPermissionService, Mockito.never()).canAccessCategory(
Mockito.any(), Mockito.anyString(), Mockito.any(), Mockito.any());
}
/**
* 验证资源动作不能跨越租户边界,即使资源是公开状态。
*/