package cn.iocoder.yudao.module.system.controller.admin.agent;
|
|
import cn.iocoder.yudao.framework.common.biz.system.permission.PermissionCommonApi;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
import cn.iocoder.yudao.module.system.framework.agent.AgentBridgeException;
|
import cn.iocoder.yudao.module.system.framework.agent.AgentDelegationToken;
|
import cn.iocoder.yudao.module.system.framework.agent.SystemAgentBridgeGuard;
|
import cn.iocoder.yudao.module.system.framework.agent.SystemAgentDelegationService;
|
import cn.iocoder.yudao.module.system.service.storage.SystemAgentImportBridgeService;
|
import jakarta.annotation.Resource;
|
import jakarta.validation.Valid;
|
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.Size;
|
import lombok.Data;
|
import org.springframework.http.HttpStatus;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.web.bind.annotation.*;
|
|
import java.util.Map;
|
import java.util.LinkedHashSet;
|
import java.util.Set;
|
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|
/** 浏览器以当前登录身份为异步 Worker 签发短期、可撤销、限定范围的委托票据。 */
|
@RestController
|
@RequestMapping("/agent/bridge/delegations")
|
public class SystemAgentDelegationController {
|
|
private static final String IMPORT_PERMISSIONS_EXPR =
|
"@ss.hasAnyPermissions('mdm:item:import','srm:supplier:create','mes:md-item:create',"
|
+ "'mes:qc-template:create','mes:pro-mps:create','mes:pro-route:create')";
|
private static final Set<String> ALLOWED_OPERATIONS = Set.of(
|
"material_import.prepare", "material_import.read", "material_import.review",
|
"material_import.preflight", "material_import.commit", "material_import.read_receipt",
|
"conversation.create", "conversation.read", "conversation.message", "conversation.action",
|
"conversation.report", "attachment.read", "import.modules.read", "import.preflight",
|
"import.commit", "import.receipt.read");
|
private static final Map<String, String> MODULE_PERMISSIONS = Map.of(
|
"mdm.item", SystemAgentBridgeGuard.PERMISSION_ITEM_IMPORT,
|
"srm.supplier", "srm:supplier:create",
|
"mes.bom", "mes:md-item:create",
|
"mes.qc-template", "mes:qc-template:create",
|
"mes.mps", "mes:pro-mps:create",
|
"mes.route", "mes:pro-route:create");
|
|
@Resource
|
private SystemAgentBridgeGuard bridgeGuard;
|
@Resource
|
private SystemAgentDelegationService delegationService;
|
@Resource
|
private SystemAgentImportBridgeService bridgeService;
|
@Resource
|
private PermissionCommonApi permissionApi;
|
|
@PostMapping
|
@PreAuthorize(IMPORT_PERMISSIONS_EXPR)
|
public CommonResult<AgentDelegationToken> issue(
|
@RequestHeader(value = "X-Agent-Service-Token", required = false) String serviceToken,
|
@Valid @RequestBody IssueRequest request) {
|
bridgeGuard.verifyServiceToken(serviceToken);
|
if (!ALLOWED_OPERATIONS.containsAll(request.getOperations())) {
|
throw new AgentBridgeException(HttpStatus.BAD_REQUEST, "DELEGATION_OPERATION_INVALID",
|
"委托包含不支持的操作");
|
}
|
Set<Long> attachmentIds = request.normalizedAttachmentIds();
|
for (Long attachmentId : attachmentIds) {
|
bridgeService.requireOwnedAttachmentRef(attachmentId);
|
}
|
String permission = resolvePermission(request.getModuleId());
|
AgentDelegationToken token = delegationService.issue(request.getTaskId(), request.getModuleId(),
|
attachmentIds, request.getOperations(), permission);
|
return success(token);
|
}
|
|
@DeleteMapping("/{delegationId}")
|
@PreAuthorize(IMPORT_PERMISSIONS_EXPR)
|
public CommonResult<Boolean> revoke(
|
@RequestHeader(value = "X-Agent-Service-Token", required = false) String serviceToken,
|
@PathVariable String delegationId) {
|
bridgeGuard.verifyServiceToken(serviceToken);
|
delegationService.revoke(delegationId, SecurityFrameworkUtils.getLoginUserId());
|
return success(true);
|
}
|
|
private String resolvePermission(String moduleId) {
|
if (moduleId != null && !moduleId.isBlank()) {
|
String permission = MODULE_PERMISSIONS.get(moduleId);
|
if (permission == null) {
|
throw new AgentBridgeException(HttpStatus.BAD_REQUEST, "MODULE_NOT_SUPPORTED", "不支持的导入模块");
|
}
|
return permission;
|
}
|
Long userId = SecurityFrameworkUtils.getLoginUserId();
|
return SystemAgentBridgeGuard.IMPORT_PERMISSIONS.stream()
|
.filter(permission -> permissionApi.hasAnyPermissions(userId, permission))
|
.findFirst()
|
.orElseThrow(() -> new AgentBridgeException(HttpStatus.FORBIDDEN, "FORBIDDEN",
|
"当前用户缺少数据导入权限"));
|
}
|
|
@Data
|
public static class IssueRequest {
|
@NotBlank
|
private String taskId;
|
private String moduleId;
|
private Long attachmentId;
|
@Size(max = 20)
|
private Set<Long> attachmentIds;
|
@NotEmpty
|
private Set<String> operations;
|
|
public Set<Long> normalizedAttachmentIds() {
|
Set<Long> values = new LinkedHashSet<>();
|
if (attachmentIds != null) {
|
values.addAll(attachmentIds);
|
}
|
if (attachmentId != null) {
|
values.add(attachmentId);
|
}
|
if (values.stream().anyMatch(id -> id == null || id <= 0) || values.size() > 20) {
|
throw new AgentBridgeException(HttpStatus.BAD_REQUEST, "DELEGATION_SCOPE_INVALID",
|
"委托附件范围无效");
|
}
|
return values;
|
}
|
}
|
}
|