diff --git a/packages/core/pipeline/src/plugin/api.ts b/packages/core/pipeline/src/plugin/api.ts index 9753e35b7..27f06be7c 100644 --- a/packages/core/pipeline/src/plugin/api.ts +++ b/packages/core/pipeline/src/plugin/api.ts @@ -170,9 +170,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin { } if (this.ctx?.define?.onlyAdmin) { - if (!this.isAdmin()) { - throw new Error("只有管理员才能运行此任务"); - } + this.checkAdmin(); } } @@ -284,6 +282,12 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin { return this.ctx.user.role === "admin"; } + checkAdmin() { + if (!this.isAdmin()) { + throw new Error("只有“管理员”或“系统级项目”才有权限运行此插件任务"); + } + } + getStepFromPipeline(stepId: string) { let found: any = null; RunnableCollection.each(this.ctx.pipeline.stages, step => { diff --git a/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx b/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx index 5dcc10fa3..4b1823ea6 100644 --- a/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx @@ -734,7 +734,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }), }, column: { - width: 100, + width: 140, sorter: true, align: "center", }, @@ -757,7 +757,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat helper: t("monitor.ipSyncModeHelper"), }, column: { - width: 100, + width: 140, sorter: true, align: "center", }, @@ -779,7 +779,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat helper: t("monitor.ipIgnoreCoherenceHelper"), }, column: { - width: 100, + width: 180, sorter: true, align: "center", }, diff --git a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx index c69119847..ca8144cfa 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx @@ -16,13 +16,16 @@ import { useCertViewer } from "/@/views/certd/pipeline/use"; import { useI18n } from "/src/locales"; import { useDicts } from "../dicts"; import { useProjectStore } from "/@/store/project"; +import { useCrudPermission } from "/@/plugin/permission"; -export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog, hasActionPermission } }: CreateCrudOptionsProps): CreateCrudOptionsRet { +export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog, permission } }: CreateCrudOptionsProps): CreateCrudOptionsRet { const router = useRouter(); const lastResRef = ref(); const { t } = useI18n(); + const { hasActionPermission } = useCrudPermission({ permission }); + const { openUploadCreateDialog } = useCertUpload(); const pageRequest = async (query: UserPageQuery): Promise => { diff --git a/packages/ui/certd-client/src/views/sys/enterprise/project/crud.tsx b/packages/ui/certd-client/src/views/sys/enterprise/project/crud.tsx index a3c6b7645..d6e0e053e 100644 --- a/packages/ui/certd-client/src/views/sys/enterprise/project/crud.tsx +++ b/packages/ui/certd-client/src/views/sys/enterprise/project/crud.tsx @@ -104,7 +104,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat helper: t("certd.ent.isSystemHelper"), }, column: { - width: 100, + width: 150, }, }, adminId: { diff --git a/packages/ui/certd-server/src/controller/user/cname/cname-provider-controller.ts b/packages/ui/certd-server/src/controller/user/cname/cname-provider-controller.ts index 044713c79..618cbbe7e 100644 --- a/packages/ui/certd-server/src/controller/user/cname/cname-provider-controller.ts +++ b/packages/ui/certd-server/src/controller/user/cname/cname-provider-controller.ts @@ -20,8 +20,6 @@ export class CnameProviderController extends BaseController { @Post('/list', { summary: Constants.per.authOnly }) async list(@Body(ALL) body: any) { - body.query = body.query ?? {}; - body.query.userId = this.getUserId(); const res = await this.providerService.list({}); return this.ok(res); } diff --git a/packages/ui/certd-server/src/controller/user/cname/cname-record-controller.ts b/packages/ui/certd-server/src/controller/user/cname/cname-record-controller.ts index 13215ab16..c2cc24dcd 100644 --- a/packages/ui/certd-server/src/controller/user/cname/cname-record-controller.ts +++ b/packages/ui/certd-server/src/controller/user/cname/cname-record-controller.ts @@ -67,50 +67,51 @@ export class CnameRecordController extends CrudController { @Post('/info', { summary: Constants.per.authOnly }) async info(@Query('id') id: number) { - await this.service.checkUserId(id, this.getUserId()); + await this.checkOwner(this.getService(), id, "read"); return super.info(id); } @Post('/delete', { summary: Constants.per.authOnly }) async delete(@Query('id') id: number) { - await this.service.checkUserId(id, this.getUserId()); + await this.checkOwner(this.getService(), id, "write"); return super.delete(id); } @Post('/deleteByIds', { summary: Constants.per.authOnly }) async deleteByIds(@Body(ALL) body: any) { + const {userId,projectId} = await this.getProjectUserIdWrite(); await this.service.delete(body.ids, { - userId: this.getUserId(), + userId, + projectId, }); return this.ok(); } @Post('/getByDomain', { summary: Constants.per.authOnly }) async getByDomain(@Body(ALL) body: { domain: string; createOnNotFound: boolean }) { - const userId = this.getUserId(); - const res = await this.service.getByDomain(body.domain, userId, body.createOnNotFound); + const {userId,projectId} = await this.getProjectUserIdRead(); + const res = await this.service.getByDomain(body.domain, userId,projectId, body.createOnNotFound); return this.ok(res); } @Post('/verify', { summary: Constants.per.authOnly }) async verify(@Body(ALL) body: { id: number }) { - const userId = this.getUserId(); - await this.service.checkUserId(body.id, userId); + await this.checkOwner(this.getService(), body.id, "read"); const res = await this.service.verify(body.id); return this.ok(res); } @Post('/resetStatus', { summary: Constants.per.authOnly }) async resetStatus(@Body(ALL) body: { id: number }) { - const userId = this.getUserId(); - await this.service.checkUserId(body.id, userId); + await this.checkOwner(this.getService(), body.id, "read"); const res = await this.service.resetStatus(body.id); return this.ok(res); } @Post('/import', { summary: Constants.per.authOnly }) async import(@Body(ALL) body: { domainList: string; cnameProviderId: any }) { - const userId = this.getUserId(); + const {userId,projectId} = await this.getProjectUserIdWrite(); const res = await this.service.doImport({ userId, + projectId, domainList: body.domainList, cnameProviderId: body.cnameProviderId, }); diff --git a/packages/ui/certd-server/src/modules/cname/service/cname-record-service.ts b/packages/ui/certd-server/src/modules/cname/service/cname-record-service.ts index 8207ee687..1fb8f13d6 100644 --- a/packages/ui/certd-server/src/modules/cname/service/cname-record-service.ts +++ b/packages/ui/certd-server/src/modules/cname/service/cname-record-service.ts @@ -164,8 +164,8 @@ export class CnameRecordService extends BaseService { // // 3. 检查原域名是否有cname记录 // } - async getWithAccessByDomain(domain: string, userId: number) { - const record: CnameRecord = await this.getByDomain(domain, userId); + async getWithAccessByDomain(domain: string, userId: number,projectId?:number) { + const record: CnameRecord = await this.getByDomain(domain, userId,projectId); if (record.cnameProvider.id > 0) { //自定义cname服务 record.cnameProvider.access = await this.accessService.getAccessById(record.cnameProvider.accessId, false); @@ -179,17 +179,17 @@ export class CnameRecordService extends BaseService { return record; } - async getByDomain(domain: string, userId: number, createOnNotFound = true) { + async getByDomain(domain: string, userId: number,projectId?:number, createOnNotFound = true) { if (!domain) { throw new ValidateException("domain不能为空"); } if (userId == null) { throw new ValidateException("userId不能为空"); } - let record = await this.getRepository().findOne({ where: { domain, userId } }); + let record = await this.getRepository().findOne({ where: { domain, userId,projectId } }); if (record == null) { if (createOnNotFound) { - record = await this.add({ domain, userId }); + record = await this.add({ domain, userId,projectId }); } else { throw new ValidateException(`找不到${domain}的CNAME记录`); } @@ -489,8 +489,8 @@ export class CnameRecordService extends BaseService { await this.getRepository().update(id, { status: "cname", mainDomain: "" }); } - async doImport(req:{ userId: number; domainList: string; cnameProviderId: any }) { - const {userId,cnameProviderId,domainList} = req; + async doImport(req:{ userId: number; projectId: number; domainList: string; cnameProviderId: any }) { + const {userId,projectId,cnameProviderId,domainList} = req; const domains = domainList.split("\n").map(item => item.trim()).filter(item => item.length > 0); if (domains.length === 0) { throw new ValidateException("域名列表不能为空"); @@ -504,18 +504,19 @@ export class CnameRecordService extends BaseService { key: "user_"+userId, title: "导入CNAME记录", run: async (task) => { - await this._import({ userId, domains, cnameProviderId },task); + await this._import({ userId,projectId, domains, cnameProviderId },task); } })); } - async _import(req :{ userId: number; domains: string[]; cnameProviderId: any },task:BackTask) { + async _import(req :{ userId: number; projectId: number; domains: string[]; cnameProviderId: any },task:BackTask) { const userId = req.userId; for (const domain of req.domains) { const old = await this.getRepository().findOne({ where: { userId: req.userId, domain, + projectId: req.projectId, }, }); if (old) { @@ -526,6 +527,7 @@ export class CnameRecordService extends BaseService { await this.add({ userId, domain: domain, + projectId: req.projectId, cnameProviderId: req.cnameProviderId, }); }catch(e){ diff --git a/packages/ui/certd-server/src/modules/pipeline/service/getter/cname-proxy-service.ts b/packages/ui/certd-server/src/modules/pipeline/service/getter/cname-proxy-service.ts index 4f4a7113f..e8b5df3b9 100644 --- a/packages/ui/certd-server/src/modules/pipeline/service/getter/cname-proxy-service.ts +++ b/packages/ui/certd-server/src/modules/pipeline/service/getter/cname-proxy-service.ts @@ -2,13 +2,15 @@ import { CnameRecord, ICnameProxyService } from '@certd/pipeline'; export class CnameProxyService implements ICnameProxyService { userId: number; - getter: (domain: string, userId?: number) => Promise; - constructor(userId: number, getter: (domain: string, userId: number) => Promise) { + projectId: number; + getter: (domain: string, userId?: number, projectId?: number) => Promise; + constructor(userId: number, projectId: number, getter: (domain: string, userId: number, projectId: number) => Promise) { this.userId = userId; + this.projectId = projectId; this.getter = getter; } async getByDomain(domain: string): Promise { - return await this.getter(domain, this.userId); + return await this.getter(domain, this.userId, this.projectId); } } diff --git a/packages/ui/certd-server/src/modules/pipeline/service/getter/task-service-getter.ts b/packages/ui/certd-server/src/modules/pipeline/service/getter/task-service-getter.ts index e30a20511..12ef4e1d7 100644 --- a/packages/ui/certd-server/src/modules/pipeline/service/getter/task-service-getter.ts +++ b/packages/ui/certd-server/src/modules/pipeline/service/getter/task-service-getter.ts @@ -59,7 +59,7 @@ export class TaskServiceGetter implements IServiceGetter{ async getCnameProxyService(): Promise { const cnameRecordService:CnameRecordService = await this.appCtx.getAsync("cnameRecordService") - return new CnameProxyService(this.userId, cnameRecordService.getWithAccessByDomain.bind(cnameRecordService)); + return new CnameProxyService(this.userId, this.projectId, cnameRecordService.getWithAccessByDomain.bind(cnameRecordService)); } async getNotificationService(): Promise { diff --git a/packages/ui/certd-server/src/plugins/plugin-admin/plugin-db-backup.ts b/packages/ui/certd-server/src/plugins/plugin-admin/plugin-db-backup.ts index 6d54f06cd..1499f26c0 100644 --- a/packages/ui/certd-server/src/plugins/plugin-admin/plugin-db-backup.ts +++ b/packages/ui/certd-server/src/plugins/plugin-admin/plugin-db-backup.ts @@ -157,9 +157,7 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin { async onInstance() {} async execute(): Promise { - if (!this.isAdmin()) { - throw new Error("只有管理员才能运行此任务"); - } + this.checkAdmin(); this.logger.info("开始备份数据库"); diff --git a/packages/ui/certd-server/src/plugins/plugin-admin/plugin-deploy-to-certd.ts b/packages/ui/certd-server/src/plugins/plugin-admin/plugin-deploy-to-certd.ts index 235fab024..12279bb8d 100644 --- a/packages/ui/certd-server/src/plugins/plugin-admin/plugin-deploy-to-certd.ts +++ b/packages/ui/certd-server/src/plugins/plugin-admin/plugin-deploy-to-certd.ts @@ -32,9 +32,7 @@ export class DeployToCertdPlugin extends AbstractTaskPlugin { cert!: CertInfo; async onInstance() { } async execute(): Promise { - if (!this.isAdmin()) { - throw new Error('只有管理员才能运行此任务'); - } + this.checkAdmin(); //部署证书 let crtPath = "ssl/cert.crt"; diff --git a/packages/ui/certd-server/src/plugins/plugin-admin/plugin-restart.ts b/packages/ui/certd-server/src/plugins/plugin-admin/plugin-restart.ts index 4a1659473..1a9698daa 100644 --- a/packages/ui/certd-server/src/plugins/plugin-admin/plugin-restart.ts +++ b/packages/ui/certd-server/src/plugins/plugin-admin/plugin-restart.ts @@ -17,9 +17,7 @@ import { httpsServer } from '../../modules/auto/https/server.js'; export class RestartCertdPlugin extends AbstractTaskPlugin { async onInstance() {} async execute(): Promise { - if (!this.isAdmin()) { - throw new Error('只有管理员才能运行此任务'); - } + this.checkAdmin(); this.logger.info('Certd https server 将在 3 秒后重启'); await this.ctx.utils.sleep(3000); await httpsServer.restart(); diff --git a/packages/ui/certd-server/src/plugins/plugin-admin/plugin-script.ts b/packages/ui/certd-server/src/plugins/plugin-admin/plugin-script.ts index aa34667f6..4a4c00834 100644 --- a/packages/ui/certd-server/src/plugins/plugin-admin/plugin-script.ts +++ b/packages/ui/certd-server/src/plugins/plugin-admin/plugin-script.ts @@ -47,9 +47,7 @@ export class CustomScriptPlugin extends AbstractTaskPlugin { async onInstance() {} async execute(): Promise { - if (!this.isAdmin()) { - throw new Error('只有管理员才能运行此任务'); - } + this.checkAdmin(); this.logger.info('执行自定义脚本:\n', this.script); const ctx: CustomScriptContext = { CertReader, diff --git a/packages/ui/certd-server/src/plugins/plugin-host/plugin/copy-to-local/index.ts b/packages/ui/certd-server/src/plugins/plugin-host/plugin/copy-to-local/index.ts index 5c46308eb..cbd6fa884 100644 --- a/packages/ui/certd-server/src/plugins/plugin-host/plugin/copy-to-local/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-host/plugin/copy-to-local/index.ts @@ -198,9 +198,7 @@ export class CopyCertToLocalPlugin extends AbstractTaskPlugin { fs.copyFileSync(srcFile, destFile); } async execute(): Promise { - if (!this.isAdmin()) { - throw new Error('只有管理员才能运行此任务'); - } + this.checkAdmin(); let { crtPath, keyPath, icPath, pfxPath, derPath, jksPath } = this; const certReader = new CertReader(this.cert);