diff --git a/packages/libs/lib-server/src/basic/base-controller.ts b/packages/libs/lib-server/src/basic/base-controller.ts index 6a9789e9c..26920077a 100644 --- a/packages/libs/lib-server/src/basic/base-controller.ts +++ b/packages/libs/lib-server/src/basic/base-controller.ts @@ -61,7 +61,7 @@ export abstract class BaseController { } } - getProjectId(permission:string) { + async getProjectId(permission:string) { if (!isEnterprise()) { return null } @@ -71,13 +71,13 @@ export abstract class BaseController { } const userId = this.getUserId() const projectId = parseInt(projectIdStr) - this.checkProjectPermission(userId, projectId,permission) + await this.checkProjectPermission(userId, projectId,permission) return projectId; } - getProjectUserId(permission:string){ + async getProjectUserId(permission:string){ let userId = this.getUserId() - const projectId = this.getProjectId(permission) + const projectId = await this.getProjectId(permission) if(projectId){ userId = 0 } @@ -85,11 +85,19 @@ export abstract class BaseController { projectId,userId } } + async getProjectUserIdRead(){ + return await this.getProjectUserId("read") + } + async getProjectUserIdWrite(){ + return await this.getProjectUserId("write") + } + async getProjectUserIdAdmin(){ + return await this.getProjectUserId("admin") + } async checkProjectPermission(userId: number, projectId: number,permission:string) { const projectService:any = await this.applicationContext.getAsync("projectService"); await projectService.checkPermission({userId,projectId,permission}) - } diff --git a/packages/libs/lib-server/src/system/settings/service/sys-settings-service.ts b/packages/libs/lib-server/src/system/settings/service/sys-settings-service.ts index 5118235f3..5ae977b12 100644 --- a/packages/libs/lib-server/src/system/settings/service/sys-settings-service.ts +++ b/packages/libs/lib-server/src/system/settings/service/sys-settings-service.ts @@ -9,6 +9,7 @@ import { cache, logger, mergeUtils, setGlobalProxy } from '@certd/basic'; import * as dns from 'node:dns'; import { BaseService, setAdminMode } from '../../../basic/index.js'; import { executorQueue } from '../../basic/service/executor-queue.js'; +import { isComm } from '@certd/plus-core'; const { merge } = mergeUtils; /** * 设置 @@ -116,6 +117,12 @@ export class SysSettingsService extends BaseService { } async savePublicSettings(bean: SysPublicSettings) { + if(isComm()){ + if(bean.adminMode === 'enterprise'){ + throw new Error("商业版不支持使用企业管理模式") + } + } + await this.saveSetting(bean); //让设置生效 await this.reloadPublicSettings(); diff --git a/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts index ebcbc057d..2d671a307 100644 --- a/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts @@ -35,8 +35,8 @@ export class PipelineController extends CrudController { const isAdmin = await this.authService.isAdmin(this.ctx); const publicSettings = await this.sysSettingsService.getPublicSettings(); - const {projectId,userId} = this.getProjectUserId("read") - body.query.projectId = projectId + const { projectId, userId } = await this.getProjectUserIdRead() + body.query.projectId = projectId let onlyOther = false if (isAdmin) { if (publicSettings.managerOtherUserPipeline) { @@ -79,15 +79,15 @@ export class PipelineController extends CrudController { @Post('/getSimpleByIds', { summary: Constants.per.authOnly }) async getSimpleById(@Body(ALL) body) { - const {projectId,userId} = this.getProjectUserId("read") - const ret = await this.getService().getSimplePipelines(body.ids, userId,projectId); + const { projectId, userId } = await this.getProjectUserIdRead() + const ret = await this.getService().getSimplePipelines(body.ids, userId, projectId); return this.ok(ret); } @Post('/add', { summary: Constants.per.authOnly }) async add(@Body(ALL) bean: PipelineEntity) { - const {projectId,userId} = this.getProjectUserId("write") + const { projectId, userId } = await this.getProjectUserIdWrite() bean.userId = userId bean.projectId = projectId return super.add(bean); @@ -95,17 +95,27 @@ export class PipelineController extends CrudController { @Post('/update', { summary: Constants.per.authOnly }) async update(@Body(ALL) bean) { - await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id); + const { projectId } = await this.getProjectUserIdWrite() + if (projectId) { + await this.authService.checkEntityProjectId(this.getService(), projectId, bean.id); + } else { + await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id); + } delete bean.userId; return super.update(bean); } @Post('/save', { summary: Constants.per.authOnly }) async save(@Body(ALL) bean: { addToMonitorEnabled: boolean, addToMonitorDomains: string } & PipelineEntity) { + const { projectId, userId } = await this.getProjectUserIdWrite() if (bean.id > 0) { - await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id); + if (projectId) { + await this.authService.checkEntityProjectId(this.getService(), projectId, bean.id); + } else { + await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id); + } } else { - bean.userId = this.getUserId(); + bean.userId = userId; } if (!this.isAdmin()) { @@ -121,7 +131,7 @@ export class PipelineController extends CrudController { //增加证书监控 await this.siteInfoService.doImport({ text: bean.addToMonitorDomains, - userId: this.getUserId(), + userId: userId, }); } } @@ -130,14 +140,24 @@ export class PipelineController extends CrudController { @Post('/delete', { summary: Constants.per.authOnly }) async delete(@Query('id') id: number) { - await this.authService.checkEntityUserId(this.ctx, this.getService(), id); + const { projectId } = await this.getProjectUserIdWrite() + if (projectId) { + await this.authService.checkEntityProjectId(this.getService(), projectId, id); + } else { + await this.authService.checkEntityUserId(this.ctx, this.getService(), id); + } await this.service.delete(id); return this.ok({}); } @Post('/disabled', { summary: Constants.per.authOnly }) async disabled(@Body(ALL) bean) { - await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id); + const { projectId } = await this.getProjectUserIdWrite() + if (projectId) { + await this.authService.checkEntityProjectId(this.getService(), projectId, bean.id); + } else { + await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id); + } delete bean.userId; await this.service.disabled(bean.id, bean.disabled); return this.ok({}); @@ -145,75 +165,140 @@ export class PipelineController extends CrudController { @Post('/detail', { summary: Constants.per.authOnly }) async detail(@Query('id') id: number) { - await this.authService.checkEntityUserId(this.ctx, this.getService(), id); + const { projectId } = await this.getProjectUserIdRead() + if (projectId) { + await this.authService.checkEntityProjectId(this.getService(), projectId, id); + } else { + await this.authService.checkEntityUserId(this.ctx, this.getService(), id); + } const detail = await this.service.detail(id); return this.ok(detail); } @Post('/trigger', { summary: Constants.per.authOnly }) async trigger(@Query('id') id: number, @Query('stepId') stepId?: string) { - await this.authService.checkEntityUserId(this.ctx, this.getService(), id); + const { projectId } = await this.getProjectUserIdWrite() + if (projectId) { + await this.authService.checkEntityProjectId(this.getService(), projectId, id); + } else { + await this.authService.checkEntityUserId(this.ctx, this.getService(), id); + } await this.service.trigger(id, stepId, true); return this.ok({}); } @Post('/cancel', { summary: Constants.per.authOnly }) async cancel(@Query('historyId') historyId: number) { - await this.authService.checkEntityUserId(this.ctx, this.historyService, historyId); + const { projectId } = await this.getProjectUserIdWrite() + if (projectId) { + await this.authService.checkEntityProjectId(this.historyService, projectId, historyId); + } else { + await this.authService.checkEntityUserId(this.ctx, this.historyService, historyId); + } await this.service.cancel(historyId); return this.ok({}); } @Post('/count', { summary: Constants.per.authOnly }) async count() { - const count = await this.service.count({ userId: this.getUserId() }); + const { userId } = await this.getProjectUserIdRead() + const count = await this.service.count({ userId: userId }); return this.ok({ count }); } + + private async checkPermissionCall(callback:any){ + let { projectId ,userId} = await this.getProjectUserIdWrite() + if(projectId){ + return await callback({userId,projectId}); + } + const isAdmin = await this.authService.isAdmin(this.ctx); + userId = isAdmin ? undefined : userId; + return await callback({userId}); + } + @Post('/batchDelete', { summary: Constants.per.authOnly }) async batchDelete(@Body('ids') ids: number[]) { - const isAdmin = await this.authService.isAdmin(this.ctx); - const userId = isAdmin ? undefined : this.getUserId(); - await this.service.batchDelete(ids, userId); - return this.ok({}); + // let { projectId ,userId} = await this.getProjectUserIdWrite() + // if(projectId){ + // await this.service.batchDelete(ids, null,projectId); + // return this.ok({}); + // } + // const isAdmin = await this.authService.isAdmin(this.ctx); + // userId = isAdmin ? undefined : userId; + // await this.service.batchDelete(ids, userId); + // return this.ok({}); + await this.checkPermissionCall(async ({userId,projectId})=>{ + await this.service.batchDelete(ids, userId,projectId); + }) + return this.ok({}) } @Post('/batchUpdateGroup', { summary: Constants.per.authOnly }) async batchUpdateGroup(@Body('ids') ids: number[], @Body('groupId') groupId: number) { - const isAdmin = await this.authService.isAdmin(this.ctx); - const userId = isAdmin ? undefined : this.getUserId(); - await this.service.batchUpdateGroup(ids, groupId, userId); + // let { projectId ,userId} = await this.getProjectUserIdWrite() + // if(projectId){ + // await this.service.batchUpdateGroup(ids, groupId, null,projectId); + // return this.ok({}); + // } + + // const isAdmin = await this.authService.isAdmin(this.ctx); + // userId = isAdmin ? undefined : this.getUserId(); + // await this.service.batchUpdateGroup(ids, groupId, userId); + await this.checkPermissionCall(async ({userId,projectId})=>{ + await this.service.batchUpdateGroup(ids, groupId, userId,projectId); + }) return this.ok({}); } @Post('/batchUpdateTrigger', { summary: Constants.per.authOnly }) async batchUpdateTrigger(@Body('ids') ids: number[], @Body('trigger') trigger: any) { - const isAdmin = await this.authService.isAdmin(this.ctx); - const userId = isAdmin ? undefined : this.getUserId(); - await this.service.batchUpdateTrigger(ids, trigger, userId); + // let { projectId ,userId} = await this.getProjectUserIdWrite() + // if(projectId){ + // await this.service.batchUpdateTrigger(ids, trigger, null,projectId); + // return this.ok({}); + // } + + // const isAdmin = await this.authService.isAdmin(this.ctx); + // userId = isAdmin ? undefined : this.getUserId(); + // await this.service.batchUpdateTrigger(ids, trigger, userId); + await this.checkPermissionCall(async ({userId,projectId})=>{ + await this.service.batchUpdateTrigger(ids, trigger, userId,projectId); + }) return this.ok({}); } @Post('/batchUpdateNotification', { summary: Constants.per.authOnly }) async batchUpdateNotification(@Body('ids') ids: number[], @Body('notification') notification: any) { - const isAdmin = await this.authService.isAdmin(this.ctx); - const userId = isAdmin ? undefined : this.getUserId(); - await this.service.batchUpdateNotifications(ids, notification, userId); + // const isAdmin = await this.authService.isAdmin(this.ctx); + // const userId = isAdmin ? undefined : this.getUserId(); + // await this.service.batchUpdateNotifications(ids, notification, userId); + await this.checkPermissionCall(async ({userId,projectId})=>{ + await this.service.batchUpdateNotifications(ids, notification, userId,projectId); + }) return this.ok({}); } @Post('/batchRerun', { summary: Constants.per.authOnly }) async batchRerun(@Body('ids') ids: number[], @Body('force') force: boolean) { - await this.service.batchRerun(ids, this.getUserId(), force); + await this.checkPermissionCall(async ({userId,projectId})=>{ + await this.service.batchRerun(ids, force,userId,projectId); + }) return this.ok({}); } @Post('/refreshWebhookKey', { summary: Constants.per.authOnly }) async refreshWebhookKey(@Body('id') id: number) { - await this.authService.checkEntityUserId(this.ctx, this.getService(), id); + + const { projectId } = await this.getProjectUserIdWrite() + if (projectId) { + await this.authService.checkEntityProjectId(this.getService(), projectId, id); + } else { + await this.authService.checkEntityUserId(this.ctx, this.getService(), id); + } const res = await this.service.refreshWebhookKey(id); return this.ok({ webhookKey: res, diff --git a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts index be67ba4e0..d06f0dea5 100644 --- a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts +++ b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts @@ -4,6 +4,7 @@ import { In, MoreThan, Repository } from "typeorm"; import { AccessService, BaseService, + isEnterprise, NeedSuiteException, NeedVIPException, PageReq, @@ -38,7 +39,7 @@ import { CnameRecordService } from "../../cname/service/cname-record-service.js" import { PluginConfigGetter } from "../../plugin/service/plugin-config-getter.js"; import dayjs from "dayjs"; import { DbAdapter } from "../../db/index.js"; -import { isComm, isPlus } from "@certd/plus-core"; +import { checkPlus, isComm, isPlus } from "@certd/plus-core"; import { logger, utils } from "@certd/basic"; import { UrlService } from "./url-service.js"; import { NotificationService } from "./notification-service.js"; @@ -301,6 +302,12 @@ export class PipelineService extends BaseService { // throw new NeedVIPException(`基础版最多只能创建${freeCount}条流水线`); // } // } + if(isEnterprise()){ + //企业模式不限制 + checkPlus() + return; + } + if (isComm()) { //校验pipelineCount const suiteSetting = await this.userSuiteService.getSuiteSetting(); @@ -328,6 +335,7 @@ export class PipelineService extends BaseService { } } } + } async foreachPipeline(callback: (pipeline: PipelineEntity) => void) { @@ -559,6 +567,12 @@ export class PipelineService extends BaseService { } async beforeCheck(entity: PipelineEntity) { + + if(isEnterprise()){ + checkPlus() + return {} + } + const validTimeEnabled = await this.isPipelineValidTimeEnabled(entity) if (!validTimeEnabled) { throw new Error(`流水线${entity.id}已过期,不予执行`); @@ -582,7 +596,7 @@ export class PipelineService extends BaseService { const res = await this.beforeCheck(entity); suite = res.suite } catch (e) { - logger.error(`流水线${entity.id}触发${triggerId}失败:${e.message}`); + logger.error(`流水线${entity.id}触发失败(${triggerId}):${e.message}`); } const id = entity.id; @@ -625,7 +639,10 @@ export class PipelineService extends BaseService { const userId = entity.userId; const historyId = await this.historyService.start(entity, triggerType); - const userIsAdmin = await this.userService.isAdmin(userId); + let userIsAdmin = false + if(userId){ + userIsAdmin = await this.userService.isAdmin(userId); + } const user: UserInfo = { id: userId, role: userIsAdmin ? "admin" : "user" @@ -836,7 +853,7 @@ export class PipelineService extends BaseService { return result; } - async batchDelete(ids: number[], userId: number) { + async batchDelete(ids: number[], userId?: number,projectId?:number) { if (!isPlus()) { throw new NeedVIPException("此功能需要升级专业版"); } @@ -844,11 +861,14 @@ export class PipelineService extends BaseService { if (userId) { await this.checkUserId(id, userId); } + if(projectId){ + await this.checkUserId(id,projectId,"projectId") + } await this.delete(id); } } - async batchUpdateGroup(ids: number[], groupId: number, userId: any) { + async batchUpdateGroup(ids: number[], groupId: number, userId: any,projectId?:number) { if (!isPlus()) { throw new NeedVIPException("此功能需要升级专业版"); } @@ -856,6 +876,9 @@ export class PipelineService extends BaseService { if (userId && userId > 0) { query.userId = userId; } + if(projectId){ + query.projectId = projectId; + } await this.repository.update( { id: In(ids), @@ -866,7 +889,7 @@ export class PipelineService extends BaseService { } - async batchUpdateTrigger(ids: number[], trigger: any, userId: any) { + async batchUpdateTrigger(ids: number[], trigger: any, userId: any,projectId?:number) { if (!isPlus()) { throw new NeedVIPException("此功能需要升级专业版"); } @@ -874,6 +897,9 @@ export class PipelineService extends BaseService { if (userId && userId > 0) { query.userId = userId; } + if(projectId){ + query.projectId = projectId; + } const list = await this.find({ where: { id: In(ids), @@ -915,7 +941,7 @@ export class PipelineService extends BaseService { } - async batchUpdateNotifications(ids: number[], notification: Notification, userId: any) { + async batchUpdateNotifications(ids: number[], notification: Notification, userId: any,projectId?:number) { if (!isPlus()) { throw new NeedVIPException("此功能需要升级专业版"); } @@ -923,6 +949,9 @@ export class PipelineService extends BaseService { if (userId && userId > 0) { query.userId = userId; } + if(projectId){ + query.projectId = projectId; + } const list = await this.find({ where: { id: In(ids), @@ -950,7 +979,7 @@ export class PipelineService extends BaseService { } } - async batchRerun(ids: number[], userId: any, force: boolean) { + async batchRerun(ids: number[], force: boolean,userId: any, projectId?:number) { if (!isPlus()) { throw new NeedVIPException("此功能需要升级专业版"); } @@ -958,14 +987,18 @@ export class PipelineService extends BaseService { if (!userId || ids.length === 0) { return; } + const where:any = { + id: In(ids), + userId, + } + if(projectId){ + where.projectId = projectId + } const list = await this.repository.find({ select: { id: true }, - where: { - id: In(ids), - userId - } + where:where }); ids = list.map(item => item.id); diff --git a/packages/ui/certd-server/src/modules/sys/authority/service/auth-service.ts b/packages/ui/certd-server/src/modules/sys/authority/service/auth-service.ts index 3d7e55547..0ea36a3e9 100644 --- a/packages/ui/certd-server/src/modules/sys/authority/service/auth-service.ts +++ b/packages/ui/certd-server/src/modules/sys/authority/service/auth-service.ts @@ -35,4 +35,8 @@ export class AuthService { } await service.checkUserId(id, ctx.user.id, userKey); } + + async checkEntityProjectId(service:any,projectId = 0,id:any=0){ + await service.checkUserId(id, projectId , "projectId"); + } }