Skip to content

Commit

Permalink
feat:用户个人视角 权限管理优化 #11138
Browse files Browse the repository at this point in the history
  • Loading branch information
fcfang123 committed Dec 18, 2024
1 parent fd9528b commit 2cca032
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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" // 蓝盾项目
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -640,7 +639,7 @@ class AuthResourceGroupMemberDao {
fun buildExcludeMemberGroupCondition(
excludeIamGroupIds: List<Int>?,
// 仅排除用户直接加入的组
onlyExcludeUserDirectlyJoined: Boolean?,
onlyExcludeUserDirectlyJoined: Boolean?
): MutableList<Condition> {
val conditions = mutableListOf<Condition>()
with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -128,21 +127,21 @@ class RbacPermissionHandoverApplicationService(
titleOfApplication = titleOfApplication.plus(groupCount).plus(
bkHandoverGroups.plus("").plus(authorizationCount).plus(bkHandoverAuthorizations)
)
handoverOverviewContentOfEmail = """<span class="num">${groupCount}</span>$bkHandoverGroups,<span class="num">${authorizationCount}</span>$bkHandoverAuthorizations""".trimMargin()
handoverOverviewContentOfEmail = """<span class="num">$groupCount</span>$bkHandoverGroups,<span class="num">$authorizationCount</span>$bkHandoverAuthorizations""".trimMargin()
handoverOverviewContentOfRtx = handoverOverviewContentOfRtx.plus(groupCount).plus(
bkHandoverGroups.plus("").plus(authorizationCount).plus(bkHandoverAuthorizations)
)
}

groupCount > 0 -> {
titleOfApplication = titleOfApplication.plus(groupCount).plus(bkHandoverGroups)
handoverOverviewContentOfEmail = """<span class="num">${groupCount}</span>$bkHandoverGroups""".trimMargin()
handoverOverviewContentOfEmail = """<span class="num">$groupCount</span>$bkHandoverGroups""".trimMargin()
handoverOverviewContentOfRtx = handoverOverviewContentOfRtx.plus(groupCount).plus(bkHandoverGroups)
}

else -> {
titleOfApplication = titleOfApplication.plus(authorizationCount).plus(bkHandoverAuthorizations)
handoverOverviewContentOfEmail = """<span class="num">${authorizationCount}</span>$bkHandoverAuthorizations""".trimMargin()
handoverOverviewContentOfEmail = """<span class="num">$authorizationCount</span>$bkHandoverAuthorizations""".trimMargin()
handoverOverviewContentOfRtx = handoverOverviewContentOfRtx.plus(authorizationCount).plus(bkHandoverAuthorizations)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -693,6 +712,61 @@ class RbacPermissionManageFacadeServiceImpl(
}
}

private fun getNotExpiredIamGroupIds(
projectCode: String,
memberId: String,
iamGroupIds: List<Int>
): List<Int> {
return authResourceGroupMemberDao.listMemberGroupDetail(
dslContext = dslContext,
projectCode = projectCode,
memberId = memberId,
iamGroupIds = iamGroupIds,
minExpiredAt = LocalDateTime.now()
).map { it.iamGroupId }
}

private fun checkProjectVisitPermission(
projectCode: String,
iamGroupIds: List<Int>
): 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<Int>
): 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<Int>,
Expand All @@ -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(
Expand All @@ -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(
Expand Down Expand Up @@ -828,80 +903,6 @@ class RbacPermissionManageFacadeServiceImpl(
return InvalidAuthorizationsDTO(emptyList(), emptyList())
}

private fun listInvalidReposAndNodesAfterOperatedGroups(
projectCode: String,
iamGroupIds: List<Int>,
memberId: String
): Pair<List<String>/*invalidRepositoryIds*/, List<String>/*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,
Expand Down Expand Up @@ -1355,7 +1356,7 @@ class RbacPermissionManageFacadeServiceImpl(
projectCode = projectCode,
repertoryIds = invalidRepertoryIds,
handoverFrom = removeMemberDTO.targetMember.id,
handoverTo = removeMemberDTO.handoverTo!!.id,
handoverTo = removeMemberDTO.handoverTo!!.id
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ class RbacPermissionResourceValidateService(
dslContext = dslContext,
condition = ResourceAuthorizationConditionRequest(
projectCode = projectCode,
handoverFrom = userId,
handoverFrom = userId
)
) > 0
if (!isUserHasProjectAuthorizations) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import com.tencent.devops.common.api.model.SQLPage

class SamplePermissionHandoverApplicationService : PermissionHandoverApplicationService {
override fun createHandoverApplication(
overview: HandoverOverviewCreateDTO, details: List<HandoverDetailDTO>
overview: HandoverOverviewCreateDTO,
details: List<HandoverDetailDTO>
): String {
return ""
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ interface PermissionManageFacadeService {
* 1、引起代持人权限失效的用户组。
* 2、引起代持人权限失效的流水线。
* 3、引起代码库oauth失效的代码库(当用户操作完组后,不再拥有项目访问权限时,会代码库oauth引起失效)
* 4、引起失效的环境节点授权
**/
fun listInvalidAuthorizationsAfterOperatedGroups(
projectCode: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ data class StartBuildContext(
*/
private fun fillCascadeParam(
param: BuildParameters,
originStartContexts: HashMap<String, BuildParameters>,
originStartContexts: HashMap<String, BuildParameters>
): List<BuildParameters> {
val originStartParams = mutableListOf<BuildParameters>()
val key = param.key
Expand Down

0 comments on commit 2cca032

Please sign in to comment.