From 2cca03283eaf219f24700c905d0387f2bca69d4a Mon Sep 17 00:00:00 2001 From: greysonfang Date: Wed, 18 Dec 2024 15:27:56 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E7=94=A8=E6=88=B7=E4=B8=AA?= =?UTF-8?q?=E4=BA=BA=E8=A7=86=E8=A7=92=20=E6=9D=83=E9=99=90=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E4=BC=98=E5=8C=96=20#11138?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/constant/AuthI18nConstants.kt | 2 +- .../auth/dao/AuthResourceGroupMemberDao.kt | 3 +- ...bacPermissionHandoverApplicationService.kt | 7 +- .../RbacPermissionManageFacadeServiceImpl.kt | 175 +++++++++--------- .../RbacPermissionResourceGroupSyncService.kt | 3 +- .../RbacPermissionResourceValidateService.kt | 2 +- ...plePermissionHandoverApplicationService.kt | 3 +- .../iam/PermissionManageFacadeService.kt | 1 + .../process/pojo/app/StartBuildContext.kt | 2 +- 9 files changed, 99 insertions(+), 99 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/constant/AuthI18nConstants.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/constant/AuthI18nConstants.kt index 53bd5e71fe9..a6ecd767309 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/constant/AuthI18nConstants.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/constant/AuthI18nConstants.kt @@ -50,6 +50,6 @@ object AuthI18nConstants { const val BK_APPLY_TO_HANDOVER = "bkApplyToHandover" // 申请移交 const val BK_HANDOVER_GROUPS = "bkHandoverGroups" // 个权限用户组 - const val BK_HANDOVER_AUTHORIZATIONS = "bkHandoverAuthorizations" //个授权 + const val BK_HANDOVER_AUTHORIZATIONS = "bkHandoverAuthorizations" // 个授权 const val BK_PROJECT = "bk_project" // 蓝盾项目 } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupMemberDao.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupMemberDao.kt index 2c78d21c4c6..e8fbeab2883 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupMemberDao.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupMemberDao.kt @@ -31,7 +31,6 @@ import com.tencent.devops.auth.pojo.AuthResourceGroupMember import com.tencent.devops.auth.pojo.ResourceMemberInfo import com.tencent.devops.auth.pojo.dto.ProjectMembersQueryConditionDTO import com.tencent.devops.auth.pojo.enum.MemberType -import com.tencent.devops.auth.pojo.enum.OperateChannel import com.tencent.devops.common.auth.api.pojo.BkAuthGroup import com.tencent.devops.common.db.utils.skipCheck import com.tencent.devops.model.auth.tables.TAuthResourceAuthorization @@ -640,7 +639,7 @@ class AuthResourceGroupMemberDao { fun buildExcludeMemberGroupCondition( excludeIamGroupIds: List?, // 仅排除用户直接加入的组 - onlyExcludeUserDirectlyJoined: Boolean?, + onlyExcludeUserDirectlyJoined: Boolean? ): MutableList { val conditions = mutableListOf() with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionHandoverApplicationService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionHandoverApplicationService.kt index fc733335eba..9d25d166f20 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionHandoverApplicationService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionHandoverApplicationService.kt @@ -39,7 +39,6 @@ import org.jooq.impl.DSL import org.slf4j.LoggerFactory import java.time.LocalDateTime - class RbacPermissionHandoverApplicationService( private val dslContext: DSLContext, private val handoverOverviewDao: AuthHandoverOverviewDao, @@ -128,7 +127,7 @@ class RbacPermissionHandoverApplicationService( titleOfApplication = titleOfApplication.plus(groupCount).plus( bkHandoverGroups.plus(",").plus(authorizationCount).plus(bkHandoverAuthorizations) ) - handoverOverviewContentOfEmail = """${groupCount}$bkHandoverGroups,${authorizationCount}$bkHandoverAuthorizations""".trimMargin() + handoverOverviewContentOfEmail = """$groupCount$bkHandoverGroups,$authorizationCount$bkHandoverAuthorizations""".trimMargin() handoverOverviewContentOfRtx = handoverOverviewContentOfRtx.plus(groupCount).plus( bkHandoverGroups.plus(",").plus(authorizationCount).plus(bkHandoverAuthorizations) ) @@ -136,13 +135,13 @@ class RbacPermissionHandoverApplicationService( groupCount > 0 -> { titleOfApplication = titleOfApplication.plus(groupCount).plus(bkHandoverGroups) - handoverOverviewContentOfEmail = """${groupCount}$bkHandoverGroups""".trimMargin() + handoverOverviewContentOfEmail = """$groupCount$bkHandoverGroups""".trimMargin() handoverOverviewContentOfRtx = handoverOverviewContentOfRtx.plus(groupCount).plus(bkHandoverGroups) } else -> { titleOfApplication = titleOfApplication.plus(authorizationCount).plus(bkHandoverAuthorizations) - handoverOverviewContentOfEmail = """${authorizationCount}$bkHandoverAuthorizations""".trimMargin() + handoverOverviewContentOfEmail = """$authorizationCount$bkHandoverAuthorizations""".trimMargin() handoverOverviewContentOfRtx = handoverOverviewContentOfRtx.plus(authorizationCount).plus(bkHandoverAuthorizations) } } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionManageFacadeServiceImpl.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionManageFacadeServiceImpl.kt index 1365511b9d4..69798f4336a 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionManageFacadeServiceImpl.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionManageFacadeServiceImpl.kt @@ -665,21 +665,40 @@ class RbacPermissionManageFacadeServiceImpl( ): InvalidAuthorizationsDTO { val startEpoch = System.currentTimeMillis() try { - val (invalidGroups, invalidPipelines) = listInvalidPipelinesAfterOperatedGroups( + // 筛选出本次操作中未过期的用户组 + val iamGroupIdsOfNotExpired = getNotExpiredIamGroupIds( projectCode = projectCode, - iamGroupIds = iamGroupIds, - memberId = memberId + memberId = memberId, + iamGroupIds = iamGroupIds + ) + // 获取用户退出/交接以上用户组后,还未退出的用户组 + val (count, userGroupsJoinedAfterOperatedGroups) = listResourceGroupMembers( + projectCode = projectCode, + memberId = memberId, + excludeIamGroupIds = iamGroupIds, + onlyExcludeUserDirectlyJoined = true, + operateChannel = OperateChannel.PERSONAL, + minExpiredAt = LocalDateTime.now().timestampmilli() ) - val (invalidRepositoryIds, invalidEnvNodeIds) = listInvalidReposAndNodesAfterOperatedGroups( + logger.debug("list all user groups joined after operated groups: {}, {}", count, userGroupsJoinedAfterOperatedGroups) + + val isHasProjectVisitPermAfterOperatedGroups = checkProjectVisitPermission( + projectCode = projectCode, + iamGroupIds = userGroupsJoinedAfterOperatedGroups.map { it.iamGroupId } + ) + logger.debug("whether the user has project visit perm after operated groups: {}", isHasProjectVisitPermAfterOperatedGroups) + + if (count == 0L || !isHasProjectVisitPermAfterOperatedGroups) { + return getInvalidAuthorizationsAfterAllGroupsRemoved(projectCode, memberId, iamGroupIdsOfNotExpired) + } + val (invalidGroups, invalidPipelines) = listInvalidPipelinesAfterOperatedGroups( projectCode = projectCode, iamGroupIds = iamGroupIds, memberId = memberId ) val invalidAuthorizationsDTO = InvalidAuthorizationsDTO( invalidGroupIds = invalidGroups, - invalidPipelineIds = invalidPipelines, - invalidRepertoryIds = invalidRepositoryIds, - invalidEnvNodeIds = invalidEnvNodeIds + invalidPipelineIds = invalidPipelines ) logger.info( "invalid authorizations after operated groups|$projectCode|$iamGroupIds|$memberId|$invalidAuthorizationsDTO" @@ -693,6 +712,61 @@ class RbacPermissionManageFacadeServiceImpl( } } + private fun getNotExpiredIamGroupIds( + projectCode: String, + memberId: String, + iamGroupIds: List + ): List { + return authResourceGroupMemberDao.listMemberGroupDetail( + dslContext = dslContext, + projectCode = projectCode, + memberId = memberId, + iamGroupIds = iamGroupIds, + minExpiredAt = LocalDateTime.now() + ).map { it.iamGroupId } + } + + private fun checkProjectVisitPermission( + projectCode: String, + iamGroupIds: List + ): Boolean { + return groupPermissionService.isGroupsHasPermission( + projectCode = projectCode, + filterIamGroupIds = iamGroupIds, + relatedResourceType = ResourceTypeId.PROJECT, + relatedResourceCode = projectCode, + action = ActionId.PROJECT_VISIT + ) + } + + private fun getInvalidAuthorizationsAfterAllGroupsRemoved( + projectCode: String, + memberId: String, + iamGroupIdsOfNotExpired: List + ): InvalidAuthorizationsDTO { + val invalidAuthorizations = authAuthorizationDao.list( + dslContext = dslContext, + condition = ResourceAuthorizationConditionRequest( + projectCode = projectCode, + handoverFrom = memberId + ) + ).groupBy({ it.resourceType }, { it.resourceCode }) + + val operatedGroupsWithExecutePerm = groupPermissionService.listGroupsByPermissionConditions( + projectCode = projectCode, + relatedResourceType = AuthResourceType.PIPELINE_DEFAULT.value, + action = ActionId.PIPELINE_EXECUTE, + filterIamGroupIds = iamGroupIdsOfNotExpired + ) + + return InvalidAuthorizationsDTO( + invalidGroupIds = operatedGroupsWithExecutePerm, + invalidPipelineIds = invalidAuthorizations[ResourceTypeId.PIPELINE] ?: emptyList(), + invalidRepertoryIds = invalidAuthorizations[ResourceTypeId.REPERTORY] ?: emptyList(), + invalidEnvNodeIds = invalidAuthorizations[ResourceTypeId.ENV_NODE] ?: emptyList() + ) + } + private fun listInvalidPipelinesAfterOperatedGroups( projectCode: String, iamGroupIds: List, @@ -701,13 +775,11 @@ class RbacPermissionManageFacadeServiceImpl( logger.info("list invalid authorizations after operated groups:$projectCode|$iamGroupIds|$memberId") val now = LocalDateTime.now() // 0.筛选出本次操作中的用户未过期用户组ID - val iamGroupIdsOfNotExpired = authResourceGroupMemberDao.listMemberGroupDetail( - dslContext = dslContext, + val iamGroupIdsOfNotExpired = getNotExpiredIamGroupIds( projectCode = projectCode, memberId = memberId, - iamGroupIds = iamGroupIds, - minExpiredAt = now - ).map { it.iamGroupId } + iamGroupIds = iamGroupIds + ) logger.debug("list iam group ids of not expired:{}", iamGroupIdsOfNotExpired) // 1.筛选出本次退出/交接中包含流水线执行权限的用户组 val operatedGroupsWithExecutePerm = groupPermissionService.listGroupsByPermissionConditions( @@ -717,6 +789,9 @@ class RbacPermissionManageFacadeServiceImpl( filterIamGroupIds = iamGroupIdsOfNotExpired ) logger.debug("list operated groups with execute perm:{}", operatedGroupsWithExecutePerm) + if (operatedGroupsWithExecutePerm.isEmpty()) { + return InvalidAuthorizationsDTO(emptyList(), emptyList()) + } // 2.获取用户退出/交接以上操作的用户组后,还未退出并且未过期的流水线/项目级别(仅这些类型会包含流水线执行权限)的用户组。 val userGroupsJoinedAfterOperatedGroups = listResourceGroupMembers( @@ -828,80 +903,6 @@ class RbacPermissionManageFacadeServiceImpl( return InvalidAuthorizationsDTO(emptyList(), emptyList()) } - private fun listInvalidReposAndNodesAfterOperatedGroups( - projectCode: String, - iamGroupIds: List, - memberId: String - ): Pair/*invalidRepositoryIds*/, List/*invalidEnvNodeIds*/> { - // 获取用户退出/交接以上用户组后还加入并且未过期的用户组 - val (count, records) = listResourceGroupMembers( - projectCode = projectCode, - memberId = memberId, - excludeIamGroupIds = iamGroupIds, - onlyExcludeUserDirectlyJoined = true, - operateChannel = OperateChannel.PERSONAL, - minExpiredAt = LocalDateTime.now().timestampmilli() - ) - logger.debug("list all user groups joined after operated groups:{}|{}", count, records) - // 如果退出/交接了项目下所有组,直接返回用户无效代码库oauth列表 - if (count == 0L) { - logger.debug("The user has removed/handover all user groups") - val invalidRepositoryIds = authAuthorizationDao.list( - dslContext = dslContext, - condition = ResourceAuthorizationConditionRequest( - projectCode = projectCode, - resourceType = ResourceTypeId.REPERTORY, - handoverFrom = memberId - ) - ).map { it.resourceCode } - val invalidEnvNodeIds = authAuthorizationDao.list( - dslContext = dslContext, - condition = ResourceAuthorizationConditionRequest( - projectCode = projectCode, - resourceType = ResourceTypeId.ENV_NODE, - handoverFrom = memberId - ) - ).map { it.resourceCode } - return Pair(invalidRepositoryIds, invalidEnvNodeIds) - } - - // 检查用户是否还有权限访问权限当退出/交接以上组后 - val isHasProjectVisitPermOperatedGroups = groupPermissionService.isGroupsHasPermission( - projectCode = projectCode, - filterIamGroupIds = records.map { it.iamGroupId }, - relatedResourceType = ResourceTypeId.PROJECT, - relatedResourceCode = projectCode, - action = ActionId.PROJECT_VISIT - ) - logger.debug("whether the user has project visit perm after operated groups {}", isHasProjectVisitPermOperatedGroups) - // 如果有访问权限,返回空列表,否则直接返回用户无效代码库oauth列表/环境节点授权 - return if (isHasProjectVisitPermOperatedGroups) { - Pair(emptyList(), emptyList()) - } else { - logger.debug( - "user does not have perm to visit the project after operated groups|{}|{}|{}", - projectCode, memberId, iamGroupIds - ) - val invalidRepositoryIds = authAuthorizationDao.list( - dslContext = dslContext, - condition = ResourceAuthorizationConditionRequest( - projectCode = projectCode, - resourceType = ResourceTypeId.REPERTORY, - handoverFrom = memberId - ) - ).map { it.resourceCode } - val invalidEnvNodeIds = authAuthorizationDao.list( - dslContext = dslContext, - condition = ResourceAuthorizationConditionRequest( - projectCode = projectCode, - resourceType = ResourceTypeId.ENV_NODE, - handoverFrom = memberId - ) - ).map { it.resourceCode } - return Pair(invalidRepositoryIds, invalidEnvNodeIds) - } - } - override fun renewalGroupMember( userId: String, projectCode: String, @@ -1355,7 +1356,7 @@ class RbacPermissionManageFacadeServiceImpl( projectCode = projectCode, repertoryIds = invalidRepertoryIds, handoverFrom = removeMemberDTO.targetMember.id, - handoverTo = removeMemberDTO.handoverTo!!.id, + handoverTo = removeMemberDTO.handoverTo!!.id ) } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceGroupSyncService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceGroupSyncService.kt index 2742d6ff082..13b9f4f427e 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceGroupSyncService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceGroupSyncService.kt @@ -40,8 +40,8 @@ import com.tencent.devops.auth.pojo.AuthResourceGroup import com.tencent.devops.auth.pojo.AuthResourceGroupMember import com.tencent.devops.auth.pojo.enum.ApplyToGroupStatus import com.tencent.devops.auth.pojo.enum.AuthMigrateStatus -import com.tencent.devops.auth.service.DeptService import com.tencent.devops.auth.pojo.enum.MemberType +import com.tencent.devops.auth.service.DeptService import com.tencent.devops.auth.service.iam.PermissionResourceGroupPermissionService import com.tencent.devops.auth.service.iam.PermissionResourceGroupSyncService import com.tencent.devops.auth.service.lock.SyncGroupAndMemberLock @@ -63,7 +63,6 @@ import org.slf4j.LoggerFactory import org.slf4j.MDC import org.springframework.beans.factory.annotation.Autowired import java.time.LocalDateTime -import java.util.concurrent.Callable import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletionException import java.util.concurrent.Executors diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceValidateService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceValidateService.kt index ea065a680f2..4e3d651924e 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceValidateService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceValidateService.kt @@ -178,7 +178,7 @@ class RbacPermissionResourceValidateService( dslContext = dslContext, condition = ResourceAuthorizationConditionRequest( projectCode = projectCode, - handoverFrom = userId, + handoverFrom = userId ) ) > 0 if (!isUserHasProjectAuthorizations) { diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionHandoverApplicationService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionHandoverApplicationService.kt index 076da2c1369..b0be465262b 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionHandoverApplicationService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionHandoverApplicationService.kt @@ -15,7 +15,8 @@ import com.tencent.devops.common.api.model.SQLPage class SamplePermissionHandoverApplicationService : PermissionHandoverApplicationService { override fun createHandoverApplication( - overview: HandoverOverviewCreateDTO, details: List + overview: HandoverOverviewCreateDTO, + details: List ): String { return "" } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionManageFacadeService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionManageFacadeService.kt index f509eae81fa..34c26a12e7e 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionManageFacadeService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionManageFacadeService.kt @@ -115,6 +115,7 @@ interface PermissionManageFacadeService { * 1、引起代持人权限失效的用户组。 * 2、引起代持人权限失效的流水线。 * 3、引起代码库oauth失效的代码库(当用户操作完组后,不再拥有项目访问权限时,会代码库oauth引起失效) + * 4、引起失效的环境节点授权 **/ fun listInvalidAuthorizationsAfterOperatedGroups( projectCode: String, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/app/StartBuildContext.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/app/StartBuildContext.kt index fb8ad79b289..d8ffd3e3629 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/app/StartBuildContext.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/app/StartBuildContext.kt @@ -481,7 +481,7 @@ data class StartBuildContext( */ private fun fillCascadeParam( param: BuildParameters, - originStartContexts: HashMap, + originStartContexts: HashMap ): List { val originStartParams = mutableListOf() val key = param.key