diff --git a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v3/ApigwTemplateResourceV3.kt b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v3/ApigwTemplateResourceV3.kt index e1114d43209..ed229084db4 100644 --- a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v3/ApigwTemplateResourceV3.kt +++ b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v3/ApigwTemplateResourceV3.kt @@ -36,6 +36,8 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.web.annotation.BkField import com.tencent.devops.common.web.constant.BkStyleEnum +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.template.OptionalTemplateList import com.tencent.devops.process.pojo.template.TemplateId import com.tencent.devops.process.pojo.template.TemplateListModel @@ -134,6 +136,12 @@ interface ApigwTemplateResourceV3 { @Parameter(description = "是否已关联到store", required = false) @QueryParam("storeFlag") storeFlag: Boolean?, + @Parameter(description = "模版排序字段", required = false, example = "CREATE_TIME") + @QueryParam("orderBy") + orderBy: PTemplateOrderByType? = PTemplateOrderByType.CREATE_TIME, + @Parameter(description = "orderBy排序顺序", required = false) + @QueryParam("sort") + sort: PTemplateSortType?, @Parameter(description = "页码", required = true) @QueryParam("page") page: Int = 1, diff --git a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwTemplateResourceV4.kt b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwTemplateResourceV4.kt index 6131461eea5..59686817985 100644 --- a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwTemplateResourceV4.kt +++ b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwTemplateResourceV4.kt @@ -36,6 +36,8 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.web.annotation.BkField import com.tencent.devops.common.web.constant.BkStyleEnum +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.template.OptionalTemplateList import com.tencent.devops.process.pojo.template.TemplateId import com.tencent.devops.process.pojo.template.TemplateListModel @@ -137,6 +139,12 @@ interface ApigwTemplateResourceV4 { @Parameter(description = "是否已关联到store", required = false) @QueryParam("storeFlag") storeFlag: Boolean?, + @Parameter(description = "模版排序字段", required = false, example = "CREATE_TIME") + @QueryParam("orderBy") + orderBy: PTemplateOrderByType? = PTemplateOrderByType.CREATE_TIME, + @Parameter(description = "orderBy排序顺序", required = false) + @QueryParam("sort") + sort: PTemplateSortType?, @Parameter(description = "页码", required = true) @QueryParam("page") page: Int = 1, diff --git a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwTemplateResourceV3Impl.kt b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwTemplateResourceV3Impl.kt index 34c77266421..21700a9d8c9 100644 --- a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwTemplateResourceV3Impl.kt +++ b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwTemplateResourceV3Impl.kt @@ -34,6 +34,8 @@ import com.tencent.devops.openapi.api.apigw.v3.ApigwTemplateResourceV3 import com.tencent.devops.openapi.utils.ApigwParamUtil import com.tencent.devops.process.api.template.ServicePTemplateResource import com.tencent.devops.process.api.template.UserPTemplateResource +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.template.OptionalTemplateList import com.tencent.devops.process.pojo.template.TemplateId import com.tencent.devops.process.pojo.template.TemplateListModel @@ -52,6 +54,8 @@ class ApigwTemplateResourceV3Impl @Autowired constructor(private val client: Cli projectId: String, templateType: TemplateType?, storeFlag: Boolean?, + orderBy: PTemplateOrderByType?, + sort: PTemplateSortType?, page: Int, pageSize: Int ): Result { @@ -61,6 +65,8 @@ class ApigwTemplateResourceV3Impl @Autowired constructor(private val client: Cli projectId = projectId, templateType = templateType, storeFlag = storeFlag, + orderBy = orderBy, + sort = sort, page = page, pageSize = ApigwParamUtil.standardSize(pageSize) ?: 20 ) diff --git a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwTemplateResourceV4Impl.kt b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwTemplateResourceV4Impl.kt index 91550a39fff..7a882be85ef 100644 --- a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwTemplateResourceV4Impl.kt +++ b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwTemplateResourceV4Impl.kt @@ -34,6 +34,8 @@ import com.tencent.devops.openapi.api.apigw.v4.ApigwTemplateResourceV4 import com.tencent.devops.openapi.utils.ApigwParamUtil import com.tencent.devops.process.api.template.ServicePTemplateResource import com.tencent.devops.process.api.template.UserPTemplateResource +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.template.OptionalTemplateList import com.tencent.devops.process.pojo.template.TemplateId import com.tencent.devops.process.pojo.template.TemplateListModel @@ -52,6 +54,8 @@ class ApigwTemplateResourceV4Impl @Autowired constructor(private val client: Cli projectId: String, templateType: TemplateType?, storeFlag: Boolean?, + orderBy: PTemplateOrderByType?, + sort: PTemplateSortType?, page: Int, pageSize: Int ): Result { @@ -61,6 +65,8 @@ class ApigwTemplateResourceV4Impl @Autowired constructor(private val client: Cli projectId = projectId, templateType = templateType, storeFlag = storeFlag, + orderBy = orderBy, + sort = sort, page = page, pageSize = ApigwParamUtil.standardSize(pageSize) ?: 20 ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/ServicePTemplateResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/ServicePTemplateResource.kt index f43e8e564a6..49b5d8e8901 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/ServicePTemplateResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/ServicePTemplateResource.kt @@ -35,6 +35,8 @@ import com.tencent.devops.common.web.annotation.BkApiPermission import com.tencent.devops.common.web.annotation.BkField import com.tencent.devops.common.web.constant.BkApiHandleType import com.tencent.devops.common.web.constant.BkStyleEnum +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.PipelineTemplateInfo import com.tencent.devops.process.pojo.template.MarketTemplateRequest import com.tencent.devops.process.pojo.template.OptionalTemplateList @@ -42,9 +44,9 @@ import com.tencent.devops.process.pojo.template.TemplateDetailInfo import com.tencent.devops.process.pojo.template.TemplateListModel import com.tencent.devops.process.pojo.template.TemplateModelDetail import com.tencent.devops.process.pojo.template.TemplateType -import io.swagger.v3.oas.annotations.tags.Tag import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.tags.Tag import javax.ws.rs.Consumes import javax.ws.rs.GET import javax.ws.rs.HeaderParam @@ -208,6 +210,12 @@ interface ServicePTemplateResource { @Parameter(description = "是否已关联到store", required = false) @QueryParam("storeFlag") storeFlag: Boolean?, + @Parameter(description = "模版排序字段", required = false, example = "CREATE_TIME") + @QueryParam("orderBy") + orderBy: PTemplateOrderByType? = null, + @Parameter(description = "orderBy排序顺序", required = false) + @QueryParam("sort") + sort: PTemplateSortType? = null, @Parameter(description = "页码", required = false) @QueryParam("page") page: Int?, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResource.kt index 8bd9f9130da..1af1d171e3b 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResource.kt @@ -32,9 +32,11 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.common.web.annotation.BkField import com.tencent.devops.common.web.constant.BkStyleEnum -import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.template.CopyTemplateReq import com.tencent.devops.process.pojo.template.HighlightType import com.tencent.devops.process.pojo.template.OptionalTemplateList @@ -44,9 +46,9 @@ import com.tencent.devops.process.pojo.template.TemplateListModel import com.tencent.devops.process.pojo.template.TemplateModelDetail import com.tencent.devops.process.pojo.template.TemplatePreviewDetail import com.tencent.devops.process.pojo.template.TemplateType -import io.swagger.v3.oas.annotations.tags.Tag import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.tags.Tag import javax.ws.rs.Consumes import javax.ws.rs.DELETE import javax.ws.rs.GET @@ -173,6 +175,12 @@ interface UserPTemplateResource { @Parameter(description = "是否已关联到store", required = false) @QueryParam("storeFlag") storeFlag: Boolean?, + @Parameter(description = "模版排序字段", required = false, example = "CREATE_TIME") + @QueryParam("orderBy") + orderBy: PTemplateOrderByType? = null, + @Parameter(description = "orderBy排序顺序", required = false) + @QueryParam("sort") + sort: PTemplateSortType? = null, @Parameter(description = "页码", required = false) @QueryParam("page") @BkField(patternStyle = BkStyleEnum.NUMBER_STYLE, required = false) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PTemplateOrderByType.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PTemplateOrderByType.kt new file mode 100644 index 00000000000..42737268f5b --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PTemplateOrderByType.kt @@ -0,0 +1,37 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo + +/** + * 模版order_by 排序顺序 + */ +enum class PTemplateOrderByType { + NAME, + CREATOR, + CREATE_TIME, +} diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PTemplateSortType.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PTemplateSortType.kt new file mode 100644 index 00000000000..cd429d62ec6 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PTemplateSortType.kt @@ -0,0 +1,33 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo + +enum class PTemplateSortType { + ASC, + DESC; +} diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/template/TemplateModel.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/template/TemplateModel.kt index eb59a2b2d72..79532f8e35a 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/template/TemplateModel.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/template/TemplateModel.kt @@ -77,5 +77,9 @@ data class TemplateModel( @get:Schema(title = "是否有模版编辑权限", required = true) val canEdit: Boolean? = null, @get:Schema(title = "是否有模版删除权限", required = true) - val canDelete: Boolean? = null + val canDelete: Boolean? = null, + @get:Schema(title = "创建者", required = false) + val creator: String, + @get:Schema(title = "更新时间", required = false) + val updateTime: Long ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/template/TemplateDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/template/TemplateDao.kt index b5f4962ff5c..9abab7414d6 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/template/TemplateDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/template/TemplateDao.kt @@ -33,10 +33,11 @@ import com.tencent.devops.model.process.tables.TTemplate import com.tencent.devops.model.process.tables.records.TTemplateRecord import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.constant.ProcessMessageCode.FAIL_TO_LIST_TEMPLATE_PARAMS +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.template.TemplateType import com.tencent.devops.store.pojo.common.KEY_CREATE_TIME import com.tencent.devops.store.pojo.common.KEY_ID -import java.time.LocalDateTime import org.jooq.Condition import org.jooq.DSLContext import org.jooq.Record @@ -44,6 +45,7 @@ import org.jooq.Record1 import org.jooq.Result import org.jooq.impl.DSL import org.springframework.stereotype.Repository +import java.time.LocalDateTime @Suppress("ALL") @Repository @@ -451,6 +453,8 @@ class TemplateDao { templateType: TemplateType?, templateIdList: Collection?, storeFlag: Boolean?, + orderBy: PTemplateOrderByType? = null, + sort: PTemplateSortType? = null, offset: Int?, limit: Int?, queryModelFlag: Boolean = true @@ -479,6 +483,8 @@ class TemplateDao { templateType = templateType, templateIdList = templateIdList, storeFlag = storeFlag, + orderBy = orderBy, + sort = sort, offset = offset, limit = limit, tTemplate = tTemplate, @@ -492,6 +498,8 @@ class TemplateDao { templateType: TemplateType?, templateIdList: Collection?, storeFlag: Boolean?, + orderBy: PTemplateOrderByType?, + sort: PTemplateSortType?, offset: Int?, limit: Int?, tTemplate: TTemplate, @@ -546,7 +554,43 @@ class TemplateDao { ) ) .where(conditions) - .orderBy(tTemplate.WEIGHT.desc(), tTemplate.CREATED_TIME.desc(), tTemplate.VERSION.desc()) + + if (orderBy != null) { + val orderByField = when (orderBy) { + PTemplateOrderByType.NAME -> { + tTemplate.TEMPLATE_NAME.let { + if (sort == null || sort == PTemplateSortType.ASC) { + it.asc() + } else { + it.desc() + } + } + } + + PTemplateOrderByType.CREATOR -> { + tTemplate.CREATOR.let { + if (sort == null || sort == PTemplateSortType.ASC) { + it.asc() + } else { + it.desc() + } + } + } + + PTemplateOrderByType.CREATE_TIME -> { + tTemplate.CREATED_TIME.let { + if (sort == null || sort == PTemplateSortType.DESC) { + it.desc() + } else { + it.asc() + } + } + } + } + baseStep.orderBy(tTemplate.WEIGHT.desc(), orderByField, tTemplate.VERSION.desc()) + } else { + baseStep.orderBy(tTemplate.WEIGHT.desc(), tTemplate.CREATED_TIME.desc(), tTemplate.VERSION.desc()) + } return if (null != offset && null != limit) { baseStep.limit(offset, limit).skipCheck().fetch() diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/ServicePTemplateResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/ServicePTemplateResourceImpl.kt index 63e2e48bc86..c2db4973744 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/ServicePTemplateResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/ServicePTemplateResourceImpl.kt @@ -29,6 +29,8 @@ package com.tencent.devops.process.api.template import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.web.RestResource +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.PipelineTemplateInfo import com.tencent.devops.process.pojo.template.MarketTemplateRequest import com.tencent.devops.process.pojo.template.OptionalTemplateList @@ -87,6 +89,8 @@ class ServicePTemplateResourceImpl @Autowired constructor( projectId: String, templateType: TemplateType?, storeFlag: Boolean?, + orderBy: PTemplateOrderByType?, + sort: PTemplateSortType?, page: Int?, pageSize: Int? ): Result { @@ -96,6 +100,8 @@ class ServicePTemplateResourceImpl @Autowired constructor( userId = userId, templateType = templateType, storeFlag = storeFlag, + orderBy = orderBy, + sort = sort, page = page ?: 1, pageSize = pageSize ?: 1000 ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResourceImpl.kt index 7980760a626..7544ac76a5f 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResourceImpl.kt @@ -33,11 +33,13 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.auth.api.ActionId import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.constant.ProcessMessageCode -import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType -import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.template.CopyTemplateReq import com.tencent.devops.process.pojo.template.HighlightType import com.tencent.devops.process.pojo.template.OptionalTemplateList @@ -124,10 +126,23 @@ class UserPTemplateResourceImpl @Autowired constructor( projectId: String, templateType: TemplateType?, storeFlag: Boolean?, + orderBy: PTemplateOrderByType?, + sort: PTemplateSortType?, page: Int?, pageSize: Int? ): Result { - return Result(templateFacadeService.listTemplate(projectId, userId, templateType, storeFlag, page, pageSize)) + return Result( + templateFacadeService.listTemplate( + projectId = projectId, + userId = userId, + templateType = templateType, + storeFlag = storeFlag, + orderBy = orderBy, + sort = sort, + page = page, + pageSize = pageSize + ) + ) } override fun listAllTemplate( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPipelineTemplateResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPipelineTemplateResourceImpl.kt index 67437ab182d..8d092513c6e 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPipelineTemplateResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPipelineTemplateResourceImpl.kt @@ -55,6 +55,8 @@ class UserPipelineTemplateResourceImpl @Autowired constructor( userId = userId, templateType = templateType, storeFlag = storeFlag, + orderBy = null, + sort = null, page = page, pageSize = pageSize, keywords = keywords diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt index 76aaf8f1113..627ac20c761 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt @@ -73,8 +73,6 @@ import com.tencent.devops.store.pojo.atom.enums.JobTypeEnum import com.tencent.devops.store.pojo.common.ATOM_INPUT import com.tencent.devops.store.pojo.common.ATOM_NAMESPACE import com.tencent.devops.store.pojo.common.ATOM_OUTPUT -import java.util.concurrent.TimeUnit -import javax.ws.rs.core.Response import org.jooq.DSLContext import org.jooq.Record import org.slf4j.LoggerFactory @@ -82,6 +80,8 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service +import java.util.concurrent.TimeUnit +import javax.ws.rs.core.Response @Suppress("ALL") @Service diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt index 23a69069518..d0d7172c124 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt @@ -433,11 +433,6 @@ class PipelineBuildFacadeService( if (readyToBuildPipelineInfo.locked == true) { throw ErrorCodeException(errorCode = ProcessMessageCode.ERROR_PIPELINE_LOCK) } - if (!readyToBuildPipelineInfo.canManualStartup && checkManualStartup == false) { - throw ErrorCodeException( - errorCode = ProcessMessageCode.DENY_START_BY_MANUAL - ) - } val model = buildDetailService.getBuildModel(projectId, buildId) ?: throw ErrorCodeException( errorCode = ProcessMessageCode.ERROR_PIPELINE_MODEL_NOT_EXISTS diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index 1df01aa4e8b..781f002957c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -92,6 +92,8 @@ import com.tencent.devops.process.engine.dao.template.TemplatePipelineDao import com.tencent.devops.process.engine.utils.PipelineUtils import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.permission.template.PipelineTemplatePermissionService +import com.tencent.devops.process.pojo.PTemplateOrderByType +import com.tencent.devops.process.pojo.PTemplateSortType import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineTemplateInfo import com.tencent.devops.process.pojo.enums.TemplateSortTypeEnum @@ -689,6 +691,8 @@ class TemplateFacadeService @Autowired constructor( userId: String, templateType: TemplateType?, storeFlag: Boolean?, + orderBy: PTemplateOrderByType? = null, + sort: PTemplateSortType? = null, page: Int? = null, pageSize: Int? = null, keywords: String? = null @@ -702,6 +706,8 @@ class TemplateFacadeService @Autowired constructor( templateType = templateType, storeFlag = storeFlag, hasManagerPermission = hasManagerPermission, + orderBy = orderBy, + sort = sort, page = page, pageSize = pageSize, templateIds = null @@ -745,6 +751,8 @@ class TemplateFacadeService @Autowired constructor( storeFlag: Boolean?, hasManagerPermission: Boolean?, checkPermission: Boolean = true, + orderBy: PTemplateOrderByType? = null, + sort: PTemplateSortType? = null, page: Int?, pageSize: Int?, includePublicFlag: Boolean? = null, @@ -759,6 +767,8 @@ class TemplateFacadeService @Autowired constructor( includePublicFlag = includePublicFlag, templateType = templateType, storeFlag = storeFlag, + orderBy = orderBy, + sort = sort, offset = offset, pageSize = pageSize, hasManagerPermission = hasManagerPermission, @@ -781,6 +791,8 @@ class TemplateFacadeService @Autowired constructor( includePublicFlag = includePublicFlag, templateType = templateType, storeFlag = storeFlag, + orderBy = orderBy, + sort = sort, offset = offset, pageSize = pageSize, templatesByPermissionMap = templatesByPermissionMap @@ -793,6 +805,8 @@ class TemplateFacadeService @Autowired constructor( includePublicFlag: Boolean?, templateType: TemplateType?, storeFlag: Boolean?, + orderBy: PTemplateOrderByType?, + sort: PTemplateSortType?, offset: Int?, pageSize: Int?, hasManagerPermission: Boolean?, @@ -806,6 +820,8 @@ class TemplateFacadeService @Autowired constructor( templateType = templateType, templateIdList = templateIds, storeFlag = storeFlag, + orderBy = orderBy, + sort = sort, offset = offset, limit = pageSize, queryModelFlag = true @@ -837,6 +853,8 @@ class TemplateFacadeService @Autowired constructor( includePublicFlag: Boolean?, templateType: TemplateType?, storeFlag: Boolean?, + orderBy: PTemplateOrderByType?, + sort: PTemplateSortType?, offset: Int?, pageSize: Int?, templatesByPermissionMap: Map> @@ -868,6 +886,8 @@ class TemplateFacadeService @Autowired constructor( templateType = templateType, templateIdList = templatesWithListPermIds, storeFlag = storeFlag, + orderBy = orderBy, + sort = sort, offset = offset, limit = pageSize, queryModelFlag = true @@ -989,7 +1009,9 @@ class TemplateFacadeService @Autowired constructor( hasPermission = hasManagerPermission, canView = templateWithPermission.templatesWithViewPermIds?.contains(templateId), canDelete = templateWithPermission.templatesWithDeletePermIds?.contains(templateId), - canEdit = templateWithPermission.templatesWithEditPermIds?.contains(templateId) + canEdit = templateWithPermission.templatesWithEditPermIds?.contains(templateId), + creator = record[tTemplate.CREATOR], + updateTime = record[tTemplate.UPDATE_TIME].timestampmilli() ) ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PipelineTriggerEventService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PipelineTriggerEventService.kt index 82ee2bb573e..1f981c12a48 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PipelineTriggerEventService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PipelineTriggerEventService.kt @@ -28,22 +28,27 @@ package com.tencent.devops.process.trigger +import com.tencent.devops.common.api.constant.CommonMessageCode import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.exception.ParamBlankException import com.tencent.devops.common.api.model.SQLPage import com.tencent.devops.common.api.pojo.I18Variable import com.tencent.devops.common.api.util.JsonUtil +import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.api.util.timestampmilli +import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.client.Client import com.tencent.devops.common.service.trace.TraceTag import com.tencent.devops.common.service.utils.HomeHostUtil +import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.common.web.utils.I18nUtil.getCodeLanMessage import com.tencent.devops.common.webhook.enums.WebhookI18nConstants.EVENT_REPLAY_DESC import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.constant.ProcessMessageCode.ERROR_TRIGGER_DETAIL_NOT_FOUND import com.tencent.devops.process.constant.ProcessMessageCode.ERROR_TRIGGER_REPLAY_PIPELINE_NOT_EMPTY import com.tencent.devops.process.dao.PipelineTriggerEventDao +import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.trigger.PipelineTriggerDetail import com.tencent.devops.process.pojo.trigger.PipelineTriggerEvent import com.tencent.devops.process.pojo.trigger.PipelineTriggerEventVo @@ -55,6 +60,7 @@ import com.tencent.devops.process.pojo.trigger.RepoTriggerEventVo import com.tencent.devops.process.webhook.CodeWebhookEventDispatcher import com.tencent.devops.process.webhook.pojo.event.commit.ReplayWebhookEvent import com.tencent.devops.project.api.service.ServiceAllocIdResource +import com.tencent.devops.repository.api.ServiceRepositoryPermissionResource import org.jooq.DSLContext import org.jooq.impl.DSL import org.slf4j.LoggerFactory @@ -71,7 +77,8 @@ class PipelineTriggerEventService @Autowired constructor( private val dslContext: DSLContext, private val client: Client, private val pipelineTriggerEventDao: PipelineTriggerEventDao, - private val streamBridge: StreamBridge + private val streamBridge: StreamBridge, + private val pipelinePermissionService: PipelinePermissionService ) { companion object { @@ -343,6 +350,18 @@ class PipelineTriggerEventService @Autowired constructor( errorCode = ERROR_TRIGGER_REPLAY_PIPELINE_NOT_EMPTY, params = arrayOf(detailId.toString()) ) + val permission = AuthPermission.EXECUTE + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf(userId, projectId, permission.getI18n(I18nUtil.getLanguage(userId)), pipelineId) + ) + ) replayAll( userId = userId, projectId = projectId, @@ -371,6 +390,12 @@ class PipelineTriggerEventService @Autowired constructor( errorCode = ProcessMessageCode.ERROR_TRIGGER_TYPE_REPLAY_NOT_SUPPORT, params = arrayOf(triggerEvent.triggerType) ) + client.get(ServiceRepositoryPermissionResource::class).validatePermission( + userId = userId, + projectId = projectId, + repositoryHashId = triggerEvent.eventSource!!, + permission = AuthPermission.USE + ) // 保存重放事件 val requestId = MDC.get(TraceTag.BIZID) val replayEventId = getEventId() diff --git a/src/backend/ci/core/repository/api-repository/src/main/kotlin/com/tencent/devops/repository/api/ServiceRepositoryPermissionResource.kt b/src/backend/ci/core/repository/api-repository/src/main/kotlin/com/tencent/devops/repository/api/ServiceRepositoryPermissionResource.kt new file mode 100644 index 00000000000..eda6c5483c5 --- /dev/null +++ b/src/backend/ci/core/repository/api-repository/src/main/kotlin/com/tencent/devops/repository/api/ServiceRepositoryPermissionResource.kt @@ -0,0 +1,68 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.repository.api + +import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_USER_ID +import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.auth.api.AuthPermission +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.tags.Tag +import javax.ws.rs.Consumes +import javax.ws.rs.GET +import javax.ws.rs.HeaderParam +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.QueryParam +import javax.ws.rs.core.MediaType + +@Tag(name = "SERVICE_PIPELINE_PERMISSION", description = "服务-流水线-鉴权") +@Path("/service/repositories/permission") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +interface ServiceRepositoryPermissionResource { + + @GET + @Path("/{projectId}/{repositoryHashId}/validate") + @Operation(summary = "校验用户是否有具体操作的权限") + fun validatePermission( + @HeaderParam(AUTH_HEADER_DEVOPS_USER_ID) + @Parameter(description = "待校验用户ID", required = true) + userId: String, + @Parameter(description = "项目ID", required = true) + @PathParam("projectId") + projectId: String, + @Parameter(description = "代码库hashId", required = true) + @PathParam("repositoryHashId") + repositoryHashId: String, + @QueryParam("permission") + @Parameter(description = "操作权限", required = false) + permission: AuthPermission + ): Result +} diff --git a/src/backend/ci/core/repository/api-repository/src/main/kotlin/com/tencent/devops/repository/constant/RepositoryMessageCode.kt b/src/backend/ci/core/repository/api-repository/src/main/kotlin/com/tencent/devops/repository/constant/RepositoryMessageCode.kt index 9ddc4cc7723..a0f561300a1 100644 --- a/src/backend/ci/core/repository/api-repository/src/main/kotlin/com/tencent/devops/repository/constant/RepositoryMessageCode.kt +++ b/src/backend/ci/core/repository/api-repository/src/main/kotlin/com/tencent/devops/repository/constant/RepositoryMessageCode.kt @@ -95,6 +95,8 @@ object RepositoryMessageCode { const val NOT_GITHUB_AUTHORIZED_BY_OAUTH = "2115044" // 用户[{0}]尚未进行GITHUB OAUTH授权,请先授权。 const val REPOSITORY_NO_SUPPORT_OAUTH = "2115045" // ({0})类型代码库暂不支持OAUTH授权 + const val USER_NOT_PERMISSIONS_OPERATE_REPOSITORY = "2115046" // 用户({0})无权限在工程({1})下{2}流水线{3} + const val BK_REQUEST_FILE_SIZE_LIMIT = "bkRequestFileSizeLimit" // 请求文件不能超过1M const val OPERATION_ADD_CHECK_RUNS = "OperationAddCheckRuns" // 添加检测任务 const val OPERATION_UPDATE_CHECK_RUNS = "OperationUpdateCheckRuns" // 更新检测任务 diff --git a/src/backend/ci/core/repository/biz-repository/src/main/kotlin/com/tencent/devops/repository/resources/ServiceRepositoryPermissionResourceImpl.kt b/src/backend/ci/core/repository/biz-repository/src/main/kotlin/com/tencent/devops/repository/resources/ServiceRepositoryPermissionResourceImpl.kt new file mode 100644 index 00000000000..df5bb4bb650 --- /dev/null +++ b/src/backend/ci/core/repository/biz-repository/src/main/kotlin/com/tencent/devops/repository/resources/ServiceRepositoryPermissionResourceImpl.kt @@ -0,0 +1,70 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.repository.resources + +import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.api.util.HashUtil +import com.tencent.devops.common.api.util.MessageUtil +import com.tencent.devops.common.auth.api.AuthPermission +import com.tencent.devops.common.web.RestResource +import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.repository.api.ServiceRepositoryPermissionResource +import com.tencent.devops.repository.constant.RepositoryMessageCode +import com.tencent.devops.repository.service.RepositoryPermissionService +import org.springframework.beans.factory.annotation.Autowired + +@RestResource +class ServiceRepositoryPermissionResourceImpl @Autowired constructor( + private val repositoryPermissionService: RepositoryPermissionService +) : ServiceRepositoryPermissionResource { + override fun validatePermission( + userId: String, + projectId: String, + repositoryHashId: String, + permission: AuthPermission + ): Result { + val repositoryId = HashUtil.decodeOtherIdToLong(repositoryHashId) + repositoryPermissionService.validatePermission( + userId = userId, + projectId = projectId, + authPermission = permission, + repositoryId = repositoryId, + message = MessageUtil.getMessageByLocale( + messageCode = RepositoryMessageCode.USER_NOT_PERMISSIONS_OPERATE_REPOSITORY, + params = arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + repositoryHashId + ), + language = I18nUtil.getLanguage(userId) + ) + ) + return Result(true) + } +} diff --git a/support-files/i18n/repository/message_en_US.properties b/support-files/i18n/repository/message_en_US.properties index b59ec9c03cd..a6ebabe38e3 100644 --- a/support-files/i18n/repository/message_en_US.properties +++ b/support-files/i18n/repository/message_en_US.properties @@ -46,6 +46,7 @@ 2115043=User ({0}) does not have pull access to the ({2}) repository 2115044=User [{0}] has not authorized Github Oauth yet. Please authorize first 2115045=({0}) type of code repository does not currently support OAUTH authorization +2100054=User ({0}) does not have permission to {2} repository {3} under project ({1}). bkRequestFileSizeLimit=The request file cannot exceed 1m OperationAddCheckRuns=Add a detection task OperationUpdateCheckRuns=Update the detection task diff --git a/support-files/i18n/repository/message_zh_CN.properties b/support-files/i18n/repository/message_zh_CN.properties index b832d9be1b8..7b08079fde9 100644 --- a/support-files/i18n/repository/message_zh_CN.properties +++ b/support-files/i18n/repository/message_zh_CN.properties @@ -45,6 +45,7 @@ 2115043=用户 ({0}) 无 ({2}) 代码库的拉取权限 2115044=用户[{0}]尚未进行GITHUB OAUTH授权,请先授权 2115045=({0})类型代码库暂不支持OAUTH授权 +2115046=用户({0})无权限在工程({1})下{2}代码库{3} bkRequestFileSizeLimit=请求文件不能超过1M OperationAddCheckRuns=添加检测任务 OperationUpdateCheckRuns=更新检测任务