diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceResourceGroupResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceResourceGroupResource.kt index dcbc9e6e546..35f662d4cd7 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceResourceGroupResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceResourceGroupResource.kt @@ -1,6 +1,7 @@ package com.tencent.devops.auth.api.service import com.tencent.devops.auth.pojo.dto.GroupAddDTO +import com.tencent.devops.auth.pojo.request.CustomGroupCreateReq import com.tencent.devops.auth.pojo.vo.GroupPermissionDetailVo import com.tencent.devops.common.api.annotation.BkInterfaceI18n import com.tencent.devops.common.api.pojo.Result @@ -49,7 +50,18 @@ interface ServiceResourceGroupResource { @Parameter(description = "用户组code,CI管理员为CI_MANAGER", required = true) @QueryParam("groupCode") groupCode: BkAuthGroup - ): Result + ): Result + + @POST + @Path("/{projectCode}/createCustomGroupAndPermissions/") + @Operation(summary = "创建自定义用户组和权限") + fun createCustomGroupAndPermissions( + @Parameter(description = "项目Id", required = true) + @PathParam("projectCode") + projectCode: String, + @Parameter(description = "自定义组创建请求体", required = true) + customGroupCreateReq: CustomGroupCreateReq + ): Result @POST @Path("/{projectCode}/createGroup/") diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/CustomGroupCreateReq.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/CustomGroupCreateReq.kt new file mode 100644 index 00000000000..b0d5d9e98b1 --- /dev/null +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/request/CustomGroupCreateReq.kt @@ -0,0 +1,13 @@ +package com.tencent.devops.auth.pojo.request + +import io.swagger.v3.oas.annotations.media.Schema + +@Schema(title = "自定义组创建请求体") +data class CustomGroupCreateReq( + @get:Schema(title = "组名称") + val groupName: String, + @get:Schema(title = "组描述") + val groupDesc: String, + @get:Schema(title = "操作集合") + val actions: List +) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/config/RbacAuthConfiguration.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/config/RbacAuthConfiguration.kt index f6dc9dd7779..71d841d67f6 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/config/RbacAuthConfiguration.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/config/RbacAuthConfiguration.kt @@ -178,7 +178,8 @@ class RbacAuthConfiguration { rbacCacheService: RbacCacheService, monitorSpaceService: AuthMonitorSpaceService, authResourceGroupConfigDao: AuthResourceGroupConfigDao, - authResourceGroupMemberDao: AuthResourceGroupMemberDao + authResourceGroupMemberDao: AuthResourceGroupMemberDao, + objectMapper: ObjectMapper ) = RbacPermissionResourceGroupService( iamV2ManagerService = iamV2ManagerService, authResourceService = authResourceService, @@ -190,7 +191,8 @@ class RbacAuthConfiguration { rbacCacheService = rbacCacheService, monitorSpaceService = monitorSpaceService, authResourceGroupConfigDao = authResourceGroupConfigDao, - authResourceGroupMemberDao = authResourceGroupMemberDao + authResourceGroupMemberDao = authResourceGroupMemberDao, + objectMapper = objectMapper ) @Bean diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceGroupService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceGroupService.kt index 62e0309f4e4..e950ab5a694 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceGroupService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/rbac/service/RbacPermissionResourceGroupService.kt @@ -28,9 +28,14 @@ package com.tencent.devops.auth.provider.rbac.service +import com.fasterxml.jackson.databind.ObjectMapper import com.tencent.bk.sdk.iam.constants.ManagerScopesEnum import com.tencent.bk.sdk.iam.dto.InstancesDTO import com.tencent.bk.sdk.iam.dto.V2PageInfoDTO +import com.tencent.bk.sdk.iam.dto.manager.Action +import com.tencent.bk.sdk.iam.dto.manager.AuthorizationScopes +import com.tencent.bk.sdk.iam.dto.manager.ManagerPath +import com.tencent.bk.sdk.iam.dto.manager.ManagerResources import com.tencent.bk.sdk.iam.dto.manager.ManagerRoleGroup import com.tencent.bk.sdk.iam.dto.manager.dto.ManagerRoleGroupDTO import com.tencent.bk.sdk.iam.dto.manager.dto.SearchGroupDTO @@ -51,6 +56,7 @@ import com.tencent.devops.auth.pojo.dto.GroupAddDTO import com.tencent.devops.auth.pojo.dto.ListGroupConditionDTO import com.tencent.devops.auth.pojo.dto.RenameGroupDTO import com.tencent.devops.auth.pojo.enum.GroupMemberStatus +import com.tencent.devops.auth.pojo.request.CustomGroupCreateReq import com.tencent.devops.auth.pojo.vo.GroupPermissionDetailVo import com.tencent.devops.auth.pojo.vo.IamGroupInfoVo import com.tencent.devops.auth.pojo.vo.IamGroupMemberInfoVo @@ -82,7 +88,8 @@ class RbacPermissionResourceGroupService @Autowired constructor( private val rbacCacheService: RbacCacheService, private val monitorSpaceService: AuthMonitorSpaceService, private val authResourceGroupConfigDao: AuthResourceGroupConfigDao, - private val authResourceGroupMemberDao: AuthResourceGroupMemberDao + private val authResourceGroupMemberDao: AuthResourceGroupMemberDao, + private val objectMapper: ObjectMapper ) : PermissionResourceGroupService { @Value("\${auth.iamSystem:}") private val systemId = "" @@ -98,6 +105,7 @@ class RbacPermissionResourceGroupService @Autowired constructor( private const val MAX_GROUP_NAME_LENGTH = 32 private const val MIN_GROUP_NAME_LENGTH = 5 private const val FIRST_PAGE = 1 + private const val CUSTOM_GROUP_CODE = "custom" } override fun listGroup( @@ -340,7 +348,7 @@ class RbacPermissionResourceGroupService @Autowired constructor( projectCode = projectId, projectName = projectInfo.resourceName, relationId = projectInfo.relationId.toInt(), - groupCode = "custom", + groupCode = CUSTOM_GROUP_CODE, groupName = groupAddDTO.groupName, description = groupAddDTO.groupDesc ) @@ -460,7 +468,7 @@ class RbacPermissionResourceGroupService @Autowired constructor( override fun createProjectGroupByGroupCode( projectId: String, groupCode: String - ): Boolean { + ): Int { val projectInfo = authResourceService.get( projectCode = projectId, resourceType = AuthResourceType.PROJECT.value, @@ -482,7 +490,7 @@ class RbacPermissionResourceGroupService @Autowired constructor( groupCode = groupConfig.groupCode ) if (resourceGroupInfo != null) { - return false + return resourceGroupInfo.relationId.toInt() } val iamGroupId = createProjectGroupToIam( projectCode = projectId, @@ -502,7 +510,79 @@ class RbacPermissionResourceGroupService @Autowired constructor( resourceName = projectInfo.resourceName, iamGroupId = iamGroupId ) - return true + return iamGroupId + } + + override fun createCustomGroupAndPermissions( + projectId: String, + customGroupCreateReq: CustomGroupCreateReq + ): Int { + val projectInfo = authResourceService.get( + projectCode = projectId, + resourceType = AuthResourceType.PROJECT.value, + resourceCode = projectId + ) + val resourceGroupInfo = authResourceGroupDao.getByGroupName( + dslContext = dslContext, + projectCode = projectId, + resourceType = AuthResourceType.PROJECT.value, + resourceCode = projectId, + groupName = customGroupCreateReq.groupName + ) + if (resourceGroupInfo != null) + return resourceGroupInfo.relationId.toInt() + val authorizationScopes = buildProjectPermissions( + projectCode = projectInfo.projectCode, + projectName = projectInfo.resourceName, + actions = customGroupCreateReq.actions + ) + val iamGroupId = createProjectGroupToIam( + projectCode = projectId, + projectName = projectInfo.resourceName, + relationId = projectInfo.relationId.toInt(), + groupCode = CUSTOM_GROUP_CODE, + groupName = customGroupCreateReq.groupName, + description = customGroupCreateReq.groupDesc + ) + permissionGroupPoliciesService.grantGroupPermission( + authorizationScopesStr = authorizationScopes, + projectCode = projectId, + projectName = projectInfo.resourceName, + resourceType = AuthResourceType.PROJECT.value, + groupCode = CUSTOM_GROUP_CODE, + iamResourceCode = projectId, + resourceName = projectInfo.resourceName, + iamGroupId = iamGroupId + ) + return iamGroupId + } + + private fun buildProjectPermissions( + projectCode: String, + projectName: String, + actions: List + ): String { + val resourceType2Actions = actions.groupBy { it.substringAfterLast("_") } + val authorizationScopes = resourceType2Actions.map { (resourceType, actions) -> + val projectPath = ManagerPath().apply { + system = systemId + id = projectCode + name = projectName + type = AuthResourceType.PROJECT.value + } + val resources = ManagerResources.builder() + .system(systemId) + .type(resourceType) + .paths(listOf(listOf(projectPath))) + .build() + val iamActions = actions.map { Action(it) } + AuthorizationScopes().also { + it.resources = listOf(resources) + it.actions = iamActions + it.system = systemId + } + } + return objectMapper.writeValueAsString(authorizationScopes) } private fun getGroupPermissionDetailBySystem(iamSystemId: String, groupId: Int): List { diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceGroupService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceGroupService.kt index 30a8fc341af..293fd27e406 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceGroupService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/provider/sample/service/SamplePermissionResourceGroupService.kt @@ -31,6 +31,7 @@ package com.tencent.devops.auth.provider.sample.service import com.tencent.devops.auth.pojo.dto.GroupAddDTO import com.tencent.devops.auth.pojo.dto.ListGroupConditionDTO import com.tencent.devops.auth.pojo.dto.RenameGroupDTO +import com.tencent.devops.auth.pojo.request.CustomGroupCreateReq import com.tencent.devops.auth.pojo.vo.GroupPermissionDetailVo import com.tencent.devops.auth.pojo.vo.IamGroupInfoVo import com.tencent.devops.auth.pojo.vo.IamGroupMemberInfoVo @@ -96,5 +97,10 @@ class SamplePermissionResourceGroupService : PermissionResourceGroupService { override fun createProjectGroupByGroupCode( projectId: String, groupCode: String - ) = true + ) = 0 + + override fun createCustomGroupAndPermissions( + projectId: String, + customGroupCreateReq: CustomGroupCreateReq + ): Int = 0 } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/service/ServiceResourceGroupResourceImpl.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/service/ServiceResourceGroupResourceImpl.kt index 9553befeb08..202a8a61de1 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/service/ServiceResourceGroupResourceImpl.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/resources/service/ServiceResourceGroupResourceImpl.kt @@ -2,6 +2,7 @@ package com.tencent.devops.auth.resources.service import com.tencent.devops.auth.api.service.ServiceResourceGroupResource import com.tencent.devops.auth.pojo.dto.GroupAddDTO +import com.tencent.devops.auth.pojo.request.CustomGroupCreateReq import com.tencent.devops.auth.pojo.vo.GroupPermissionDetailVo import com.tencent.devops.auth.service.iam.PermissionResourceGroupService import com.tencent.devops.common.api.pojo.Result @@ -27,7 +28,7 @@ class ServiceResourceGroupResourceImpl constructor( projectCode: String, resourceType: String, groupCode: BkAuthGroup - ): Result { + ): Result { return Result( permissionResourceGroupService.createProjectGroupByGroupCode( projectId = projectCode, @@ -36,6 +37,18 @@ class ServiceResourceGroupResourceImpl constructor( ) } + override fun createCustomGroupAndPermissions( + projectCode: String, + customGroupCreateReq: CustomGroupCreateReq + ): Result { + return Result( + permissionResourceGroupService.createCustomGroupAndPermissions( + projectId = projectCode, + customGroupCreateReq = customGroupCreateReq + ) + ) + } + override fun createGroup( projectCode: String, groupAddDTO: GroupAddDTO diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceGroupService.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceGroupService.kt index 700b634676b..07d1c98f666 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceGroupService.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/service/iam/PermissionResourceGroupService.kt @@ -31,6 +31,7 @@ package com.tencent.devops.auth.service.iam import com.tencent.devops.auth.pojo.dto.GroupAddDTO import com.tencent.devops.auth.pojo.dto.ListGroupConditionDTO import com.tencent.devops.auth.pojo.dto.RenameGroupDTO +import com.tencent.devops.auth.pojo.request.CustomGroupCreateReq import com.tencent.devops.auth.pojo.vo.GroupPermissionDetailVo import com.tencent.devops.auth.pojo.vo.IamGroupInfoVo import com.tencent.devops.auth.pojo.vo.IamGroupMemberInfoVo @@ -91,5 +92,10 @@ interface PermissionResourceGroupService { fun createProjectGroupByGroupCode( projectId: String, groupCode: String - ): Boolean + ): Int + + fun createCustomGroupAndPermissions( + projectId: String, + customGroupCreateReq: CustomGroupCreateReq + ): Int } diff --git a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwAuthProjectResourceV4.kt b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwAuthProjectResourceV4.kt index 0efbdfe7396..7fd7286cde2 100644 --- a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwAuthProjectResourceV4.kt +++ b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwAuthProjectResourceV4.kt @@ -1,6 +1,7 @@ package com.tencent.devops.openapi.api.apigw.v4 import com.tencent.devops.auth.pojo.dto.GroupAddDTO +import com.tencent.devops.auth.pojo.request.CustomGroupCreateReq import com.tencent.devops.auth.pojo.vo.GroupPermissionDetailVo import com.tencent.devops.auth.pojo.vo.ProjectPermissionInfoVO import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_APP_CODE @@ -190,7 +191,27 @@ interface ApigwAuthProjectResourceV4 { @Parameter(description = "用户组code,CI管理员为CI_MANAGER", required = true) @QueryParam("groupCode") groupCode: BkAuthGroup - ): Result + ): Result + + @POST + @Path("/create_custom_group_and_permissions/") + @Operation(summary = "创建自定义用户和权限", tags = ["v4_app_create_custom_group_and_permissions"]) + fun createCustomGroupAndPermissions( + @Parameter(description = "appCode", required = true, example = AUTH_HEADER_DEVOPS_APP_CODE_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_DEVOPS_APP_CODE) + appCode: String?, + @Parameter(description = "apigw Type", required = true) + @PathParam("apigwType") + apigwType: String?, + @Parameter(description = "userId") + @HeaderParam(AUTH_HEADER_DEVOPS_USER_ID) + userId: String?, + @Parameter(description = "项目Id", required = true) + @PathParam("projectId") + projectId: String, + @Parameter(description = "自定义组创建请求体", required = true) + customGroupCreateReq: CustomGroupCreateReq + ): Result @POST @Path("/create_group") diff --git a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwAuthProjectResourceV4Impl.kt b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwAuthProjectResourceV4Impl.kt index 0e187c02f3a..017513ca840 100644 --- a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwAuthProjectResourceV4Impl.kt +++ b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwAuthProjectResourceV4Impl.kt @@ -4,6 +4,7 @@ import com.tencent.devops.auth.api.service.ServiceProjectAuthResource import com.tencent.devops.auth.api.service.ServiceResourceGroupResource import com.tencent.devops.auth.api.service.ServiceResourceMemberResource import com.tencent.devops.auth.pojo.dto.GroupAddDTO +import com.tencent.devops.auth.pojo.request.CustomGroupCreateReq import com.tencent.devops.auth.pojo.vo.GroupPermissionDetailVo import com.tencent.devops.auth.pojo.vo.ProjectPermissionInfoVO import com.tencent.devops.common.api.pojo.Result @@ -128,7 +129,7 @@ class ApigwAuthProjectResourceV4Impl @Autowired constructor( projectId: String, resourceType: String, groupCode: BkAuthGroup - ): Result { + ): Result { logger.info( "OPENAPI_AUTH_PROJECT_RESOURCE_V4 createGroupByGroupCode " + " |$appCode|$userId|$projectId|$resourceType|$groupCode" @@ -140,6 +141,23 @@ class ApigwAuthProjectResourceV4Impl @Autowired constructor( ) } + override fun createCustomGroupAndPermissions( + appCode: String?, + apigwType: String?, + userId: String?, + projectId: String, + customGroupCreateReq: CustomGroupCreateReq + ): Result { + logger.info( + "OPENAPI_AUTH_PROJECT_RESOURCE_V4 createCustomGroupAndPermissions " + + " |$appCode|$userId|$projectId|$customGroupCreateReq" + ) + return client.get(ServiceResourceGroupResource::class).createCustomGroupAndPermissions( + projectCode = projectId, + customGroupCreateReq = customGroupCreateReq + ) + } + override fun createGroup( appCode: String?, apigwType: String?,