import { ALL, Body, Controller, Inject, Post, Provide } from "@midwayjs/core"; import { AccessGetter, AccessService, BaseController, Constants } from "@certd/lib-server"; import { AccessRequestHandleReq, IAccessService, ITaskPlugin, newAccess, newNotification, NotificationRequestHandleReq, pluginRegistry, PluginRequestHandleReq, TaskInstanceContext } from "@certd/pipeline"; import { EmailService } from "../../../modules/basic/service/email-service.js"; import { http, HttpRequestConfig, logger, mergeUtils, utils } from "@certd/basic"; import { NotificationService } from "../../../modules/pipeline/service/notification-service.js"; import { TaskServiceBuilder } from "../../../modules/pipeline/service/getter/task-service-getter.js"; import { cloneDeep } from "lodash-es"; import { ApiTags } from "@midwayjs/swagger"; import { AuthService } from "../../../modules/sys/authority/service/auth-service.js"; @Provide() @Controller("/api/pi/handle") @ApiTags(["pipeline-handle"]) export class HandleController extends BaseController { @Inject() accessService: AccessService; @Inject() emailService: EmailService; @Inject() authService: AuthService; @Inject() taskServiceBuilder: TaskServiceBuilder; @Inject() notificationService: NotificationService; @Post("/access", { description: Constants.per.authOnly, summary: "处理授权请求" }) async accessRequest(@Body(ALL) body: AccessRequestHandleReq) { let { projectId, userId } = await this.getProjectUserIdRead(); if (body.fromType === "sys") { //系统级别的请求 const pass = await this.authService.checkPermission(this.ctx, "sys:settings:view"); if (!pass) { throw new Error("权限不足"); } projectId = null; userId = 0; } let inputAccess = body.input; if (body.record.id > 0) { const oldEntity = await this.accessService.info(body.record.id); if (oldEntity) { if (oldEntity.userId !== userId && oldEntity.userId !== this.getUserId()) { throw new Error("您没有权限使用该授权"); } if (oldEntity.projectId && oldEntity.projectId !== projectId) { throw new Error("您没有权限使用该授权(projectId不匹配)"); } const param: any = { type: body.typeName, setting: JSON.stringify(body.input), }; this.accessService.encryptSetting(param, oldEntity); inputAccess = this.accessService.decryptAccessEntity(param); } } const getAccessById = this.accessService.getById.bind(this.accessService); const accessGetter = new AccessGetter(userId, projectId, getAccessById); const serviceGetter = this.taskServiceBuilder.create({ userId, projectId }); const accessContext = { http, logger, utils, accessService: accessGetter, serviceGetter, define: undefined, } as any; const access = await newAccess(body.typeName, inputAccess, accessGetter, accessContext); // mergeUtils.merge(access, body.input); const res = await access.onRequest(body); return this.ok(res); } @Post("/notification", { description: Constants.per.authOnly, summary: "处理通知请求" }) async notificationRequest(@Body(ALL) body: NotificationRequestHandleReq) { const { projectId, userId } = await this.getProjectUserIdRead(); const input = body.input; const serviceGetter = this.taskServiceBuilder.create({ userId, projectId }); const notification = await newNotification(body.typeName, input, { http, logger, utils, emailService: this.emailService, serviceGetter, } as any); const res = await notification.onRequest(body); return this.ok(res); } @Post("/plugin", { description: Constants.per.authOnly, summary: "处理插件请求" }) async pluginRequest(@Body(ALL) body: PluginRequestHandleReq) { const { projectId, userId } = await this.getProjectUserIdRead(); const pluginDefine = pluginRegistry.get(body.typeName); const pluginCls = await pluginDefine.target(); if (pluginCls == null) { throw new Error(`plugin ${body.typeName} not found`); } //实例化access //@ts-ignore const plugin: PluginRequestHandler = new pluginCls(); //@ts-ignore const instance = plugin as ITaskPlugin; const download = async (config: HttpRequestConfig, savePath: string) => { await utils.download({ http, logger, config, savePath, }); }; const taskServiceGetter = this.taskServiceBuilder.create({ userId, projectId }); const accessGetter = await taskServiceGetter.get("accessService"); //@ts-ignore const taskCtx: TaskInstanceContext = { pipeline: undefined, step: undefined, define: cloneDeep(pluginDefine.define), lastStatus: undefined, http, download, logger: logger, inputChanged: true, accessService: accessGetter, emailService: this.emailService, pipelineContext: undefined, userContext: undefined, fileStore: undefined, signal: undefined, user: { id: userId, role: "user" }, projectId, // pipelineContext: this.pipelineContext, // userContext: this.contextFactory.getContext('user', this.options.userId), // fileStore: new FileStore({ // scope: this.pipeline.id, // parent: this.runtime.id, // rootDir: this.options.fileRootDir, // }), // signal: this.abort.signal, utils, serviceGetter: taskServiceGetter, } as any; await instance.setCtx(taskCtx); mergeUtils.merge(plugin, body.input); await instance.onInstance(); const res = await plugin.onRequest(body); return this.ok(res); } }