Skip to content

Commit

Permalink
Merge pull request #9170 from fcfang123/issue-9116
Browse files Browse the repository at this point in the history
feat:蓝盾权限-支持查询某单一资源的用户组人员名单 #9116
  • Loading branch information
bkci-bot authored Sep 22, 2023
2 parents 6d4166d + a62311a commit 7563864
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 76 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.tencent.devops.auth.api.service

import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_BK_TOKEN
import com.tencent.devops.common.api.pojo.Result
import com.tencent.devops.common.auth.api.pojo.BkAuthGroup
import com.tencent.devops.common.auth.api.pojo.BkAuthGroupAndUserList
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import javax.ws.rs.Consumes
import javax.ws.rs.GET
import javax.ws.rs.HeaderParam
import javax.ws.rs.Path
import javax.ws.rs.PathParam
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.MediaType

@Api(tags = ["AUTH_SERVICE_RESOURCE"], description = "权限--资源相关接口")
@Path("/open/service/auth/resource/member")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
interface ServiceResourceMemberResource {
@GET
@Path("/{projectCode}/getResourceGroupUsers")
@ApiOperation("获取特定资源下用户组成员")
fun getResourceGroupMembers(
@HeaderParam(AUTH_HEADER_DEVOPS_BK_TOKEN)
@ApiParam("认证token", required = true)
token: String,
@PathParam("projectCode")
@ApiParam("项目Code", required = true)
projectCode: String,
@QueryParam("resourceType")
@ApiParam("资源类型", required = false)
resourceType: String,
@QueryParam("resourceCode")
@ApiParam("资源code", required = false)
resourceCode: String,
@QueryParam("group")
@ApiParam("资源用户组类型", required = false)
group: BkAuthGroup? = null
): Result<List<String>>

@GET
@Path("/{projectCode}/getResourceUsers")
@ApiOperation("拉取资源下所有成员,并按项目角色组分组成员信息返回")
fun getResourceGroupAndMembers(
@HeaderParam(AUTH_HEADER_DEVOPS_BK_TOKEN)
@ApiParam("认证token", required = true)
token: String,
@PathParam("projectCode")
@ApiParam("项目Code", required = true)
projectCode: String,
@QueryParam("resourceType")
@ApiParam("资源类型", required = false)
resourceType: String,
@QueryParam("resourceCode")
@ApiParam("资源code", required = false)
resourceCode: String
): Result<List<BkAuthGroupAndUserList>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import com.tencent.devops.auth.service.RbacPermissionItsmCallbackService
import com.tencent.devops.auth.service.RbacPermissionProjectService
import com.tencent.devops.auth.service.RbacPermissionResourceCallbackService
import com.tencent.devops.auth.service.RbacPermissionResourceGroupService
import com.tencent.devops.auth.service.RbacPermissionResourceMemberService
import com.tencent.devops.auth.service.RbacPermissionResourceService
import com.tencent.devops.auth.service.RbacPermissionResourceValidateService
import com.tencent.devops.auth.service.RbacPermissionService
Expand Down Expand Up @@ -172,6 +173,21 @@ class RbacAuthConfiguration {
dslContext = dslContext
)

@Bean
fun permissionResourceMemberService(
authResourceService: AuthResourceService,
iamV2ManagerService: V2ManagerService,
permissionGradeManagerService: PermissionGradeManagerService,
authResourceGroupDao: AuthResourceGroupDao,
dslContext: DSLContext
) = RbacPermissionResourceMemberService(
authResourceService = authResourceService,
iamV2ManagerService = iamV2ManagerService,
permissionGradeManagerService = permissionGradeManagerService,
authResourceGroupDao = authResourceGroupDao,
dslContext = dslContext
)

@Bean
@Primary
fun rbacPermissionExtService(
Expand Down Expand Up @@ -224,7 +240,7 @@ class RbacAuthConfiguration {
dslContext: DSLContext,
rbacCacheService: RbacCacheService,
deptService: DeptService,
permissionGradeManagerService: PermissionGradeManagerService
resourceGroupMemberService: RbacPermissionResourceMemberService
) = RbacPermissionProjectService(
authHelper = authHelper,
authResourceService = authResourceService,
Expand All @@ -234,7 +250,7 @@ class RbacAuthConfiguration {
dslContext = dslContext,
rbacCacheService = rbacCacheService,
deptService = deptService,
permissionGradeManagerService = permissionGradeManagerService
resourceGroupMemberService = resourceGroupMemberService
)

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,15 @@
package com.tencent.devops.auth.service

import com.tencent.bk.sdk.iam.config.IamConfiguration
import com.tencent.bk.sdk.iam.constants.ManagerScopesEnum
import com.tencent.bk.sdk.iam.dto.InstanceDTO
import com.tencent.bk.sdk.iam.dto.V2PageInfoDTO
import com.tencent.bk.sdk.iam.dto.manager.ManagerMember
import com.tencent.bk.sdk.iam.dto.manager.dto.ManagerMemberGroupDTO
import com.tencent.bk.sdk.iam.dto.manager.dto.SearchGroupDTO
import com.tencent.bk.sdk.iam.helper.AuthHelper
import com.tencent.bk.sdk.iam.service.v2.V2ManagerService
import com.tencent.devops.auth.constant.AuthMessageCode
import com.tencent.devops.auth.dao.AuthResourceGroupDao
import com.tencent.devops.auth.service.iam.PermissionProjectService
import com.tencent.devops.common.api.exception.ErrorCodeException
import com.tencent.devops.common.api.util.PageUtil
import com.tencent.devops.common.auth.api.AuthPermission
import com.tencent.devops.common.auth.api.AuthResourceType
import com.tencent.devops.common.auth.api.pojo.BKAuthProjectRolesResources
Expand All @@ -62,7 +58,7 @@ class RbacPermissionProjectService(
private val dslContext: DSLContext,
private val rbacCacheService: RbacCacheService,
private val deptService: DeptService,
private val permissionGradeManagerService: PermissionGradeManagerService
private val resourceGroupMemberService: RbacPermissionResourceMemberService
) : PermissionProjectService {

companion object {
Expand All @@ -71,75 +67,24 @@ class RbacPermissionProjectService(
private const val USER_TYPE = "user"
}

override fun getProjectUsers(projectCode: String, group: BkAuthGroup?): List<String> {
return when (group) {
// 新的rbac版本中,没有ci管理员组,不可以调用此接口来获取ci管理员组的成员
BkAuthGroup.CIADMIN, BkAuthGroup.CI_MANAGER -> emptyList()
// 获取项目下组全部成员
null -> {
getProjectGroupAndUserList(projectCode).flatMap { it.userIdList }.distinct()
}
else -> {
val dbGroupInfo = authResourceGroupDao.get(
dslContext = dslContext,
projectCode = projectCode,
resourceType = AuthResourceType.PROJECT.value,
resourceCode = projectCode,
groupCode = group.value
) ?: return emptyList()
val groupInfo = getProjectGroupAndUserList(projectCode)
.find { it.roleId == dbGroupInfo.relationId.toInt() }
groupInfo?.userIdList ?: emptyList()
}
}
override fun getProjectUsers(
projectCode: String,
group: BkAuthGroup?
): List<String> {
return resourceGroupMemberService.getResourceGroupMembers(
projectCode = projectCode,
resourceType = AuthResourceType.PROJECT.value,
resourceCode = projectCode,
group = group
)
}

override fun getProjectGroupAndUserList(projectCode: String): List<BkAuthGroupAndUserList> {
// 1、获取分级管理员id
val gradeManagerId = authResourceService.get(
return resourceGroupMemberService.getResourceGroupAndMembers(
projectCode = projectCode,
resourceType = AuthResourceType.PROJECT.value,
resourceCode = projectCode
).relationId
val searchGroupDTO = SearchGroupDTO.builder().inherit(false).build()
val groupInfoList = permissionGradeManagerService.listGroup(
gradeManagerId = gradeManagerId,
searchGroupDTO = searchGroupDTO,
page = 1,
pageSize = 1000
)
logger.info(
"[RBAC-IAM] getProjectGroupAndUserList: projectCode = $projectCode |" +
" gradeManagerId = $gradeManagerId | groupInfoList: $groupInfoList"
)
val result = mutableListOf<BkAuthGroupAndUserList>()
groupInfoList.forEach {
// 3、获取组成员
val pageInfoDTO = V2PageInfoDTO()
pageInfoDTO.page = PageUtil.DEFAULT_PAGE
pageInfoDTO.pageSize = PageUtil.MAX_PAGE_SIZE * 10
val groupMemberInfoList = iamV2ManagerService.getRoleGroupMemberV2(it.id, pageInfoDTO).results
logger.info(
"[RBAC-IAM] getProjectGroupAndUserList ,groupId: ${it.id} " +
"| groupMemberInfoList: $groupMemberInfoList"
)
val members = mutableListOf<String>()
groupMemberInfoList.forEach { memberInfo ->
// todo 暂时不返回部门的用户
if (memberInfo.type == ManagerScopesEnum.getType(ManagerScopesEnum.USER)) {
members.add(memberInfo.id)
}
}
val groupAndUser = BkAuthGroupAndUserList(
displayName = it.name,
roleId = it.id,
roleName = it.name,
userIdList = members.toSet().toList(),
type = ""
)
result.add(groupAndUser)
}
return result
}

override fun getUserProjects(userId: String): List<String> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package com.tencent.devops.auth.service

import com.tencent.bk.sdk.iam.constants.ManagerScopesEnum
import com.tencent.bk.sdk.iam.dto.V2PageInfoDTO
import com.tencent.bk.sdk.iam.dto.manager.V2ManagerRoleGroupInfo
import com.tencent.bk.sdk.iam.dto.manager.dto.SearchGroupDTO
import com.tencent.bk.sdk.iam.service.v2.V2ManagerService
import com.tencent.devops.auth.dao.AuthResourceGroupDao
import com.tencent.devops.auth.service.iam.PermissionResourceMemberService
import com.tencent.devops.common.auth.api.AuthResourceType
import com.tencent.devops.common.auth.api.pojo.BkAuthGroup
import com.tencent.devops.common.auth.api.pojo.BkAuthGroupAndUserList
import org.jooq.DSLContext
import org.slf4j.LoggerFactory

class RbacPermissionResourceMemberService constructor(
private val authResourceService: AuthResourceService,
private val iamV2ManagerService: V2ManagerService,
private val permissionGradeManagerService: PermissionGradeManagerService,
private val authResourceGroupDao: AuthResourceGroupDao,
private val dslContext: DSLContext
) : PermissionResourceMemberService {
override fun getResourceGroupMembers(
projectCode: String,
resourceType: String,
resourceCode: String,
group: BkAuthGroup?
): List<String> {
logger.info("[RBAC-IAM] get resource group members:$projectCode|$resourceType|$resourceCode|$group")
return when (group) {
// 新的rbac版本中,没有ci管理员组,不可以调用此接口来获取ci管理员组的成员
BkAuthGroup.CIADMIN, BkAuthGroup.CI_MANAGER -> emptyList()
// 获取特定资源下全部成员
null -> {
getResourceGroupAndMembers(
projectCode = projectCode,
resourceType = resourceType,
resourceCode = resourceCode
).flatMap { it.userIdList }.distinct()
}
// 获取特定资源下特定用户组成员
else -> {
val dbGroupInfo = authResourceGroupDao.get(
dslContext = dslContext,
projectCode = projectCode,
resourceType = resourceType,
resourceCode = resourceCode,
groupCode = group.value
) ?: return emptyList()
val groupInfo = getResourceGroupAndMembers(
projectCode = projectCode,
resourceType = resourceType,
resourceCode = resourceCode
).find { it.roleId == dbGroupInfo.relationId.toInt() }
groupInfo?.userIdList ?: emptyList()
}
}
}

override fun getResourceGroupAndMembers(
projectCode: String,
resourceType: String,
resourceCode: String
): List<BkAuthGroupAndUserList> {
// 1、获取管理员id
val managerId = authResourceService.get(
projectCode = projectCode,
resourceType = resourceType,
resourceCode = resourceCode
).relationId
// 2、获取分级管理员下所有的用户组
val groupInfoList = getGroupInfoList(
resourceType = resourceType,
managerId = managerId
)
logger.info(
"[RBAC-IAM] getResourceGroupAndMembers: projectCode = $projectCode |" +
" managerId = $managerId | groupInfoList: $groupInfoList"
)
// 3、获取组成员
return groupInfoList.map { getUsersUnderGroup(groupInfo = it) }
}

private fun getGroupInfoList(
resourceType: String,
managerId: String
): List<V2ManagerRoleGroupInfo> {
return if (resourceType == AuthResourceType.PROJECT.value) {
val searchGroupDTO = SearchGroupDTO.builder().inherit(false).build()
permissionGradeManagerService.listGroup(
gradeManagerId = managerId,
searchGroupDTO = searchGroupDTO,
page = 1,
pageSize = 1000
)
} else {
val v2PageInfoDTO = V2PageInfoDTO().apply {
pageSize = 1000
page = 1
}
iamV2ManagerService.getSubsetManagerRoleGroup(
managerId.toInt(),
v2PageInfoDTO
).results
}
}

private fun getUsersUnderGroup(groupInfo: V2ManagerRoleGroupInfo): BkAuthGroupAndUserList {
val pageInfoDTO = V2PageInfoDTO().apply {
pageSize = 1000
page = 1
}
val groupMemberInfoList = iamV2ManagerService.getRoleGroupMemberV2(groupInfo.id, pageInfoDTO).results
logger.info(
"[RBAC-IAM] getUsersUnderGroup ,groupId: ${groupInfo.id} | groupMemberInfoList: $groupMemberInfoList"
)
val members = mutableListOf<String>()
groupMemberInfoList.forEach { memberInfo ->
if (memberInfo.type == ManagerScopesEnum.getType(ManagerScopesEnum.USER)) {
members.add(memberInfo.id)
}
}
return BkAuthGroupAndUserList(
displayName = groupInfo.name,
roleId = groupInfo.id,
roleName = groupInfo.name,
userIdList = members.toSet().toList(),
type = ""
)
}

companion object {
private val logger = LoggerFactory.getLogger(RbacPermissionResourceMemberService::class.java)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.tencent.devops.auth.service.iam.PermissionItsmCallbackService
import com.tencent.devops.auth.service.iam.PermissionMigrateService
import com.tencent.devops.auth.service.iam.PermissionProjectService
import com.tencent.devops.auth.service.iam.PermissionResourceGroupService
import com.tencent.devops.auth.service.iam.PermissionResourceMemberService
import com.tencent.devops.auth.service.iam.PermissionResourceService
import com.tencent.devops.auth.service.iam.PermissionResourceValidateService
import com.tencent.devops.auth.service.iam.PermissionRoleMemberService
Expand All @@ -32,6 +33,7 @@ import com.tencent.devops.auth.service.sample.SamplePermissionGradeService
import com.tencent.devops.auth.service.sample.SamplePermissionItsmCallbackService
import com.tencent.devops.auth.service.sample.SamplePermissionMigrateService
import com.tencent.devops.auth.service.sample.SamplePermissionResourceGroupService
import com.tencent.devops.auth.service.sample.SamplePermissionResourceMemberService
import com.tencent.devops.auth.service.sample.SamplePermissionResourceService
import com.tencent.devops.auth.service.sample.SamplePermissionResourceValidateService
import com.tencent.devops.auth.service.sample.SamplePermissionRoleMemberService
Expand Down Expand Up @@ -104,6 +106,10 @@ class MockAuthCoreAutoConfiguration {
@ConditionalOnMissingBean(PermissionResourceGroupService::class)
fun samplePermissionResourceGroupService() = SamplePermissionResourceGroupService()

@Bean
@ConditionalOnMissingBean(PermissionResourceMemberService::class)
fun samplePermissionResourceMemberService() = SamplePermissionResourceMemberService()

@Bean
@ConditionalOnMissingBean(PermissionApplyService::class)
fun samplePermissionApplyService() = SamplePermissionApplyService()
Expand Down
Loading

0 comments on commit 7563864

Please sign in to comment.