From 9e8757090c449928d9546b6e63f632c1198939e8 Mon Sep 17 00:00:00 2001 From: greysonfang Date: Tue, 3 Sep 2024 11:03:07 +0800 Subject: [PATCH 01/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserAuthResourceGroupResource.kt | 6 + .../user/UserAuthResourceMemberResource.kt | 23 ++- .../dto/ProjectMembersQueryConditionDTO.kt | 57 ++++++ .../ProjectMembersQueryConditionReq.kt | 30 +++ .../devops/auth/dao/AuthAuthorizationDao.kt | 2 +- .../devops/auth/dao/AuthResourceGroupDao.kt | 22 ++- .../auth/dao/AuthResourceGroupMemberDao.kt | 76 +++++++- .../RbacPermissionResourceMemberService.kt | 175 ++++++++++++++++-- .../SamplePermissionResourceMemberService.kt | 13 +- .../UserAuthResourceGroupResourceImpl.kt | 4 + .../UserAuthResourceMemberResourceImpl.kt | 22 ++- .../iam/PermissionResourceMemberService.kt | 24 ++- 12 files changed, 425 insertions(+), 29 deletions(-) create mode 100644 src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt create mode 100644 src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt index 50d7ce1996c..158da1ba0ca 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt @@ -92,6 +92,12 @@ interface UserAuthResourceGroupResource { @QueryParam("memberId") @Parameter(description = "组织ID/成员ID") memberId: String, + @QueryParam("groupName") + @Parameter(description = "用户组名称") + groupName: String?, + @QueryParam("expiredAt") + @Parameter(description = "过期时间戳-毫秒级") + expiredAt: Long?, @Parameter(description = "起始位置,从0开始") @QueryParam("start") start: Int, diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceMemberResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceMemberResource.kt index 8e0da2fd2f1..7959ddcb5ce 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceMemberResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceMemberResource.kt @@ -6,6 +6,7 @@ import com.tencent.devops.auth.pojo.request.GroupMemberCommonConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberHandoverConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberRenewalConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberSingleRenewalReq +import com.tencent.devops.auth.pojo.request.ProjectMembersQueryConditionReq import com.tencent.devops.auth.pojo.request.RemoveMemberFromProjectReq import com.tencent.devops.auth.pojo.vo.BatchOperateGroupMemberCheckVo import com.tencent.devops.auth.pojo.vo.GroupDetailsInfoVo @@ -64,6 +65,20 @@ interface UserAuthResourceMemberResource { pageSize: Int ): Result> + @POST + @Path("/listProjectMembersByCondition") + @Operation(summary = "根据条件获取项目下全体成员") + fun listProjectMembersByCondition( + @Parameter(description = "用户名", required = true) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @Parameter(description = "项目ID", required = true) + @PathParam("projectId") + projectId: String, + @Parameter(description = "查询条件", required = true) + projectMembersQueryConditionReq: ProjectMembersQueryConditionReq + ): Result> + @PUT @Path("/renewal") @Operation(summary = "续期单个组成员权限--无需进行审批") @@ -177,6 +192,12 @@ interface UserAuthResourceMemberResource { projectId: String, @QueryParam("memberId") @Parameter(description = "组织ID/成员ID") - memberId: String + memberId: String, + @QueryParam("groupName") + @Parameter(description = "用户组名称") + groupName: String?, + @QueryParam("expiredAt") + @Parameter(description = "过期时间") + expiredAt: Long? ): Result> } diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt new file mode 100644 index 00000000000..614bb52c8c2 --- /dev/null +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt @@ -0,0 +1,57 @@ +package com.tencent.devops.auth.pojo.dto + +import com.tencent.devops.auth.pojo.request.ProjectMembersQueryConditionReq +import com.tencent.devops.common.api.util.DateTimeUtil +import com.tencent.devops.common.api.util.PageUtil +import io.swagger.v3.oas.annotations.media.Schema +import java.time.LocalDateTime + +@Schema(title = "项目成员查询业务处理实体") +data class ProjectMembersQueryConditionDTO( + @get:Schema(title = "项目ID") + val projectCode: String, + @get:Schema(title = "成员类型") + val memberType: String?, + @get:Schema(title = "用户名称") + val userName: String?, + @get:Schema(title = "部门名称") + val deptName: String?, + @get:Schema(title = "用户组名称") + val groupName: String?, + @get:Schema(title = "用户组Id") + val iamGroupIds: List?, + @get:Schema(title = "过期时间") + val expiredTime: LocalDateTime?, + @get:Schema(title = "离职标识") + val departedFlag: Boolean? = false, + @get:Schema(title = "是否查询模板") + val queryTemplate: Boolean? = false, + @get:Schema(title = "限制") + val limit: Int, + @get:Schema(title = "起始值") + val offset: Int +) { + companion object { + fun build( + projectMembersQueryConditionReq: ProjectMembersQueryConditionReq, + iamGroupIds: List? + ): ProjectMembersQueryConditionDTO { + return with(projectMembersQueryConditionReq) { + val expiredTime = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it) } + val limit = PageUtil.convertPageSizeToSQLLimit(page, pageSize) + ProjectMembersQueryConditionDTO( + projectCode = projectCode, + memberType = memberType, + userName = userName, + deptName = deptName, + groupName = groupName, + iamGroupIds = iamGroupIds, + expiredTime = expiredTime, + departedFlag = departedFlag, + limit = limit.limit, + offset = limit.offset + ) + } + } + } +} diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt new file mode 100644 index 00000000000..d07efb9ae8a --- /dev/null +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt @@ -0,0 +1,30 @@ +package com.tencent.devops.auth.pojo.request + +import io.swagger.v3.oas.annotations.media.Schema + +@Schema(title = "项目成员查询业务处理请求体") +data class ProjectMembersQueryConditionReq( + @get:Schema(title = "项目ID") + val projectCode: String, + @get:Schema(title = "成员类型") + val memberType: String?, + @get:Schema(title = "用户名称") + val userName: String?, + @get:Schema(title = "部门名称") + val deptName: String?, + @get:Schema(title = "用户组名称") + val groupName: String?, + @get:Schema(title = "过期时间") + val expiredAt: Long?, + @get:Schema(title = "离职标识") + val departedFlag: Boolean? = false, + @get:Schema(title = "第几页") + val page: Int, + @get:Schema(title = "页数") + val pageSize: Int +) { + // 当查询到权限相关信息时,如组名称,过期时间,操作,资源类型时,走复杂查询逻辑 + fun isComplexQuery(): Boolean { + return groupName != null || expiredAt != null + } +} diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthAuthorizationDao.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthAuthorizationDao.kt index ef94562a6fc..4dc56b5b18d 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthAuthorizationDao.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthAuthorizationDao.kt @@ -96,7 +96,7 @@ class AuthAuthorizationDao { .set(HANDOVER_FROM_CN_NAME, resourceAuthorizationDto.handoverToCnName) .set(HANDOVER_TIME, LocalDateTime.now()) } else { - it + it.set(HANDOVER_TIME, HANDOVER_TIME) } } .set(RESOURCE_NAME, resourceAuthorizationDto.resourceName) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt index 49efc0066bd..b288b93739f 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt @@ -252,12 +252,30 @@ class AuthResourceGroupDao { fun listIamGroupIdsByConditions( dslContext: DSLContext, projectCode: String, - iamGroupIds: List + iamGroupIds: List? = null, + groupName: String? = null, + iamTemplateIds: List? = null ): List { return with(TAuthResourceGroup.T_AUTH_RESOURCE_GROUP) { dslContext.select(RELATION_ID).from(this) .where(PROJECT_CODE.eq(projectCode)) - .and(RELATION_ID.`in`(iamGroupIds)) + .let { + if (!iamGroupIds.isNullOrEmpty()) + it.and(RELATION_ID.`in`(iamGroupIds)) + else it + } + .let { + if (groupName != null) + it.and(GROUP_NAME.like("%$groupName%")) + else + it + } + .let { + if (!iamTemplateIds.isNullOrEmpty()) + it.and(IAM_TEMPLATE_ID.`in`(iamTemplateIds)) + else + it + } .fetch().map { it.value1().toInt() } } } 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 1d95eb1b2f8..cb530cb2570 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 @@ -30,6 +30,7 @@ package com.tencent.devops.auth.dao import com.tencent.bk.sdk.iam.constants.ManagerScopesEnum 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.common.auth.api.pojo.BkAuthGroup import com.tencent.devops.model.auth.tables.TAuthResourceAuthorization import com.tencent.devops.model.auth.tables.TAuthResourceGroupMember @@ -362,6 +363,59 @@ class AuthResourceGroupMemberDao { } } + fun listProjectMembersByComplexConditions( + dslContext: DSLContext, + projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO + ): List { + return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { + dslContext.select(MEMBER_ID, MEMBER_NAME, MEMBER_TYPE).from(this) + .where(buildProjectMembersByComplexConditions(projectMembersQueryConditionDTO)) + .groupBy(MEMBER_ID) + .orderBy(MEMBER_ID) + .fetch().map { + ResourceMemberInfo( + id = it.value1(), + name = it.value1(), + type = it.value3() + ) + } + } + } + + fun buildProjectMembersByComplexConditions( + projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO + ): MutableList { + val conditions = mutableListOf() + with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { + with(projectMembersQueryConditionDTO) { + conditions.add(PROJECT_CODE.eq(projectCode)) + if (queryTemplate == false) { + conditions.add(MEMBER_TYPE.notEqual(ManagerScopesEnum.getType(ManagerScopesEnum.TEMPLATE))) + } else { + conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.TEMPLATE))) + } + if (memberType != null) { + conditions.add(MEMBER_TYPE.eq(memberType)) + } + if (userName != null) { + conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.USER))) + conditions.add(MEMBER_ID.like("%$userName%").or(MEMBER_NAME.like("%$userName%"))) + } + if (deptName != null) { + conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.DEPARTMENT))) + conditions.add(MEMBER_NAME.like("%$deptName%")) + } + if (expiredTime != null) { + conditions.add(EXPIRED_TIME.le(expiredTime)) + } + if (!iamGroupIds.isNullOrEmpty()) { + conditions.add(IAM_GROUP_ID.`in`(iamGroupIds)) + } + } + } + return conditions + } + fun countProjectMember( dslContext: DSLContext, projectCode: String @@ -458,12 +512,12 @@ class AuthResourceGroupMemberDao { fun listGroupMember( dslContext: DSLContext, projectCode: String, - iamGroupId: Int + iamGroupIds: List ): List { return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { dslContext.selectFrom(this) .where(PROJECT_CODE.eq(projectCode)) - .and(IAM_GROUP_ID.eq(iamGroupId)) + .and(IAM_GROUP_ID.`in`(iamGroupIds)) .fetch().map { convert(it) } @@ -479,14 +533,16 @@ class AuthResourceGroupMemberDao { memberId: String, iamTemplateIds: List, resourceType: String? = null, - iamGroupIds: List? = null + iamGroupIds: List? = null, + expiredAt: LocalDateTime? = null ): Map { val conditions = buildMemberGroupCondition( projectCode = projectCode, memberId = memberId, iamTemplateIds = iamTemplateIds, resourceType = resourceType, - iamGroupIds = iamGroupIds + iamGroupIds = iamGroupIds, + expiredAt = expiredAt ) return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { val select = dslContext.select(RESOURCE_TYPE, count()) @@ -507,6 +563,7 @@ class AuthResourceGroupMemberDao { iamTemplateIds: List, resourceType: String? = null, iamGroupIds: List? = null, + expiredAt: LocalDateTime? = null, offset: Int? = null, limit: Int? = null ): List { @@ -515,7 +572,8 @@ class AuthResourceGroupMemberDao { memberId = memberId, iamTemplateIds = iamTemplateIds, resourceType = resourceType, - iamGroupIds = iamGroupIds + iamGroupIds = iamGroupIds, + expiredAt = expiredAt ) return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { dslContext.selectFrom(this) @@ -532,7 +590,8 @@ class AuthResourceGroupMemberDao { memberId: String, iamTemplateIds: List, resourceType: String? = null, - iamGroupIds: List? = null + iamGroupIds: List? = null, + expiredAt: LocalDateTime? = null ): MutableList { val conditions = mutableListOf() with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { @@ -552,7 +611,10 @@ class AuthResourceGroupMemberDao { ) ) resourceType?.let { conditions.add(RESOURCE_TYPE.eq(resourceType)) } - iamGroupIds?.let { conditions.add(IAM_GROUP_ID.`in`(iamGroupIds)) } + expiredAt?.let { conditions.add(EXPIRED_TIME.le(expiredAt)) } + if (!iamGroupIds.isNullOrEmpty()) { + conditions.add(IAM_GROUP_ID.`in`(iamGroupIds)) + } } return conditions } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt index ee46893139b..17f0d15a37b 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt @@ -17,6 +17,7 @@ import com.tencent.devops.auth.dao.AuthResourceGroupMemberDao import com.tencent.devops.auth.pojo.AuthResourceGroupMember import com.tencent.devops.auth.pojo.ResourceMemberInfo import com.tencent.devops.auth.pojo.dto.GroupMemberRenewalDTO +import com.tencent.devops.auth.pojo.dto.ProjectMembersQueryConditionDTO import com.tencent.devops.auth.pojo.enum.BatchOperateType import com.tencent.devops.auth.pojo.enum.JoinedType import com.tencent.devops.auth.pojo.enum.RemoveMemberButtonControl @@ -24,6 +25,7 @@ import com.tencent.devops.auth.pojo.request.GroupMemberCommonConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberHandoverConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberRenewalConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberSingleRenewalReq +import com.tencent.devops.auth.pojo.request.ProjectMembersQueryConditionReq import com.tencent.devops.auth.pojo.request.RemoveMemberFromProjectReq import com.tencent.devops.auth.pojo.vo.BatchOperateGroupMemberCheckVo import com.tencent.devops.auth.pojo.vo.GroupDetailsInfoVo @@ -180,52 +182,189 @@ class RbacPermissionResourceMemberService constructor( return SQLPage(count = count, records = records) } + return SQLPage(count = count, records = addDepartedFlagToMembers(records)) + } + + private fun addDepartedFlagToMembers(records: List): List { val userMembers = records.filter { it.type == ManagerScopesEnum.getType(ManagerScopesEnum.USER) }.map { it.id } - val departedMembers = if (userMembers.isNotEmpty()) { deptService.listDepartedMembers( memberIds = userMembers ) } else { - return SQLPage(count = count, records = records) + return records } - - val recordsWithDepartedFlag = records.map { + return records.map { if (it.type != ManagerScopesEnum.getType(ManagerScopesEnum.USER)) { it.copy(departed = false) } else { it.copy(departed = departedMembers.contains(it.id)) } } - return SQLPage(count = count, records = recordsWithDepartedFlag) + } + + override fun listProjectMembersByComplexConditions( + projectMembersQueryConditionReq: ProjectMembersQueryConditionReq + ): SQLPage { + logger.info("list project members by complex conditions:$projectMembersQueryConditionReq") + + with(projectMembersQueryConditionReq) { + if (!userName.isNullOrEmpty() && !deptName.isNullOrEmpty()) { + return SQLPage(count = 0, records = emptyList()) + } + val isComplexQuery = projectMembersQueryConditionReq.isComplexQuery() + // 简单查询 + if (!isComplexQuery) { + return listProjectMembers( + projectCode = projectCode, + memberType = memberType, + userName = userName, + deptName = deptName, + departedFlag = departedFlag, + page = page, + pageSize = pageSize + ) + } + } + + // 该方法后期可进行扩展,根据用户组名称,操作,资源类型,组策略查询出对应的组ID,传递用户组表进行查询。 + val iamGroupIdsByCondition = queryIamGroupIdsByConditions( + projectCode = projectMembersQueryConditionReq.projectCode, + groupName = projectMembersQueryConditionReq.groupName + ) + logger.info("list project members by complex conditions:$projectMembersQueryConditionReq") + val projectMembersQueryConditionDTO = ProjectMembersQueryConditionDTO.build( + projectMembersQueryConditionReq = projectMembersQueryConditionReq, + iamGroupIds = iamGroupIdsByCondition + ) + + // 获取用户直接加入组的记录 + val groupMembersFromDirect = authResourceGroupMemberDao.listProjectMembersByComplexConditions( + dslContext = dslContext, + projectMembersQueryConditionDTO = projectMembersQueryConditionDTO + ).toMutableList() + + // 获取通过模板加入组的记录 + val recordsWithTemplate = authResourceGroupMemberDao.listProjectMembersByComplexConditions( + dslContext = dslContext, + projectMembersQueryConditionDTO = projectMembersQueryConditionDTO.copy( + queryTemplate = true + ) + ) + // 获取模板下成员 + val groupMembersFromTemplate = listMembersFromTemplate( + projectCode = projectMembersQueryConditionDTO.projectCode, + iamTemplateIds = recordsWithTemplate.map { it.id.toInt() } + ) + + val allGroupMembers = groupMembersFromDirect.apply { + groupMembersFromDirect.addAll(groupMembersFromTemplate) + }.distinctBy { it.id } + .sortedWith(compareBy({ it.type }, { it.id })) + + // 内存中分页 + val limit = projectMembersQueryConditionDTO.offset + val offset = projectMembersQueryConditionDTO.limit + val startIndex = projectMembersQueryConditionDTO.offset.coerceAtLeast(0) + val endIndex = (limit + offset).coerceAtMost(allGroupMembers.size) + val finalGroupMembers = allGroupMembers.subList(startIndex, endIndex) + + // 不查询离职相关信息,防止调用用户管理接口,响应慢 + if (projectMembersQueryConditionDTO.departedFlag == false) { + return SQLPage( + count = allGroupMembers.size.toLong(), + records = finalGroupMembers + ) + } + return SQLPage( + count = allGroupMembers.size.toLong(), + records = addDepartedFlagToMembers(finalGroupMembers) + ) + } + + /** + * 该方法后期可进行扩展,根据用户组名称,操作,资源类型, + * 组策略查询出对应的组ID,传递用户组表进行查询。 + * */ + private fun queryIamGroupIdsByConditions( + projectCode: String, + groupName: String? = null, + iamGroupIds: List? = null + ): List { + val finalGroupIds = mutableListOf() + if (groupName != null) { + val iamGroupIdsByConditions = authResourceGroupDao.listIamGroupIdsByConditions( + dslContext = dslContext, + projectCode = projectCode, + groupName = groupName + ) + finalGroupIds.addAll(iamGroupIdsByConditions) + } + if (!iamGroupIds.isNullOrEmpty()) { + finalGroupIds.addAll(iamGroupIds) + } + return finalGroupIds + } + + // 获取模板下成员 + private fun listMembersFromTemplate( + projectCode: String, + iamTemplateIds: List + ): List { + val iamGroupIdsFromTemplate = authResourceGroupDao.listIamGroupIdsByConditions( + dslContext = dslContext, + projectCode = projectCode, + iamTemplateIds = iamTemplateIds + ) + // 获取模板下的成员 + return authResourceGroupMemberDao.listGroupMember( + dslContext = dslContext, + projectCode = projectCode, + iamGroupIds = iamGroupIdsFromTemplate + ).map { + ResourceMemberInfo( + id = it.memberId, + name = it.memberName, + type = it.memberType + ) + } } override fun getMemberGroupsCount( projectCode: String, - memberId: String + memberId: String, + groupName: String?, + expiredAt: Long? ): List { - // 1. 查询项目下包含该成员的组列表 + // 查询项目下包含该成员的组列表 val projectGroupIds = authResourceGroupMemberDao.listResourceGroupMember( dslContext = dslContext, projectCode = projectCode, resourceType = AuthResourceType.PROJECT.value, memberId = memberId ).map { it.iamGroupId.toString() } - // 2. 通过项目组ID获取人员模板ID + // 通过项目组ID获取人员模板ID val iamTemplateId = authResourceGroupDao.listByRelationId( dslContext = dslContext, projectCode = projectCode, iamGroupIds = projectGroupIds ).filter { it.iamTemplateId != null } .map { it.iamTemplateId.toString() } - // 3. 获取成员直接加入的组和通过模板加入的组 + // 根据条件进行筛选 + val iamGroupIdsByConditions = queryIamGroupIdsByConditions( + projectCode = projectCode, + groupName = groupName + ) + // 获取成员直接加入的组和通过模板加入的组 val memberGroupCountMap = authResourceGroupMemberDao.countMemberGroup( dslContext = dslContext, projectCode = projectCode, memberId = memberId, - iamTemplateIds = iamTemplateId + iamTemplateIds = iamTemplateId, + iamGroupIds = iamGroupIdsByConditions, + expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it) } ) val memberGroupCountList = mutableListOf() // 项目排在第一位 @@ -1292,15 +1431,24 @@ class RbacPermissionResourceMemberService constructor( memberId: String, resourceType: String?, iamGroupIds: List?, + groupName: String?, + expiredAt: Long?, start: Int?, limit: Int? ): SQLPage { + // 根据查询条件查询得到iam组id + val iamGroupIdsByConditions = queryIamGroupIdsByConditions( + projectCode = projectId, + groupName = groupName, + iamGroupIds = iamGroupIds + ) // 查询成员所在资源用户组列表,直接加入+通过用户组(模板)加入 val (count, resourceGroupMembers) = listResourceGroupMembers( projectCode = projectId, memberId = memberId, resourceType = resourceType, - iamGroupIds = iamGroupIds, + iamGroupIds = iamGroupIdsByConditions, + expiredAt = expiredAt, start = start, limit = limit ) @@ -1344,6 +1492,7 @@ class RbacPermissionResourceMemberService constructor( memberId: String, resourceType: String? = null, iamGroupIds: List? = null, + expiredAt: Long? = null, start: Int? = null, limit: Int? = null ): Pair> { @@ -1358,7 +1507,8 @@ class RbacPermissionResourceMemberService constructor( memberId = memberId, iamTemplateIds = iamTemplateIds, resourceType = resourceType, - iamGroupIds = iamGroupIds + iamGroupIds = iamGroupIds, + expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it) } )[resourceType] ?: 0L val resourceGroupMembers = authResourceGroupMemberDao.listMemberGroupDetail( dslContext = dslContext, @@ -1367,6 +1517,7 @@ class RbacPermissionResourceMemberService constructor( iamTemplateIds = iamTemplateIds, resourceType = resourceType, iamGroupIds = iamGroupIds, + expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it) }, offset = start, limit = limit ) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceMemberService.kt index e6f5eddc799..7eb289fe8be 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceMemberService.kt @@ -10,6 +10,7 @@ import com.tencent.devops.auth.pojo.request.GroupMemberCommonConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberHandoverConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberRenewalConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberSingleRenewalReq +import com.tencent.devops.auth.pojo.request.ProjectMembersQueryConditionReq import com.tencent.devops.auth.pojo.request.RemoveMemberFromProjectReq import com.tencent.devops.auth.pojo.vo.BatchOperateGroupMemberCheckVo import com.tencent.devops.auth.pojo.vo.GroupDetailsInfoVo @@ -173,9 +174,17 @@ class SamplePermissionResourceMemberService : PermissionResourceMemberService { return SQLPage(count = 0, records = emptyList()) } + override fun listProjectMembersByComplexConditions( + projectMembersQueryConditionReq: ProjectMembersQueryConditionReq + ): SQLPage { + return SQLPage(count = 0, records = emptyList()) + } + override fun getMemberGroupsCount( projectCode: String, - memberId: String + memberId: String, + groupName: String?, + expiredAt: Long? ): List { return emptyList() } @@ -185,6 +194,8 @@ class SamplePermissionResourceMemberService : PermissionResourceMemberService { memberId: String, resourceType: String?, iamGroupIds: List?, + groupName: String?, + expiredAt: Long?, start: Int?, limit: Int? ): SQLPage { diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceGroupResourceImpl.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceGroupResourceImpl.kt index 43ed6851abe..bdb3935d1d9 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceGroupResourceImpl.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceGroupResourceImpl.kt @@ -71,6 +71,8 @@ class UserAuthResourceGroupResourceImpl @Autowired constructor( projectId: String, resourceType: String, memberId: String, + groupName: String?, + expiredAt: Long?, start: Int, limit: Int ): Result> { @@ -79,6 +81,8 @@ class UserAuthResourceGroupResourceImpl @Autowired constructor( projectId = projectId, resourceType = resourceType, memberId = memberId, + groupName = groupName, + expiredAt = expiredAt, start = start, limit = limit ) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt index 47912b3d569..37e9e557a0e 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt @@ -7,6 +7,7 @@ import com.tencent.devops.auth.pojo.request.GroupMemberCommonConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberHandoverConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberRenewalConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberSingleRenewalReq +import com.tencent.devops.auth.pojo.request.ProjectMembersQueryConditionReq import com.tencent.devops.auth.pojo.request.RemoveMemberFromProjectReq import com.tencent.devops.auth.pojo.vo.BatchOperateGroupMemberCheckVo import com.tencent.devops.auth.pojo.vo.GroupDetailsInfoVo @@ -45,6 +46,19 @@ class UserAuthResourceMemberResourceImpl( ) } + @BkManagerCheck + override fun listProjectMembersByCondition( + userId: String, + projectId: String, + projectMembersQueryConditionReq: ProjectMembersQueryConditionReq + ): Result> { + return Result( + permissionResourceMemberService.listProjectMembersByComplexConditions( + projectMembersQueryConditionReq = projectMembersQueryConditionReq + ) + ) + } + @BkManagerCheck override fun renewalGroupMember( userId: String, @@ -156,12 +170,16 @@ class UserAuthResourceMemberResourceImpl( override fun getMemberGroupCount( userId: String, projectId: String, - memberId: String + memberId: String, + groupName: String?, + expiredAt: Long? ): Result> { return Result( permissionResourceMemberService.getMemberGroupsCount( projectCode = projectId, - memberId = memberId + memberId = memberId, + groupName = groupName, + expiredAt = expiredAt ) ) } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt index e0f01355221..f2904f4f8d4 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt @@ -8,6 +8,7 @@ import com.tencent.devops.auth.pojo.request.GroupMemberCommonConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberHandoverConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberRenewalConditionReq import com.tencent.devops.auth.pojo.request.GroupMemberSingleRenewalReq +import com.tencent.devops.auth.pojo.request.ProjectMembersQueryConditionReq import com.tencent.devops.auth.pojo.request.RemoveMemberFromProjectReq import com.tencent.devops.auth.pojo.vo.BatchOperateGroupMemberCheckVo import com.tencent.devops.auth.pojo.vo.GroupDetailsInfoVo @@ -34,6 +35,11 @@ interface PermissionResourceMemberService { fun getProjectMemberCount(projectCode: String): ResourceMemberCountVO + /** + * 之所以将简单查询接口抽成单独方法,是因为该方法只用于查询用户名称/部门名称等, + 一方面,该方法职责比较单一;另一方面,该接口需要连表查询到授权资源表中授权人。 + 复杂查询虽然需要查询各种权限,但是不需要关联授权资源表。 + * */ fun listProjectMembers( projectCode: String, memberType: String?, @@ -44,21 +50,33 @@ interface PermissionResourceMemberService { pageSize: Int ): SQLPage + /** + * 根据复杂条件进行搜索,用于用户管理界面 + * */ + fun listProjectMembersByComplexConditions( + projectMembersQueryConditionReq: ProjectMembersQueryConditionReq + ): SQLPage + /** * 获取用户有权限的用户组数量 * */ fun getMemberGroupsCount( projectCode: String, - memberId: String + memberId: String, + groupName: String?, + expiredAt: Long? ): List - // 查询成员所在资源用户组详情,直接加入+通过用户组(模板)加入 - @Suppress("LongParameterList") + /** + * 查询成员所在资源用户组详情,直接加入+通过用户组(模板)加入 + * */ fun getMemberGroupsDetails( projectId: String, memberId: String, resourceType: String?, iamGroupIds: List? = null, + groupName: String? = null, + expiredAt: Long? = null, start: Int?, limit: Int? ): SQLPage From 28ff8f2e76dfc4b8ba42c0dab3e339a93fe7d7a0 Mon Sep 17 00:00:00 2001 From: greysonfang Date: Tue, 3 Sep 2024 12:20:00 +0800 Subject: [PATCH 02/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt | 2 +- .../kotlin/com/tencent/devops/common/api/util/DateTimeUtil.kt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt index 614bb52c8c2..1f3714fe50c 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt @@ -37,7 +37,7 @@ data class ProjectMembersQueryConditionDTO( iamGroupIds: List? ): ProjectMembersQueryConditionDTO { return with(projectMembersQueryConditionReq) { - val expiredTime = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it) } + val expiredTime = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } val limit = PageUtil.convertPageSizeToSQLLimit(page, pageSize) ProjectMembersQueryConditionDTO( projectCode = projectCode, diff --git a/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/util/DateTimeUtil.kt b/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/util/DateTimeUtil.kt index 53876182365..0159909c2cc 100644 --- a/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/util/DateTimeUtil.kt +++ b/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/util/DateTimeUtil.kt @@ -137,6 +137,9 @@ object DateTimeUtil { return localDateTime?.toEpochSecond(ZoneOffset.ofHours(8)) ?: 0L } + /* + * 用于转化秒级时间戳,非毫秒级 + * */ fun convertTimestampToLocalDateTime(timestamp: Long): LocalDateTime { return LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault()) } From 3fa84f9298187f7bf1212742732cd327d9c7162c Mon Sep 17 00:00:00 2001 From: greysonfang Date: Tue, 3 Sep 2024 12:21:19 +0800 Subject: [PATCH 03/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RbacPermissionResourceMemberService.kt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt index 17f0d15a37b..7311751542d 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt @@ -253,11 +253,16 @@ class RbacPermissionResourceMemberService constructor( queryTemplate = true ) ) + // 获取模板下成员 - val groupMembersFromTemplate = listMembersFromTemplate( - projectCode = projectMembersQueryConditionDTO.projectCode, - iamTemplateIds = recordsWithTemplate.map { it.id.toInt() } - ) + val groupMembersFromTemplate = if (recordsWithTemplate.isNotEmpty()) { + listMembersFromTemplate( + projectCode = projectMembersQueryConditionDTO.projectCode, + iamTemplateIds = recordsWithTemplate.map { it.id.toInt() } + ) + } else { + emptyList() + } val allGroupMembers = groupMembersFromDirect.apply { groupMembersFromDirect.addAll(groupMembersFromTemplate) @@ -364,7 +369,7 @@ class RbacPermissionResourceMemberService constructor( memberId = memberId, iamTemplateIds = iamTemplateId, iamGroupIds = iamGroupIdsByConditions, - expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it) } + expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } ) val memberGroupCountList = mutableListOf() // 项目排在第一位 @@ -1508,7 +1513,7 @@ class RbacPermissionResourceMemberService constructor( iamTemplateIds = iamTemplateIds, resourceType = resourceType, iamGroupIds = iamGroupIds, - expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it) } + expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } )[resourceType] ?: 0L val resourceGroupMembers = authResourceGroupMemberDao.listMemberGroupDetail( dslContext = dslContext, @@ -1517,7 +1522,7 @@ class RbacPermissionResourceMemberService constructor( iamTemplateIds = iamTemplateIds, resourceType = resourceType, iamGroupIds = iamGroupIds, - expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it) }, + expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) }, offset = start, limit = limit ) From 54b13ad4ae5ae370c0cc93da79ec707809c69497 Mon Sep 17 00:00:00 2001 From: greysonfang Date: Tue, 3 Sep 2024 14:33:42 +0800 Subject: [PATCH 04/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/auth/dao/AuthResourceGroupMemberDao.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 cb530cb2570..893f32ef809 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 @@ -375,7 +375,7 @@ class AuthResourceGroupMemberDao { .fetch().map { ResourceMemberInfo( id = it.value1(), - name = it.value1(), + name = it.value2(), type = it.value3() ) } From f0fe814caf9583e6d681fd3bcc51e9b61471c3b8 Mon Sep 17 00:00:00 2001 From: greysonfang Date: Tue, 3 Sep 2024 15:06:44 +0800 Subject: [PATCH 05/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/auth/cron/AuthCronSyncGroupAndMember.kt | 5 ++++- .../rbac/service/RbacPermissionResourceGroupSyncService.kt | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronSyncGroupAndMember.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronSyncGroupAndMember.kt index 774607c5e2b..aca24708f79 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronSyncGroupAndMember.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronSyncGroupAndMember.kt @@ -45,7 +45,10 @@ class AuthCronSyncGroupAndMember( } } - @Scheduled(cron = "0 0 8,16 * * ?") + /** + * 一小时,同步一次用户申请加入组的单据,若连续两个月未审批单据,将不再进行扫描 + * */ + @Scheduled(initialDelay = 10000, fixedRate = 3600000) fun syncIamGroupMembersOfApplyRegularly() { if (!enable) { return 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 6a2a651e8ee..2be996b9242 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 @@ -80,7 +80,7 @@ class RbacPermissionResourceGroupSyncService @Autowired constructor( private val syncExecutorService = Executors.newFixedThreadPool(5) private val syncProjectsExecutorService = Executors.newFixedThreadPool(10) private val syncResourceMemberExecutorService = Executors.newFixedThreadPool(50) - private const val MAX_NUMBER_OF_CHECKS = 120 + private const val MAX_NUMBER_OF_CHECKS = 1440 } override fun syncByCondition(projectConditionDTO: ProjectConditionDTO) { @@ -186,6 +186,7 @@ class RbacPermissionResourceGroupSyncService @Autowired constructor( limit = limit, offset = offset ) + // 检查60天内的申请的单据 val recordIdsOfTimeOut = records.filter { it.numberOfChecks >= MAX_NUMBER_OF_CHECKS }.map { it.id } val (recordsOfSuccess, recordsOfPending) = records.filterNot { recordIdsOfTimeOut.contains(it.id) From 884ce222cf6a3ae2157df49b2ed19949f669e6da Mon Sep 17 00:00:00 2001 From: greysonfang Date: Wed, 4 Sep 2024 17:19:31 +0800 Subject: [PATCH 06/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserAuthResourceGroupResource.kt | 9 ++++--- .../user/UserAuthResourceMemberResource.kt | 10 +++++--- .../dto/ProjectMembersQueryConditionDTO.kt | 12 ++++++--- .../ProjectMembersQueryConditionReq.kt | 8 +++--- .../auth/dao/AuthResourceGroupMemberDao.kt | 25 +++++++++++++------ .../RbacPermissionResourceMemberService.kt | 23 +++++++++++------ .../SamplePermissionResourceMemberService.kt | 6 +++-- .../UserAuthResourceGroupResourceImpl.kt | 6 +++-- .../UserAuthResourceMemberResourceImpl.kt | 6 +++-- .../iam/PermissionResourceMemberService.kt | 6 +++-- 10 files changed, 75 insertions(+), 36 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt index 158da1ba0ca..e403ce5b338 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt @@ -95,9 +95,12 @@ interface UserAuthResourceGroupResource { @QueryParam("groupName") @Parameter(description = "用户组名称") groupName: String?, - @QueryParam("expiredAt") - @Parameter(description = "过期时间戳-毫秒级") - expiredAt: Long?, + @QueryParam("minExpiredAt") + @Parameter(description = "最小过期时间") + minExpiredAt: Long?, + @QueryParam("maxExpiredAt") + @Parameter(description = "最大过期时间") + maxExpiredAt: Long?, @Parameter(description = "起始位置,从0开始") @QueryParam("start") start: Int, diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceMemberResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceMemberResource.kt index 7959ddcb5ce..868f0d39d37 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceMemberResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceMemberResource.kt @@ -33,6 +33,7 @@ import javax.ws.rs.core.MediaType @Path("/user/auth/resource/member/{projectId}/") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) +@Suppress("LongParameterList") interface UserAuthResourceMemberResource { @GET @Path("/listProjectMembers") @@ -196,8 +197,11 @@ interface UserAuthResourceMemberResource { @QueryParam("groupName") @Parameter(description = "用户组名称") groupName: String?, - @QueryParam("expiredAt") - @Parameter(description = "过期时间") - expiredAt: Long? + @QueryParam("minExpiredAt") + @Parameter(description = "最小过期时间") + minExpiredAt: Long?, + @QueryParam("maxExpiredAt") + @Parameter(description = "最大过期时间") + maxExpiredAt: Long? ): Result> } diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt index 1f3714fe50c..32d8cdaca63 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt @@ -20,8 +20,10 @@ data class ProjectMembersQueryConditionDTO( val groupName: String?, @get:Schema(title = "用户组Id") val iamGroupIds: List?, - @get:Schema(title = "过期时间") - val expiredTime: LocalDateTime?, + @get:Schema(title = "最小过期时间") + val minExpiredTime: LocalDateTime?, + @get:Schema(title = "最大过期时间") + val maxExpiredTime: LocalDateTime?, @get:Schema(title = "离职标识") val departedFlag: Boolean? = false, @get:Schema(title = "是否查询模板") @@ -37,7 +39,8 @@ data class ProjectMembersQueryConditionDTO( iamGroupIds: List? ): ProjectMembersQueryConditionDTO { return with(projectMembersQueryConditionReq) { - val expiredTime = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } + val minExpiredTime = minExpiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } + val maxExpiredTime = maxExpiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } val limit = PageUtil.convertPageSizeToSQLLimit(page, pageSize) ProjectMembersQueryConditionDTO( projectCode = projectCode, @@ -46,7 +49,8 @@ data class ProjectMembersQueryConditionDTO( deptName = deptName, groupName = groupName, iamGroupIds = iamGroupIds, - expiredTime = expiredTime, + minExpiredTime = minExpiredTime, + maxExpiredTime = maxExpiredTime, departedFlag = departedFlag, limit = limit.limit, offset = limit.offset diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt index d07efb9ae8a..1343fb28ece 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt @@ -14,8 +14,10 @@ data class ProjectMembersQueryConditionReq( val deptName: String?, @get:Schema(title = "用户组名称") val groupName: String?, - @get:Schema(title = "过期时间") - val expiredAt: Long?, + @get:Schema(title = "最小过期时间") + val minExpiredAt: Long?, + @get:Schema(title = "最大过期时间") + val maxExpiredAt: Long?, @get:Schema(title = "离职标识") val departedFlag: Boolean? = false, @get:Schema(title = "第几页") @@ -25,6 +27,6 @@ data class ProjectMembersQueryConditionReq( ) { // 当查询到权限相关信息时,如组名称,过期时间,操作,资源类型时,走复杂查询逻辑 fun isComplexQuery(): Boolean { - return groupName != null || expiredAt != null + return groupName != null || minExpiredAt != null || maxExpiredAt != null } } 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 893f32ef809..7038b9440a7 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 @@ -405,8 +405,11 @@ class AuthResourceGroupMemberDao { conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.DEPARTMENT))) conditions.add(MEMBER_NAME.like("%$deptName%")) } - if (expiredTime != null) { - conditions.add(EXPIRED_TIME.le(expiredTime)) + if (minExpiredTime != null) { + conditions.add(EXPIRED_TIME.ge(minExpiredTime)) + } + if (maxExpiredTime != null) { + conditions.add(EXPIRED_TIME.le(maxExpiredTime)) } if (!iamGroupIds.isNullOrEmpty()) { conditions.add(IAM_GROUP_ID.`in`(iamGroupIds)) @@ -534,7 +537,8 @@ class AuthResourceGroupMemberDao { iamTemplateIds: List, resourceType: String? = null, iamGroupIds: List? = null, - expiredAt: LocalDateTime? = null + minExpiredAt: LocalDateTime? = null, + maxExpiredAt: LocalDateTime? = null ): Map { val conditions = buildMemberGroupCondition( projectCode = projectCode, @@ -542,7 +546,8 @@ class AuthResourceGroupMemberDao { iamTemplateIds = iamTemplateIds, resourceType = resourceType, iamGroupIds = iamGroupIds, - expiredAt = expiredAt + minExpiredAt = minExpiredAt, + maxExpiredAt = maxExpiredAt ) return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { val select = dslContext.select(RESOURCE_TYPE, count()) @@ -563,7 +568,8 @@ class AuthResourceGroupMemberDao { iamTemplateIds: List, resourceType: String? = null, iamGroupIds: List? = null, - expiredAt: LocalDateTime? = null, + minExpiredAt: LocalDateTime? = null, + maxExpiredAt: LocalDateTime? = null, offset: Int? = null, limit: Int? = null ): List { @@ -573,7 +579,8 @@ class AuthResourceGroupMemberDao { iamTemplateIds = iamTemplateIds, resourceType = resourceType, iamGroupIds = iamGroupIds, - expiredAt = expiredAt + minExpiredAt = minExpiredAt, + maxExpiredAt = maxExpiredAt ) return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { dslContext.selectFrom(this) @@ -591,7 +598,8 @@ class AuthResourceGroupMemberDao { iamTemplateIds: List, resourceType: String? = null, iamGroupIds: List? = null, - expiredAt: LocalDateTime? = null + minExpiredAt: LocalDateTime? = null, + maxExpiredAt: LocalDateTime? = null ): MutableList { val conditions = mutableListOf() with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { @@ -611,7 +619,8 @@ class AuthResourceGroupMemberDao { ) ) resourceType?.let { conditions.add(RESOURCE_TYPE.eq(resourceType)) } - expiredAt?.let { conditions.add(EXPIRED_TIME.le(expiredAt)) } + minExpiredAt?.let { conditions.add(EXPIRED_TIME.ge(minExpiredAt)) } + maxExpiredAt?.let { conditions.add(EXPIRED_TIME.le(maxExpiredAt)) } if (!iamGroupIds.isNullOrEmpty()) { conditions.add(IAM_GROUP_ID.`in`(iamGroupIds)) } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt index 7311751542d..e814c44d993 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt @@ -341,7 +341,8 @@ class RbacPermissionResourceMemberService constructor( projectCode: String, memberId: String, groupName: String?, - expiredAt: Long? + minExpiredAt: Long?, + maxExpiredAt: Long? ): List { // 查询项目下包含该成员的组列表 val projectGroupIds = authResourceGroupMemberDao.listResourceGroupMember( @@ -369,7 +370,8 @@ class RbacPermissionResourceMemberService constructor( memberId = memberId, iamTemplateIds = iamTemplateId, iamGroupIds = iamGroupIdsByConditions, - expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } + minExpiredAt = minExpiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) }, + maxExpiredAt = maxExpiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } ) val memberGroupCountList = mutableListOf() // 项目排在第一位 @@ -1437,7 +1439,8 @@ class RbacPermissionResourceMemberService constructor( resourceType: String?, iamGroupIds: List?, groupName: String?, - expiredAt: Long?, + minExpiredAt: Long?, + maxExpiredAt: Long?, start: Int?, limit: Int? ): SQLPage { @@ -1453,7 +1456,8 @@ class RbacPermissionResourceMemberService constructor( memberId = memberId, resourceType = resourceType, iamGroupIds = iamGroupIdsByConditions, - expiredAt = expiredAt, + minExpiredAt = minExpiredAt, + maxExpiredAt = maxExpiredAt, start = start, limit = limit ) @@ -1497,7 +1501,8 @@ class RbacPermissionResourceMemberService constructor( memberId: String, resourceType: String? = null, iamGroupIds: List? = null, - expiredAt: Long? = null, + minExpiredAt: Long? = null, + maxExpiredAt: Long? = null, start: Int? = null, limit: Int? = null ): Pair> { @@ -1506,6 +1511,8 @@ class RbacPermissionResourceMemberService constructor( projectCode = projectCode, memberId = memberId ) + val minExpiredTime = minExpiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } + val maxExpiredTime = maxExpiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } val count = authResourceGroupMemberDao.countMemberGroup( dslContext = dslContext, projectCode = projectCode, @@ -1513,7 +1520,8 @@ class RbacPermissionResourceMemberService constructor( iamTemplateIds = iamTemplateIds, resourceType = resourceType, iamGroupIds = iamGroupIds, - expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) } + minExpiredAt = minExpiredTime, + maxExpiredAt = maxExpiredTime )[resourceType] ?: 0L val resourceGroupMembers = authResourceGroupMemberDao.listMemberGroupDetail( dslContext = dslContext, @@ -1522,7 +1530,8 @@ class RbacPermissionResourceMemberService constructor( iamTemplateIds = iamTemplateIds, resourceType = resourceType, iamGroupIds = iamGroupIds, - expiredAt = expiredAt?.let { DateTimeUtil.convertTimestampToLocalDateTime(it / 1000) }, + minExpiredAt = minExpiredTime, + maxExpiredAt = maxExpiredTime, offset = start, limit = limit ) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceMemberService.kt index 7eb289fe8be..6c3456ee138 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceMemberService.kt @@ -184,7 +184,8 @@ class SamplePermissionResourceMemberService : PermissionResourceMemberService { projectCode: String, memberId: String, groupName: String?, - expiredAt: Long? + minExpiredAt: Long?, + maxExpiredAt: Long? ): List { return emptyList() } @@ -195,7 +196,8 @@ class SamplePermissionResourceMemberService : PermissionResourceMemberService { resourceType: String?, iamGroupIds: List?, groupName: String?, - expiredAt: Long?, + minExpiredAt: Long?, + maxExpiredAt: Long?, start: Int?, limit: Int? ): SQLPage { diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceGroupResourceImpl.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceGroupResourceImpl.kt index bdb3935d1d9..6861454c155 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceGroupResourceImpl.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceGroupResourceImpl.kt @@ -72,7 +72,8 @@ class UserAuthResourceGroupResourceImpl @Autowired constructor( resourceType: String, memberId: String, groupName: String?, - expiredAt: Long?, + minExpiredAt: Long?, + maxExpiredAt: Long?, start: Int, limit: Int ): Result> { @@ -82,7 +83,8 @@ class UserAuthResourceGroupResourceImpl @Autowired constructor( resourceType = resourceType, memberId = memberId, groupName = groupName, - expiredAt = expiredAt, + minExpiredAt = minExpiredAt, + maxExpiredAt = maxExpiredAt, start = start, limit = limit ) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt index 37e9e557a0e..55dcb30a286 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt @@ -172,14 +172,16 @@ class UserAuthResourceMemberResourceImpl( projectId: String, memberId: String, groupName: String?, - expiredAt: Long? + minExpiredAt: Long?, + maxExpiredAt: Long? ): Result> { return Result( permissionResourceMemberService.getMemberGroupsCount( projectCode = projectId, memberId = memberId, groupName = groupName, - expiredAt = expiredAt + minExpiredAt = minExpiredAt, + maxExpiredAt = maxExpiredAt ) ) } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt index f2904f4f8d4..fee7e7bcdee 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt @@ -64,7 +64,8 @@ interface PermissionResourceMemberService { projectCode: String, memberId: String, groupName: String?, - expiredAt: Long? + minExpiredAt: Long?, + maxExpiredAt: Long? ): List /** @@ -76,7 +77,8 @@ interface PermissionResourceMemberService { resourceType: String?, iamGroupIds: List? = null, groupName: String? = null, - expiredAt: Long? = null, + minExpiredAt: Long? = null, + maxExpiredAt: Long? = null, start: Int?, limit: Int? ): SQLPage From b9424793756127d0bd991a6d96d11e192eadc0fc Mon Sep 17 00:00:00 2001 From: greysonfang Date: Thu, 5 Sep 2024 20:45:01 +0800 Subject: [PATCH 07/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/dao/AuthResourceGroupMemberDao.kt | 56 +++++--- .../RbacPermissionResourceMemberService.kt | 136 ++++++++++-------- .../UserAuthResourceMemberResourceImpl.kt | 2 +- .../iam/PermissionResourceMemberService.kt | 2 +- 4 files changed, 115 insertions(+), 81 deletions(-) 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 7038b9440a7..09519c73028 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 @@ -390,28 +390,34 @@ class AuthResourceGroupMemberDao { with(projectMembersQueryConditionDTO) { conditions.add(PROJECT_CODE.eq(projectCode)) if (queryTemplate == false) { + // 非查询模板时的条件 conditions.add(MEMBER_TYPE.notEqual(ManagerScopesEnum.getType(ManagerScopesEnum.TEMPLATE))) + memberType?.let { type -> conditions.add(MEMBER_TYPE.eq(type)) } + userName?.let { name -> + conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.USER))) + conditions.add(MEMBER_ID.like("%$name%").or(MEMBER_NAME.like("%$name%"))) + } + deptName?.let { name -> + conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.DEPARTMENT))) + conditions.add(MEMBER_NAME.like("%$name%")) + } } else { + // 查询模板时的条件 conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.TEMPLATE))) } - if (memberType != null) { - conditions.add(MEMBER_TYPE.eq(memberType)) - } - if (userName != null) { - conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.USER))) - conditions.add(MEMBER_ID.like("%$userName%").or(MEMBER_NAME.like("%$userName%"))) - } - if (deptName != null) { - conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.DEPARTMENT))) - conditions.add(MEMBER_NAME.like("%$deptName%")) - } - if (minExpiredTime != null) { - conditions.add(EXPIRED_TIME.ge(minExpiredTime)) + + minExpiredTime?.let { minTime -> + // 添加最小过期时间条件 + conditions.add(EXPIRED_TIME.ge(minTime)) } - if (maxExpiredTime != null) { - conditions.add(EXPIRED_TIME.le(maxExpiredTime)) + + maxExpiredTime?.let { maxTime -> + // 添加最大过期时间条件 + conditions.add(EXPIRED_TIME.le(maxTime)) } + if (!iamGroupIds.isNullOrEmpty()) { + // 添加IAM组ID条件 conditions.add(IAM_GROUP_ID.`in`(iamGroupIds)) } } @@ -515,12 +521,26 @@ class AuthResourceGroupMemberDao { fun listGroupMember( dslContext: DSLContext, projectCode: String, - iamGroupIds: List + iamGroupIds: List, + memberType: String? = null, + userName: String? = null, + deptName: String? = null ): List { return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { + val conditions = mutableListOf() + conditions.add(PROJECT_CODE.eq(projectCode)) + conditions.add(IAM_GROUP_ID.`in`(iamGroupIds)) + memberType?.let { type -> conditions.add(MEMBER_TYPE.eq(type)) } + userName?.let { name -> + conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.USER))) + conditions.add(MEMBER_ID.like("%$name%").or(MEMBER_NAME.like("%$name%"))) + } + deptName?.let { name -> + conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.DEPARTMENT))) + conditions.add(MEMBER_NAME.like("%$name%")) + } dslContext.selectFrom(this) - .where(PROJECT_CODE.eq(projectCode)) - .and(IAM_GROUP_ID.`in`(iamGroupIds)) + .where(conditions) .fetch().map { convert(it) } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt index e814c44d993..ecb16118dd3 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt @@ -206,87 +206,97 @@ class RbacPermissionResourceMemberService constructor( } override fun listProjectMembersByComplexConditions( - projectMembersQueryConditionReq: ProjectMembersQueryConditionReq + conditionReq: ProjectMembersQueryConditionReq ): SQLPage { - logger.info("list project members by complex conditions:$projectMembersQueryConditionReq") + logger.info("list project members by complex conditions: $conditionReq") - with(projectMembersQueryConditionReq) { - if (!userName.isNullOrEmpty() && !deptName.isNullOrEmpty()) { - return SQLPage(count = 0, records = emptyList()) - } - val isComplexQuery = projectMembersQueryConditionReq.isComplexQuery() - // 简单查询 - if (!isComplexQuery) { - return listProjectMembers( - projectCode = projectCode, - memberType = memberType, - userName = userName, - deptName = deptName, - departedFlag = departedFlag, - page = page, - pageSize = pageSize - ) - } + // 不允许同时查询部门名称和用户名称 + if (conditionReq.userName != null && conditionReq.deptName != null) { + return SQLPage(count = 0, records = emptyList()) + } + + // 简单查询直接返回结果 + if (!conditionReq.isComplexQuery()) { + return listProjectMembers( + projectCode = conditionReq.projectCode, + memberType = conditionReq.memberType, + userName = conditionReq.userName, + deptName = conditionReq.deptName, + departedFlag = conditionReq.departedFlag, + page = conditionReq.page, + pageSize = conditionReq.pageSize + ) } - // 该方法后期可进行扩展,根据用户组名称,操作,资源类型,组策略查询出对应的组ID,传递用户组表进行查询。 - val iamGroupIdsByCondition = queryIamGroupIdsByConditions( - projectCode = projectMembersQueryConditionReq.projectCode, - groupName = projectMembersQueryConditionReq.groupName + // 处理复杂查询条件 + val iamGroupIdsByCondition = if (conditionReq.groupName != null) { + queryIamGroupIdsByConditions( + projectCode = conditionReq.projectCode, + groupName = conditionReq.groupName + ).takeIf { it.isNotEmpty() } ?: return SQLPage(0, emptyList()) + } else { + emptyList() + } + + val conditionDTO = ProjectMembersQueryConditionDTO.build( + conditionReq, iamGroupIdsByCondition ) - logger.info("list project members by complex conditions:$projectMembersQueryConditionReq") - val projectMembersQueryConditionDTO = ProjectMembersQueryConditionDTO.build( - projectMembersQueryConditionReq = projectMembersQueryConditionReq, - iamGroupIds = iamGroupIdsByCondition + + // 获取用户直接加入组的记录和通过模板加入组的记录 + val (groupMembersFromDirect, groupMembersFromTemplate) = getGroupMembers( + projectMembersQueryConditionDTO = conditionDTO + ) + + // 合并并去重 + val allGroupMembers = (groupMembersFromDirect + groupMembersFromTemplate) + .distinctBy { it.id }.sortedWith(compareBy({ it.type }, { it.id })) + + // 内存分页 + val (count, records) = paginateResults( + allGroupMembers = allGroupMembers, + projectMembersQueryConditionDTO = conditionDTO ) - // 获取用户直接加入组的记录 + // 添加离职标志 + return if (conditionDTO.departedFlag == false) { + SQLPage(count, records) + } else { + SQLPage(count, addDepartedFlagToMembers(records)) + } + } + + private fun getGroupMembers( + projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO + ): Pair, List> { val groupMembersFromDirect = authResourceGroupMemberDao.listProjectMembersByComplexConditions( dslContext = dslContext, - projectMembersQueryConditionDTO = projectMembersQueryConditionDTO + projectMembersQueryConditionDTO = projectMembersQueryConditionDTO.copy(queryTemplate = false) ).toMutableList() - - // 获取通过模板加入组的记录 val recordsWithTemplate = authResourceGroupMemberDao.listProjectMembersByComplexConditions( dslContext = dslContext, - projectMembersQueryConditionDTO = projectMembersQueryConditionDTO.copy( - queryTemplate = true - ) + projectMembersQueryConditionDTO = projectMembersQueryConditionDTO.copy(queryTemplate = true) ) - - // 获取模板下成员 val groupMembersFromTemplate = if (recordsWithTemplate.isNotEmpty()) { listMembersFromTemplate( projectCode = projectMembersQueryConditionDTO.projectCode, - iamTemplateIds = recordsWithTemplate.map { it.id.toInt() } + iamTemplateIds = recordsWithTemplate.map { it.id.toInt() }, + projectMembersQueryConditionDTO = projectMembersQueryConditionDTO ) } else { emptyList() } + return Pair(groupMembersFromDirect, groupMembersFromTemplate) + } - val allGroupMembers = groupMembersFromDirect.apply { - groupMembersFromDirect.addAll(groupMembersFromTemplate) - }.distinctBy { it.id } - .sortedWith(compareBy({ it.type }, { it.id })) - - // 内存中分页 - val limit = projectMembersQueryConditionDTO.offset - val offset = projectMembersQueryConditionDTO.limit - val startIndex = projectMembersQueryConditionDTO.offset.coerceAtLeast(0) + private fun paginateResults( + allGroupMembers: List, + projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO + ): Pair> { + val limit = projectMembersQueryConditionDTO.limit + val offset = projectMembersQueryConditionDTO.offset + val startIndex = offset.coerceAtLeast(0) val endIndex = (limit + offset).coerceAtMost(allGroupMembers.size) - val finalGroupMembers = allGroupMembers.subList(startIndex, endIndex) - - // 不查询离职相关信息,防止调用用户管理接口,响应慢 - if (projectMembersQueryConditionDTO.departedFlag == false) { - return SQLPage( - count = allGroupMembers.size.toLong(), - records = finalGroupMembers - ) - } - return SQLPage( - count = allGroupMembers.size.toLong(), - records = addDepartedFlagToMembers(finalGroupMembers) - ) + return Pair(allGroupMembers.size.toLong(), allGroupMembers.subList(startIndex, endIndex)) } /** @@ -316,7 +326,8 @@ class RbacPermissionResourceMemberService constructor( // 获取模板下成员 private fun listMembersFromTemplate( projectCode: String, - iamTemplateIds: List + iamTemplateIds: List, + projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO ): List { val iamGroupIdsFromTemplate = authResourceGroupDao.listIamGroupIdsByConditions( dslContext = dslContext, @@ -327,7 +338,10 @@ class RbacPermissionResourceMemberService constructor( return authResourceGroupMemberDao.listGroupMember( dslContext = dslContext, projectCode = projectCode, - iamGroupIds = iamGroupIdsFromTemplate + iamGroupIds = iamGroupIdsFromTemplate, + memberType = projectMembersQueryConditionDTO.memberType, + userName = projectMembersQueryConditionDTO.userName, + deptName = projectMembersQueryConditionDTO.deptName ).map { ResourceMemberInfo( id = it.memberId, diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt index 55dcb30a286..55b12392dfe 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/UserAuthResourceMemberResourceImpl.kt @@ -54,7 +54,7 @@ class UserAuthResourceMemberResourceImpl( ): Result> { return Result( permissionResourceMemberService.listProjectMembersByComplexConditions( - projectMembersQueryConditionReq = projectMembersQueryConditionReq + conditionReq = projectMembersQueryConditionReq ) ) } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt index fee7e7bcdee..44dc1004ca0 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt @@ -54,7 +54,7 @@ interface PermissionResourceMemberService { * 根据复杂条件进行搜索,用于用户管理界面 * */ fun listProjectMembersByComplexConditions( - projectMembersQueryConditionReq: ProjectMembersQueryConditionReq + conditionReq: ProjectMembersQueryConditionReq ): SQLPage /** From 8ad21c037b5318f37ee09c34def15d05e92ebf3b Mon Sep 17 00:00:00 2001 From: greysonfang Date: Fri, 6 Sep 2024 10:27:40 +0800 Subject: [PATCH 08/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rbac/service/RbacPermissionResourceMemberService.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt index ecb16118dd3..c080e065cc7 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt @@ -372,7 +372,8 @@ class RbacPermissionResourceMemberService constructor( iamGroupIds = projectGroupIds ).filter { it.iamTemplateId != null } .map { it.iamTemplateId.toString() } - // 根据条件进行筛选 + + // 后续改造,根据操作/资源类型/资源实例进行筛选,只需要扩展该方法即可 val iamGroupIdsByConditions = queryIamGroupIdsByConditions( projectCode = projectCode, groupName = groupName @@ -1458,6 +1459,7 @@ class RbacPermissionResourceMemberService constructor( start: Int?, limit: Int? ): SQLPage { + // 后续改造,根据操作/资源类型/资源实例进行筛选,只需要扩展该方法即可 // 根据查询条件查询得到iam组id val iamGroupIdsByConditions = queryIamGroupIdsByConditions( projectCode = projectId, From fb76da8908353e67dd159d449c7b59516206417e Mon Sep 17 00:00:00 2001 From: greysonfang Date: Fri, 6 Sep 2024 17:23:35 +0800 Subject: [PATCH 09/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/ProjectMembersQueryConditionDTO.kt | 18 +-- .../devops/auth/dao/AuthResourceGroupDao.kt | 6 +- .../auth/dao/AuthResourceGroupMemberDao.kt | 86 ++++++-------- .../RbacPermissionResourceMemberService.kt | 105 +++++------------- 4 files changed, 73 insertions(+), 142 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt index 32d8cdaca63..8034e532bab 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/dto/ProjectMembersQueryConditionDTO.kt @@ -11,27 +11,27 @@ data class ProjectMembersQueryConditionDTO( @get:Schema(title = "项目ID") val projectCode: String, @get:Schema(title = "成员类型") - val memberType: String?, + val memberType: String? = null, @get:Schema(title = "用户名称") - val userName: String?, + val userName: String? = null, @get:Schema(title = "部门名称") - val deptName: String?, + val deptName: String? = null, @get:Schema(title = "用户组名称") - val groupName: String?, + val groupName: String? = null, @get:Schema(title = "用户组Id") - val iamGroupIds: List?, + val iamGroupIds: List? = null, @get:Schema(title = "最小过期时间") - val minExpiredTime: LocalDateTime?, + val minExpiredTime: LocalDateTime? = null, @get:Schema(title = "最大过期时间") - val maxExpiredTime: LocalDateTime?, + val maxExpiredTime: LocalDateTime? = null, @get:Schema(title = "离职标识") val departedFlag: Boolean? = false, @get:Schema(title = "是否查询模板") val queryTemplate: Boolean? = false, @get:Schema(title = "限制") - val limit: Int, + val limit: Int? = null, @get:Schema(title = "起始值") - val offset: Int + val offset: Int? = null ) { companion object { fun build( diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt index b288b93739f..fa567c941ab 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt @@ -29,6 +29,7 @@ package com.tencent.devops.auth.dao import com.tencent.devops.auth.pojo.AuthResourceGroup +import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.model.auth.tables.TAuthResourceGroup import com.tencent.devops.model.auth.tables.records.TAuthResourceGroupRecord import org.jooq.DSLContext @@ -271,9 +272,10 @@ class AuthResourceGroupDao { it } .let { - if (!iamTemplateIds.isNullOrEmpty()) + if (!iamTemplateIds.isNullOrEmpty()) { + it.and(RESOURCE_TYPE.eq(AuthResourceType.PROJECT.value)) it.and(IAM_TEMPLATE_ID.`in`(iamTemplateIds)) - else + } else it } .fetch().map { it.value1().toInt() } 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 09519c73028..68568ab1ce4 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 @@ -365,13 +365,20 @@ class AuthResourceGroupMemberDao { fun listProjectMembersByComplexConditions( dslContext: DSLContext, - projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO + conditionDTO: ProjectMembersQueryConditionDTO ): List { return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { dslContext.select(MEMBER_ID, MEMBER_NAME, MEMBER_TYPE).from(this) - .where(buildProjectMembersByComplexConditions(projectMembersQueryConditionDTO)) + .where(buildProjectMembersByComplexConditions(conditionDTO)) .groupBy(MEMBER_ID) .orderBy(MEMBER_ID) + .let { + if (conditionDTO.limit != null && conditionDTO.offset != null) { + it.offset(conditionDTO.offset).limit(conditionDTO.limit) + } else { + it + } + } .fetch().map { ResourceMemberInfo( id = it.value1(), @@ -382,6 +389,19 @@ class AuthResourceGroupMemberDao { } } + fun countProjectMembersByComplexConditions( + dslContext: DSLContext, + conditionDTO: ProjectMembersQueryConditionDTO + ): Long { + return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { + dslContext.select(countDistinct(MEMBER_ID)).from(this) + .where(buildProjectMembersByComplexConditions(conditionDTO)) + .groupBy(MEMBER_ID) + .orderBy(MEMBER_ID) + .fetchOne(0, Long::class.java)!! + } + } + fun buildProjectMembersByComplexConditions( projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO ): MutableList { @@ -390,34 +410,22 @@ class AuthResourceGroupMemberDao { with(projectMembersQueryConditionDTO) { conditions.add(PROJECT_CODE.eq(projectCode)) if (queryTemplate == false) { - // 非查询模板时的条件 conditions.add(MEMBER_TYPE.notEqual(ManagerScopesEnum.getType(ManagerScopesEnum.TEMPLATE))) - memberType?.let { type -> conditions.add(MEMBER_TYPE.eq(type)) } - userName?.let { name -> - conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.USER))) - conditions.add(MEMBER_ID.like("%$name%").or(MEMBER_NAME.like("%$name%"))) - } - deptName?.let { name -> - conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.DEPARTMENT))) - conditions.add(MEMBER_NAME.like("%$name%")) - } } else { - // 查询模板时的条件 conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.TEMPLATE))) } - - minExpiredTime?.let { minTime -> - // 添加最小过期时间条件 - conditions.add(EXPIRED_TIME.ge(minTime)) + memberType?.let { type -> conditions.add(MEMBER_TYPE.eq(type)) } + userName?.let { name -> + conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.USER))) + conditions.add(MEMBER_ID.like("%$name%").or(MEMBER_NAME.like("%$name%"))) } - - maxExpiredTime?.let { maxTime -> - // 添加最大过期时间条件 - conditions.add(EXPIRED_TIME.le(maxTime)) + deptName?.let { name -> + conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.DEPARTMENT))) + conditions.add(MEMBER_NAME.like("%$name%")) } - + minExpiredTime?.let { minTime -> conditions.add(EXPIRED_TIME.ge(minTime)) } + maxExpiredTime?.let { maxTime -> conditions.add(EXPIRED_TIME.le(maxTime)) } if (!iamGroupIds.isNullOrEmpty()) { - // 添加IAM组ID条件 conditions.add(IAM_GROUP_ID.`in`(iamGroupIds)) } } @@ -515,38 +523,6 @@ class AuthResourceGroupMemberDao { return conditions } - /** - * 查询组下所有成员 - */ - fun listGroupMember( - dslContext: DSLContext, - projectCode: String, - iamGroupIds: List, - memberType: String? = null, - userName: String? = null, - deptName: String? = null - ): List { - return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { - val conditions = mutableListOf() - conditions.add(PROJECT_CODE.eq(projectCode)) - conditions.add(IAM_GROUP_ID.`in`(iamGroupIds)) - memberType?.let { type -> conditions.add(MEMBER_TYPE.eq(type)) } - userName?.let { name -> - conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.USER))) - conditions.add(MEMBER_ID.like("%$name%").or(MEMBER_NAME.like("%$name%"))) - } - deptName?.let { name -> - conditions.add(MEMBER_TYPE.eq(ManagerScopesEnum.getType(ManagerScopesEnum.DEPARTMENT))) - conditions.add(MEMBER_NAME.like("%$name%")) - } - dslContext.selectFrom(this) - .where(conditions) - .fetch().map { - convert(it) - } - } - } - /** * 获取成员按资源类型分组数量 */ diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt index c080e065cc7..abdb462d2d8 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt @@ -209,7 +209,6 @@ class RbacPermissionResourceMemberService constructor( conditionReq: ProjectMembersQueryConditionReq ): SQLPage { logger.info("list project members by complex conditions: $conditionReq") - // 不允许同时查询部门名称和用户名称 if (conditionReq.userName != null && conditionReq.deptName != null) { return SQLPage(count = 0, records = emptyList()) @@ -229,32 +228,48 @@ class RbacPermissionResourceMemberService constructor( } // 处理复杂查询条件 - val iamGroupIdsByCondition = if (conditionReq.groupName != null) { + val isNeedToQueryIamGroupIds = conditionReq.groupName != null + val iamGroupIdsByCondition = if (isNeedToQueryIamGroupIds) { queryIamGroupIdsByConditions( projectCode = conditionReq.projectCode, groupName = conditionReq.groupName ).takeIf { it.isNotEmpty() } ?: return SQLPage(0, emptyList()) } else { emptyList() - } + }.toMutableList() val conditionDTO = ProjectMembersQueryConditionDTO.build( conditionReq, iamGroupIdsByCondition ) + if (iamGroupIdsByCondition.isNotEmpty()) { + // 根据用户组Id查询出对应用户组中的人员模板成员 + val iamTemplateIds = authResourceGroupMemberDao.listProjectMembersByComplexConditions( + dslContext = dslContext, + conditionDTO = ProjectMembersQueryConditionDTO( + projectCode = conditionDTO.projectCode, + queryTemplate = true, + iamGroupIds = conditionDTO.iamGroupIds + ) + ) + if (iamTemplateIds.isNotEmpty()) { + // 根据查询出的人员模板ID,查询出对应的组ID + val iamGroupIdsFromTemplate = authResourceGroupDao.listIamGroupIdsByConditions( + dslContext = dslContext, + projectCode = conditionDTO.projectCode, + iamTemplateIds = iamTemplateIds.map { it.id.toInt() } + ) + iamGroupIdsByCondition.addAll(iamGroupIdsFromTemplate) + } + } - // 获取用户直接加入组的记录和通过模板加入组的记录 - val (groupMembersFromDirect, groupMembersFromTemplate) = getGroupMembers( - projectMembersQueryConditionDTO = conditionDTO + val records = authResourceGroupMemberDao.listProjectMembersByComplexConditions( + dslContext = dslContext, + conditionDTO = conditionDTO ) - // 合并并去重 - val allGroupMembers = (groupMembersFromDirect + groupMembersFromTemplate) - .distinctBy { it.id }.sortedWith(compareBy({ it.type }, { it.id })) - - // 内存分页 - val (count, records) = paginateResults( - allGroupMembers = allGroupMembers, - projectMembersQueryConditionDTO = conditionDTO + val count = authResourceGroupMemberDao.countProjectMembersByComplexConditions( + dslContext = dslContext, + conditionDTO = conditionDTO ) // 添加离职标志 @@ -265,40 +280,6 @@ class RbacPermissionResourceMemberService constructor( } } - private fun getGroupMembers( - projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO - ): Pair, List> { - val groupMembersFromDirect = authResourceGroupMemberDao.listProjectMembersByComplexConditions( - dslContext = dslContext, - projectMembersQueryConditionDTO = projectMembersQueryConditionDTO.copy(queryTemplate = false) - ).toMutableList() - val recordsWithTemplate = authResourceGroupMemberDao.listProjectMembersByComplexConditions( - dslContext = dslContext, - projectMembersQueryConditionDTO = projectMembersQueryConditionDTO.copy(queryTemplate = true) - ) - val groupMembersFromTemplate = if (recordsWithTemplate.isNotEmpty()) { - listMembersFromTemplate( - projectCode = projectMembersQueryConditionDTO.projectCode, - iamTemplateIds = recordsWithTemplate.map { it.id.toInt() }, - projectMembersQueryConditionDTO = projectMembersQueryConditionDTO - ) - } else { - emptyList() - } - return Pair(groupMembersFromDirect, groupMembersFromTemplate) - } - - private fun paginateResults( - allGroupMembers: List, - projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO - ): Pair> { - val limit = projectMembersQueryConditionDTO.limit - val offset = projectMembersQueryConditionDTO.offset - val startIndex = offset.coerceAtLeast(0) - val endIndex = (limit + offset).coerceAtMost(allGroupMembers.size) - return Pair(allGroupMembers.size.toLong(), allGroupMembers.subList(startIndex, endIndex)) - } - /** * 该方法后期可进行扩展,根据用户组名称,操作,资源类型, * 组策略查询出对应的组ID,传递用户组表进行查询。 @@ -323,34 +304,6 @@ class RbacPermissionResourceMemberService constructor( return finalGroupIds } - // 获取模板下成员 - private fun listMembersFromTemplate( - projectCode: String, - iamTemplateIds: List, - projectMembersQueryConditionDTO: ProjectMembersQueryConditionDTO - ): List { - val iamGroupIdsFromTemplate = authResourceGroupDao.listIamGroupIdsByConditions( - dslContext = dslContext, - projectCode = projectCode, - iamTemplateIds = iamTemplateIds - ) - // 获取模板下的成员 - return authResourceGroupMemberDao.listGroupMember( - dslContext = dslContext, - projectCode = projectCode, - iamGroupIds = iamGroupIdsFromTemplate, - memberType = projectMembersQueryConditionDTO.memberType, - userName = projectMembersQueryConditionDTO.userName, - deptName = projectMembersQueryConditionDTO.deptName - ).map { - ResourceMemberInfo( - id = it.memberId, - name = it.memberName, - type = it.memberType - ) - } - } - override fun getMemberGroupsCount( projectCode: String, memberId: String, From a1f7ff6170172226a17b9d9b13814fad89650098 Mon Sep 17 00:00:00 2001 From: greysonfang Date: Fri, 6 Sep 2024 17:50:55 +0800 Subject: [PATCH 10/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/auth/dao/AuthResourceGroupMemberDao.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 68568ab1ce4..bf542f75aae 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 @@ -398,7 +398,7 @@ class AuthResourceGroupMemberDao { .where(buildProjectMembersByComplexConditions(conditionDTO)) .groupBy(MEMBER_ID) .orderBy(MEMBER_ID) - .fetchOne(0, Long::class.java)!! + .fetchOne(0, Long::class.java) ?: 0L } } From 2fcf6fb617b69d11e58cbba888eb264675e421bf Mon Sep 17 00:00:00 2001 From: greysonfang Date: Mon, 9 Sep 2024 10:07:15 +0800 Subject: [PATCH 11/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/auth/dao/AuthResourceGroupMemberDao.kt | 2 -- 1 file changed, 2 deletions(-) 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 bf542f75aae..1e79337a7c1 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 @@ -396,8 +396,6 @@ class AuthResourceGroupMemberDao { return with(TAuthResourceGroupMember.T_AUTH_RESOURCE_GROUP_MEMBER) { dslContext.select(countDistinct(MEMBER_ID)).from(this) .where(buildProjectMembersByComplexConditions(conditionDTO)) - .groupBy(MEMBER_ID) - .orderBy(MEMBER_ID) .fetchOne(0, Long::class.java) ?: 0L } } From 6df7b0d2abd6e59c5e505f2e7e73250f5ea1d425 Mon Sep 17 00:00:00 2001 From: greysonfang Date: Mon, 9 Sep 2024 10:11:34 +0800 Subject: [PATCH 12/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/auth/dao/AuthResourceGroupMemberDao.kt | 2 ++ 1 file changed, 2 insertions(+) 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 1e79337a7c1..5f70950b7a4 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 @@ -485,6 +485,7 @@ class AuthResourceGroupMemberDao { .from(tResourceGroupMember) .where(tResourceGroupMember.PROJECT_CODE.eq(projectCode)) .and(tResourceGroupMember.MEMBER_TYPE.notEqual(ManagerScopesEnum.getType(ManagerScopesEnum.TEMPLATE))) + .groupBy(tResourceGroupMember.MEMBER_ID) .unionAll( dslContext.select( tResourceAuthorization.HANDOVER_FROM.`as`("MEMBER_ID"), @@ -493,6 +494,7 @@ class AuthResourceGroupMemberDao { ) .from(tResourceAuthorization) .where(tResourceAuthorization.PROJECT_CODE.eq(projectCode)) + .groupBy(tResourceAuthorization.HANDOVER_FROM) ) .asTable(TABLE_NAME) } From 742f99d8db31bcae927f53ac61e27a4778332670 Mon Sep 17 00:00:00 2001 From: greysonfang Date: Mon, 9 Sep 2024 10:32:47 +0800 Subject: [PATCH 13/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/ProjectMembersQueryConditionReq.kt | 4 ++++ .../service/RbacPermissionResourceMemberService.kt | 14 ++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt index 1343fb28ece..14209b5fdf9 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/ProjectMembersQueryConditionReq.kt @@ -29,4 +29,8 @@ data class ProjectMembersQueryConditionReq( fun isComplexQuery(): Boolean { return groupName != null || minExpiredAt != null || maxExpiredAt != null } + + fun isNeedToQueryIamGroupIds(): Boolean { + return groupName != null + } } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt index abdb462d2d8..302d1ff258b 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceMemberService.kt @@ -228,19 +228,21 @@ class RbacPermissionResourceMemberService constructor( } // 处理复杂查询条件 - val isNeedToQueryIamGroupIds = conditionReq.groupName != null - val iamGroupIdsByCondition = if (isNeedToQueryIamGroupIds) { + val iamGroupIdsByCondition = if (conditionReq.isNeedToQueryIamGroupIds()) { queryIamGroupIdsByConditions( projectCode = conditionReq.projectCode, groupName = conditionReq.groupName - ).takeIf { it.isNotEmpty() } ?: return SQLPage(0, emptyList()) + ) } else { emptyList() }.toMutableList() - val conditionDTO = ProjectMembersQueryConditionDTO.build( - conditionReq, iamGroupIdsByCondition - ) + if (conditionReq.isNeedToQueryIamGroupIds() && iamGroupIdsByCondition.isEmpty()) { + return SQLPage(0, emptyList()) + } + + val conditionDTO = ProjectMembersQueryConditionDTO.build(conditionReq, iamGroupIdsByCondition) + if (iamGroupIdsByCondition.isNotEmpty()) { // 根据用户组Id查询出对应用户组中的人员模板成员 val iamTemplateIds = authResourceGroupMemberDao.listProjectMembersByComplexConditions( From d6dd237a07ce4eaafca116711bab1a55ab2e9544 Mon Sep 17 00:00:00 2001 From: greysonfang Date: Mon, 9 Sep 2024 10:34:17 +0800 Subject: [PATCH 14/14] =?UTF-8?q?feat=EF=BC=9A=E9=A1=B9=E7=9B=AE=E6=88=90?= =?UTF-8?q?=E5=91=98=E6=94=AF=E6=8C=81=E6=8C=89=E7=85=A7=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=94=A8=E6=88=B7=E7=BB=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E6=90=9C=E7=B4=A2=20#10892?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/iam/PermissionResourceMemberService.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt index 44dc1004ca0..5bd49626bfc 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceMemberService.kt @@ -181,7 +181,6 @@ interface PermissionResourceMemberService { expiredAt: Long ): Boolean - @Suppress("LongParameterList") fun batchAddResourceGroupMembers( projectCode: String, iamGroupId: Int,