From 224a11ef792b0a7906917d0dc67671350f9d098b Mon Sep 17 00:00:00 2001 From: lannoy0523 <46735290+lannoy0523@users.noreply.github.com> Date: Wed, 29 May 2024 09:58:16 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E6=94=AF=E6=8C=81=E5=A4=8D=E5=88=B6IP=20#2182?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/devops-op/src/utils/copy.js | 16 ++++++++++++++ .../devops-op/src/views/node/FileSystem.vue | 22 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/frontend/devops-op/src/utils/copy.js diff --git a/src/frontend/devops-op/src/utils/copy.js b/src/frontend/devops-op/src/utils/copy.js new file mode 100644 index 0000000000..4568b6e5a2 --- /dev/null +++ b/src/frontend/devops-op/src/utils/copy.js @@ -0,0 +1,16 @@ +export function copyToClipboard(text) { + const textArea = document.createElement('textarea') + textArea.style.position = 'absolute' + textArea.style.width = 0 + textArea.style.height = 0 + textArea.style.left = '-10px' + textArea.style.top = '-10px' + document.body.appendChild(textArea) + + textArea.value = text + textArea.focus() + textArea.select() + const result = document.execCommand('copy') + textArea.remove() + return result ? Promise.resolve() : Promise.reject(new Error()) +} diff --git a/src/frontend/devops-op/src/views/node/FileSystem.vue b/src/frontend/devops-op/src/views/node/FileSystem.vue index 1ab3689589..afb2c4edf2 100644 --- a/src/frontend/devops-op/src/views/node/FileSystem.vue +++ b/src/frontend/devops-op/src/views/node/FileSystem.vue @@ -58,6 +58,13 @@ @click="changeRouteQueryParams(1)" >查询 + + 复制当前所有IP + @@ -108,6 +115,7 @@ import { queryFileSystemClient } from '@/api/fileSystem' import { searchProjects } from '@/api/project' import { listRepositories } from '@/api/repository' import { formatNormalDate } from '@/utils/date' +import { copyToClipboard } from '@/utils/copy' import FileSystemStatusRecordDialog from '@/views/node/components/FileSystemStatusRecordDialog' export default { @@ -237,9 +245,21 @@ export default { return row.online === value }, showRecord(row) { - console.log(row) this.param = row this.showDialog = true + }, + copy() { + const ips = [] + let text = '' + if (this.clients.length > 0) { + for (let i = 0; i < this.clients.length; i++) { + ips.push(this.clients[i].ip) + } + text = ips.join('\n') + } + copyToClipboard(text).then(res => { + this.$message.success('复制成功') + }) } } } From 7da22475e9373e7879314530a97ff0acf4b40481 Mon Sep 17 00:00:00 2001 From: owen Date: Wed, 29 May 2024 17:44:41 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E7=94=A8=E6=88=B7=E7=BB=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BB=8E=E8=93=9D=E7=9B=BE=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=20#2168?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 用户组支持从蓝盾导入 #2168 * feat: 用户组支持从蓝盾导入 #2168 * feat: 用户组支持从蓝盾导入 #2168 * feat: 用户组支持从蓝盾导入 #2168 * feat: 用户组支持从蓝盾导入 #2168 * feat:用户组蓝盾导入--前端支持 #2178 * feat:用户组蓝盾导入--前端支持 #2178 * feat:用户组蓝盾导入--前端支持 #2178 * feat: 用户组支持从蓝盾导入 #2168 * feat:用户组蓝盾导入--前端支持 #2178 * feat: 用户组支持从蓝盾导入 #2168 * feat: 用户组支持从蓝盾导入 #2168 * feat: 用户组支持从蓝盾导入 #2168 --------- Co-authored-by: lannoy0523 <935275025@qq.com> --- .../controller/user/PermissionController.kt | 12 ++ .../auth/dao/repository/RoleRepository.kt | 26 ++- .../bkrepo/auth/helper/PermissionHelper.kt | 2 +- .../tencent/bkrepo/auth/helper/UserHelper.kt | 48 +++-- .../bkrepo/auth/job/ExternalGroupSyncJob.kt | 81 ++++++++ .../com/tencent/bkrepo/auth/model/TRole.kt | 7 +- .../bkrepo/auth/pojo/BkciRoleListResponse.kt | 37 ++++ .../bkrepo/auth/pojo/BkciRoleResult.kt | 47 +++++ .../auth/pojo/role/CreateRoleRequest.kt | 4 +- .../auth/pojo/role/ExternalRoleResult.kt | 7 + .../com/tencent/bkrepo/auth/pojo/role/Role.kt | 4 +- .../bkrepo/auth/pojo/role/RoleSource.kt | 36 ++++ .../bkrepo/auth/service/PermissionService.kt | 4 + .../bkrepo/auth/service/RoleService.kt | 3 + .../auth/service/bkauth/CIAuthService.kt | 18 ++ .../bkauth/DevopsPermissionServiceImpl.kt | 9 + .../service/bkauth/DevopsProjectService.kt | 9 + .../service/local/PermissionServiceImpl.kt | 6 + .../auth/service/local/RoleServiceImpl.kt | 15 +- .../auth/util/request/RoleRequestUtil.kt | 3 +- .../AddUserDialog/addUserDialog.vue | 6 - .../src/store/actions/permission.js | 4 + .../src/views/userGroup/importUserDialog.vue | 186 ++++++++++++++++++ .../src/views/userGroup/index.vue | 34 +++- src/frontend/locale/repository/en-US.json | 6 +- src/frontend/locale/repository/zh-CN.json | 6 +- 26 files changed, 578 insertions(+), 42 deletions(-) create mode 100644 src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/job/ExternalGroupSyncJob.kt create mode 100644 src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/BkciRoleListResponse.kt create mode 100644 src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/BkciRoleResult.kt create mode 100644 src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/ExternalRoleResult.kt create mode 100644 src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/RoleSource.kt create mode 100644 src/frontend/devops-repository/src/views/userGroup/importUserDialog.vue diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/controller/user/PermissionController.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/controller/user/PermissionController.kt index 834573ba1a..11ceb434e8 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/controller/user/PermissionController.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/controller/user/PermissionController.kt @@ -40,6 +40,8 @@ import com.tencent.bkrepo.auth.pojo.permission.UpdatePermissionUserRequest import com.tencent.bkrepo.auth.controller.OpenResource import com.tencent.bkrepo.auth.pojo.enums.AuthPermissionType import com.tencent.bkrepo.auth.pojo.permission.UpdatePermissionDeployInRepoRequest +import com.tencent.bkrepo.auth.pojo.role.ExternalRoleResult +import com.tencent.bkrepo.auth.pojo.role.RoleSource import com.tencent.bkrepo.auth.service.PermissionService import com.tencent.bkrepo.common.api.pojo.Response import com.tencent.bkrepo.common.service.util.ResponseBuilder @@ -182,4 +184,14 @@ class PermissionController @Autowired constructor( preCheckUserInProject(AuthPermissionType.REPO, projectId, repoName) return ResponseBuilder.success(permissionService.getOrCreatePersonalPath(projectId, repoName)) } + + @ApiOperation("查询外部用户组") + @GetMapping("/external/group/{projectId}/{source}") + fun getExternalRole( + @PathVariable projectId: String, + @PathVariable source: RoleSource + ): Response> { + preCheckProjectAdmin(projectId) + return ResponseBuilder.success(permissionService.listExternalRoleByProject(projectId, source)) + } } \ No newline at end of file diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/dao/repository/RoleRepository.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/dao/repository/RoleRepository.kt index f7890e0858..c9b1831679 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/dao/repository/RoleRepository.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/dao/repository/RoleRepository.kt @@ -33,6 +33,7 @@ package com.tencent.bkrepo.auth.dao.repository import com.tencent.bkrepo.auth.model.TRole import com.tencent.bkrepo.auth.pojo.enums.RoleType +import com.tencent.bkrepo.auth.pojo.role.RoleSource import org.springframework.data.mongodb.repository.MongoRepository import org.springframework.stereotype.Repository @@ -49,10 +50,23 @@ interface RoleRepository : MongoRepository { ): List fun findByTypeAndProjectIdAndAdmin(type: RoleType, projectId: String, admin: Boolean): List - fun findByProjectIdAndRepoNameAndType(projectId: String, repoName: String, type: RoleType): List + fun findByTypeAndProjectIdAndRepoName(type: RoleType, projectId: String, repoName: String): List fun findFirstByRoleIdAndProjectId(roleId: String, projectId: String): TRole? - fun findFirstByProjectIdAndTypeAndName(projectId: String, type: RoleType, name: String): TRole? - fun findFirstByRoleIdAndProjectIdAndRepoName(roleId: String, projectId: String, repoName: String): TRole? + fun findFirstByTypeAndProjectIdAndName(type: RoleType, projectId: String, name: String): TRole? + fun findFirstByTypeAndRoleIdAndProjectIdAndRepoName( + type: RoleType, + roleId: String, + projectId: String, + repoName: String + ): TRole? + + fun findFirstByTypeAndRoleIdAndProjectIdAndSource( + type: RoleType, + roleId: String, + projectId: String, + source: RoleSource + ): TRole? + fun findByProjectIdAndTypeAndAdminAndIdIn( projectId: String, type: RoleType, @@ -60,12 +74,14 @@ interface RoleRepository : MongoRepository { ids: List ): List - fun findByProjectIdAndTypeAndAdminAndRepoNameAndIdIn( - projectId: String, + fun findByTypeAndProjectIdAndAdminAndRepoNameAndIdIn( type: RoleType, + projectId: String, admin: Boolean, repoName: String, ids: List ): List + fun findBySource(source: RoleSource): List + } diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/helper/PermissionHelper.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/helper/PermissionHelper.kt index f23127b2fd..7870077218 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/helper/PermissionHelper.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/helper/PermissionHelper.kt @@ -89,7 +89,7 @@ class PermissionHelper constructor( } if (queryRoles.isEmpty()) return false - val result = roleRepository.findByProjectIdAndTypeAndAdminAndRepoNameAndIdIn( + val result = roleRepository.findByTypeAndProjectIdAndAdminAndRepoNameAndIdIn( projectId = request.projectId!!, type = RoleType.REPO, repoName = request.repoName!!, diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/helper/UserHelper.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/helper/UserHelper.kt index d0edd8516a..b7c8470c00 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/helper/UserHelper.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/helper/UserHelper.kt @@ -35,7 +35,6 @@ package com.tencent.bkrepo.auth.helper import com.tencent.bkrepo.auth.dao.UserDao import com.tencent.bkrepo.auth.dao.repository.RoleRepository import com.tencent.bkrepo.auth.message.AuthMessageCode -import com.tencent.bkrepo.auth.model.TRole import com.tencent.bkrepo.auth.model.TUser import com.tencent.bkrepo.auth.pojo.enums.RoleType import com.tencent.bkrepo.auth.pojo.role.CreateRoleRequest @@ -106,18 +105,33 @@ class UserHelper constructor( fun createRoleCommon(request: CreateRoleRequest): String? { logger.info("create role request:[$request] ") - val role: TRole? = if (request.type == RoleType.REPO) { - roleRepository.findFirstByRoleIdAndProjectIdAndRepoName( - request.roleId!!, - request.projectId, - request.repoName!! - ) - } else { - roleRepository.findFirstByProjectIdAndTypeAndName( - projectId = request.projectId, - type = RoleType.PROJECT, - name = request.name - ) + val role = when (request.type) { + RoleType.REPO -> { + require(request.roleId != null) + roleRepository.findFirstByTypeAndRoleIdAndProjectIdAndRepoName( + type = RoleType.REPO, + roleId = request.roleId, + projectId = request.projectId, + repoName = request.repoName!! + ) + } + RoleType.PROJECT -> { + if (request.source == null) { + roleRepository.findFirstByTypeAndProjectIdAndName( + type = RoleType.PROJECT, + projectId = request.projectId, + name = request.name + ) + } else { + require(request.roleId != null) + roleRepository.findFirstByTypeAndRoleIdAndProjectIdAndSource( + type = RoleType.PROJECT, + roleId = request.roleId, + projectId = request.projectId, + source = request.source + ) + } + } } role?.let { @@ -151,13 +165,17 @@ class UserHelper constructor( } private fun findUsableProjectTypeRoleId(roleId: String?, projectId: String): String { - var tempRoleId = roleId ?: "${projectId}_role_${IDUtil.shortUUID()}" + var tempRoleId = roleId ?: buildProjectRoleId(projectId) while (true) { val role = roleRepository.findFirstByRoleIdAndProjectId(tempRoleId, projectId) - if (role == null) return tempRoleId else tempRoleId = "${projectId}_role_${IDUtil.shortUUID()}" + if (role == null) return tempRoleId else tempRoleId = buildProjectRoleId(projectId) } } + private fun buildProjectRoleId(projectId: String): String { + return "${projectId}_role_${IDUtil.shortUUID()}" + } + companion object { private val logger = LoggerFactory.getLogger(UserHelper::class.java) } diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/job/ExternalGroupSyncJob.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/job/ExternalGroupSyncJob.kt new file mode 100644 index 0000000000..312f0acc81 --- /dev/null +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/job/ExternalGroupSyncJob.kt @@ -0,0 +1,81 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.bkrepo.auth.job + +import com.tencent.bkrepo.auth.pojo.role.RoleSource +import com.tencent.bkrepo.auth.pojo.role.UpdateRoleRequest +import com.tencent.bkrepo.auth.service.PermissionService +import com.tencent.bkrepo.auth.service.RoleService +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock +import org.slf4j.LoggerFactory +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Component + +@Component +class ExternalGroupSyncJob( + private val roleService: RoleService, + private val permissionService: PermissionService +) { + + @Scheduled(cron = "0 */10 * * * ? ") + @SchedulerLock(name = "DevopsUserGroupSync", lockAtMostFor = "PT10M") + fun runDevopsUserGroupSync() { + logger.info("start to update external role") + val roleList = roleService.listRoleBySource(RoleSource.DEVOPS) + val projectIdSet = mutableSetOf() + val indexIdMap = mutableMapOf() + val projectIdMap = mutableMapOf() + roleList.forEach { + projectIdSet.add(it.projectId) + indexIdMap[it.roleId] = it.id!! + projectIdMap[it.roleId] = it.projectId + } + + projectIdSet.forEach { project -> + val roleUserMap = mutableMapOf>() + permissionService.listExternalRoleByProject(project, RoleSource.DEVOPS).forEach { externalRole -> + roleUserMap[externalRole.roleId] = externalRole.userList + } + roleList.forEach { role -> + if (projectIdMap[role.roleId] == project) { + val updateRequest = UpdateRoleRequest( + userIds = roleUserMap[role.roleId]!!.toSet(), + description = null, + name = null + ) + logger.info("to update external role [${role.roleId}] ") + roleService.updateRoleInfo(indexIdMap[role.roleId]!!, updateRequest) + } + } + } + } + + companion object { + private val logger = LoggerFactory.getLogger(ExternalGroupSyncJob::class.java) + } +} diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/model/TRole.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/model/TRole.kt index ab54c7a297..d3dd3d5c72 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/model/TRole.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/model/TRole.kt @@ -32,6 +32,7 @@ package com.tencent.bkrepo.auth.model import com.tencent.bkrepo.auth.pojo.enums.RoleType +import com.tencent.bkrepo.auth.pojo.role.RoleSource import org.springframework.data.mongodb.core.index.CompoundIndex import org.springframework.data.mongodb.core.index.CompoundIndexes import org.springframework.data.mongodb.core.mapping.Document @@ -44,7 +45,8 @@ import org.springframework.data.mongodb.core.mapping.Document CompoundIndex(name = "roleId_idx", def = "{'roleId': 1}", background = true), CompoundIndex(name = "type_idx", def = "{'type': 1}", background = true), CompoundIndex(name = "projectId_idx", def = "{'projectId': 1}", background = true), - CompoundIndex(name = "repoName_idx", def = "{'repoName': 1}", background = true) + CompoundIndex(name = "repoName_idx", def = "{'repoName': 1}", background = true), + CompoundIndex(name = "source_idx", def = "{'source': 1}", background = true) ) data class TRole( val id: String? = null, @@ -54,5 +56,6 @@ data class TRole( val projectId: String, val repoName: String? = null, val admin: Boolean = false, - var description: String? = null + var description: String? = null, + var source: RoleSource? = null ) diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/BkciRoleListResponse.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/BkciRoleListResponse.kt new file mode 100644 index 0000000000..c97133923b --- /dev/null +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/BkciRoleListResponse.kt @@ -0,0 +1,37 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.tencent.bkrepo.auth.pojo + +data class BkciRoleListResponse( + val status: Int, + val data: List +) diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/BkciRoleResult.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/BkciRoleResult.kt new file mode 100644 index 0000000000..84f482ebf6 --- /dev/null +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/BkciRoleResult.kt @@ -0,0 +1,47 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.tencent.bkrepo.auth.pojo + +import com.fasterxml.jackson.annotation.JsonProperty + +data class BkciRoleResult( + @JsonProperty("display_name") + val displayName: String, + @JsonProperty("role_id") + val roleId: Long, + @JsonProperty("role_name") + val roleName: String, + @JsonProperty("user_id_list") + val userIdList: List, + @JsonProperty("type") + val type: String +) diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/CreateRoleRequest.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/CreateRoleRequest.kt index caa83cf519..d78e14f467 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/CreateRoleRequest.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/CreateRoleRequest.kt @@ -46,5 +46,7 @@ data class CreateRoleRequest( @ApiModelProperty("管理员") val admin: Boolean = false, @ApiModelProperty("描述信息") - val description: String? = null + val description: String? = null, + @ApiModelProperty("角色来源") + val source: RoleSource? = null ) diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/ExternalRoleResult.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/ExternalRoleResult.kt new file mode 100644 index 0000000000..79b0175336 --- /dev/null +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/ExternalRoleResult.kt @@ -0,0 +1,7 @@ +package com.tencent.bkrepo.auth.pojo.role + +data class ExternalRoleResult( + val name: String, + val roleId: String, + val userList: List +) diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/Role.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/Role.kt index 6697bb90b0..647c38f9d4 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/Role.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/Role.kt @@ -49,5 +49,7 @@ data class Role( @ApiModelProperty("绑定的用户") val users: List = listOf(), @ApiModelProperty("描述信息") - val description: String? = null + val description: String? = null, + @ApiModelProperty("角色来源") + val source: RoleSource? = null ) diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/RoleSource.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/RoleSource.kt new file mode 100644 index 0000000000..56cccd85a5 --- /dev/null +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/pojo/role/RoleSource.kt @@ -0,0 +1,36 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.bkrepo.auth.pojo.role + +import io.swagger.annotations.ApiModel + +@ApiModel("角色来源") +enum class RoleSource { + DEVOPS, + TAI +} diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/PermissionService.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/PermissionService.kt index c4cffa4152..03929aeef8 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/PermissionService.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/PermissionService.kt @@ -37,6 +37,8 @@ import com.tencent.bkrepo.auth.pojo.permission.Permission import com.tencent.bkrepo.auth.pojo.permission.UpdatePermissionDeployInRepoRequest import com.tencent.bkrepo.auth.pojo.permission.UpdatePermissionRepoRequest import com.tencent.bkrepo.auth.pojo.permission.UpdatePermissionUserRequest +import com.tencent.bkrepo.auth.pojo.role.ExternalRoleResult +import com.tencent.bkrepo.auth.pojo.role.RoleSource interface PermissionService { /** @@ -98,4 +100,6 @@ interface PermissionService { fun getPathCheckConfig(): Boolean fun getOrCreatePersonalPath(projectId: String, repoName: String): String + + fun listExternalRoleByProject(projectId: String, source: RoleSource): List } \ No newline at end of file diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/RoleService.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/RoleService.kt index 4b65855320..4890e9f346 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/RoleService.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/RoleService.kt @@ -33,6 +33,7 @@ package com.tencent.bkrepo.auth.service import com.tencent.bkrepo.auth.pojo.role.CreateRoleRequest import com.tencent.bkrepo.auth.pojo.role.Role +import com.tencent.bkrepo.auth.pojo.role.RoleSource import com.tencent.bkrepo.auth.pojo.role.UpdateRoleRequest import com.tencent.bkrepo.auth.pojo.user.UserResult @@ -44,6 +45,8 @@ interface RoleService { fun listRoleByProject(projectId: String, repoName: String? = null): List + fun listRoleBySource(source: RoleSource): List + fun detail(id: String): Role? fun detail(rid: String, projectId: String): Role? diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/CIAuthService.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/CIAuthService.kt index 5f222fed09..c6b89b7324 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/CIAuthService.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/CIAuthService.kt @@ -37,6 +37,8 @@ import com.tencent.bkrepo.auth.condition.DevopsAuthCondition import com.tencent.bkrepo.auth.config.DevopsAuthConfig import com.tencent.bkrepo.auth.pojo.BkciAuthCheckResponse import com.tencent.bkrepo.auth.pojo.BkciAuthListResponse +import com.tencent.bkrepo.auth.pojo.BkciRoleListResponse +import com.tencent.bkrepo.auth.pojo.BkciRoleResult import com.tencent.bkrepo.auth.pojo.enums.BkAuthPermission import com.tencent.bkrepo.auth.pojo.enums.BkAuthResourceType import com.tencent.bkrepo.auth.pojo.enums.PermissionAction @@ -230,6 +232,22 @@ class CIAuthService @Autowired constructor(private val devopsAuthConfig: DevopsA } } + fun getRoleAndUserByProject(projectCode: String): List { + return try { + val url = "${devopsAuthConfig.getBkciAuthServer()}/auth/api/open/service/auth/projects/$projectCode/users" + val request = Request.Builder().url(url).header(DEVOPS_BK_TOKEN, devopsAuthConfig.getBkciAuthToken()) + .get().build() + logger.debug("getRoleAndUserByProject, requestUrl: [$url]") + val apiResponse = HttpUtils.doRequest(okHttpClient, request, 2, allowHttpStatusSet) + val responseObject = objectMapper.readValue(apiResponse.content) + logger.debug("getRoleAndUserByProject, requestUrl: [$url], result : [${apiResponse.content}]") + return responseObject.data + } catch (exception: Exception) { + logger.error("getRoleAndUserByProject error : ", exception) + emptyList() + } + } + companion object { private val logger = LoggerFactory.getLogger(CIAuthService::class.java) private val allowHttpStatusSet = diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/DevopsPermissionServiceImpl.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/DevopsPermissionServiceImpl.kt index 3b483627fc..fac665a8da 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/DevopsPermissionServiceImpl.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/DevopsPermissionServiceImpl.kt @@ -50,6 +50,8 @@ import com.tencent.bkrepo.auth.pojo.enums.PermissionAction.VIEW import com.tencent.bkrepo.auth.pojo.enums.ResourceType.NODE import com.tencent.bkrepo.auth.pojo.enums.ResourceType.REPO import com.tencent.bkrepo.auth.pojo.enums.ResourceType.PROJECT +import com.tencent.bkrepo.auth.pojo.role.ExternalRoleResult +import com.tencent.bkrepo.auth.pojo.role.RoleSource import com.tencent.bkrepo.auth.service.bkiamv3.BkIamV3PermissionServiceImpl import com.tencent.bkrepo.auth.service.bkiamv3.BkIamV3Service import com.tencent.bkrepo.common.artifact.path.PathUtils @@ -129,6 +131,13 @@ class DevopsPermissionServiceImpl constructor( return devopsAuthConfig.enablePathCheck } + override fun listExternalRoleByProject(projectId: String, source: RoleSource): List { + if (source == RoleSource.DEVOPS) { + return devopsProjectService.listRoleAndUserByProject(projectId) + } + return emptyList() + } + private fun parsePipelineId(path: String): String? { val roads = PathUtils.normalizeFullPath(path).split("/") return if (roads.size < 2 || roads[1].isBlank()) { diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/DevopsProjectService.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/DevopsProjectService.kt index 9a342f6b35..314109b665 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/DevopsProjectService.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/bkauth/DevopsProjectService.kt @@ -34,6 +34,7 @@ package com.tencent.bkrepo.auth.service.bkauth import com.tencent.bkrepo.auth.condition.DevopsAuthCondition import com.tencent.bkrepo.auth.pojo.enums.BkAuthPermission import com.tencent.bkrepo.auth.pojo.enums.BkAuthResourceType +import com.tencent.bkrepo.auth.pojo.role.ExternalRoleResult import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Conditional import org.springframework.stereotype.Service @@ -58,4 +59,12 @@ class DevopsProjectService @Autowired constructor(private val ciAuthService: CIA fun listProjectByUser(user: String): List { return ciAuthService.getProjectListByUser(user) } + + fun listRoleAndUserByProject(projectCode: String): List { + val externalRoleList = mutableListOf() + ciAuthService.getRoleAndUserByProject(projectCode).forEach { + externalRoleList.add(ExternalRoleResult(it.roleName, it.roleId.toString(), it.userIdList)) + } + return externalRoleList + } } diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/local/PermissionServiceImpl.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/local/PermissionServiceImpl.kt index d11fdb1976..c2452724ac 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/local/PermissionServiceImpl.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/local/PermissionServiceImpl.kt @@ -62,6 +62,8 @@ import com.tencent.bkrepo.auth.pojo.permission.CheckPermissionRequest import com.tencent.bkrepo.auth.pojo.permission.UpdatePermissionRepoRequest import com.tencent.bkrepo.auth.pojo.permission.UpdatePermissionDeployInRepoRequest import com.tencent.bkrepo.auth.pojo.permission.UpdatePermissionUserRequest +import com.tencent.bkrepo.auth.pojo.role.ExternalRoleResult +import com.tencent.bkrepo.auth.pojo.role.RoleSource import com.tencent.bkrepo.auth.service.PermissionService import com.tencent.bkrepo.auth.util.RequestUtil import com.tencent.bkrepo.auth.util.request.PermRequestUtil @@ -398,6 +400,10 @@ open class PermissionServiceImpl constructor( return true } + override fun listExternalRoleByProject(projectId: String, source: RoleSource): List { + return emptyList() + } + fun isUserLocalProjectAdmin(userId: String, projectId: String?): Boolean { return permHelper.isUserLocalProjectAdmin(userId, projectId) } diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/local/RoleServiceImpl.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/local/RoleServiceImpl.kt index bb182fd15c..0a3976f6e7 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/local/RoleServiceImpl.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/service/local/RoleServiceImpl.kt @@ -43,6 +43,7 @@ import com.tencent.bkrepo.auth.pojo.role.UpdateRoleRequest import com.tencent.bkrepo.auth.pojo.user.UserResult import com.tencent.bkrepo.auth.dao.repository.RoleRepository import com.tencent.bkrepo.auth.helper.UserHelper +import com.tencent.bkrepo.auth.pojo.role.RoleSource import com.tencent.bkrepo.auth.service.RoleService import com.tencent.bkrepo.auth.service.UserService import com.tencent.bkrepo.common.api.exception.ErrorCodeException @@ -75,7 +76,9 @@ class RoleServiceImpl constructor( override fun detail(rid: String, projectId: String, repoName: String): Role? { logger.debug("get role detail rid : [$rid,$projectId,$repoName]") - val result = roleRepository.findFirstByRoleIdAndProjectIdAndRepoName(rid, projectId, repoName) ?: return null + val result = + roleRepository.findFirstByTypeAndRoleIdAndProjectIdAndRepoName(RoleType.REPO, rid, projectId, repoName) + ?: return null return transfer(result) } @@ -111,7 +114,7 @@ class RoleServiceImpl constructor( override fun listRoleByProject(projectId: String, repoName: String?): List { logger.debug("list role by project ,[$projectId , $repoName]") repoName?.let { - return roleRepository.findByProjectIdAndRepoNameAndType(projectId, repoName, RoleType.REPO) + return roleRepository.findByTypeAndProjectIdAndRepoName(RoleType.REPO, projectId, repoName) .map { transfer(it) } } return roleRepository.findByTypeAndProjectIdAndAdminAndRoleIdNotIn( @@ -122,6 +125,11 @@ class RoleServiceImpl constructor( ).map { transfer(it) } } + override fun listRoleBySource(source: RoleSource): List { + logger.debug("list role by role ,[$source]") + return roleRepository.findBySource(source).map { transfer(it) } + } + override fun deleteRoleById(id: String): Boolean { logger.info("delete role id : [$id]") val role = roleRepository.findFirstById(id) @@ -149,7 +157,8 @@ class RoleServiceImpl constructor( projectId = tRole.projectId, admin = tRole.admin, users = users, - description = tRole.description + description = tRole.description, + source = tRole.source ) } diff --git a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/util/request/RoleRequestUtil.kt b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/util/request/RoleRequestUtil.kt index 8343d816ba..fd4c1b3b3f 100644 --- a/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/util/request/RoleRequestUtil.kt +++ b/src/backend/auth/biz-auth/src/main/kotlin/com/tencent/bkrepo/auth/util/request/RoleRequestUtil.kt @@ -40,7 +40,8 @@ object RoleRequestUtil { projectId = request.projectId, repoName = request.repoName, admin = request.admin, - description = request.description + description = request.description, + source = request.source ) } } diff --git a/src/frontend/devops-repository/src/components/AddUserDialog/addUserDialog.vue b/src/frontend/devops-repository/src/components/AddUserDialog/addUserDialog.vue index c23ebd1877..e64c404cb1 100644 --- a/src/frontend/devops-repository/src/components/AddUserDialog/addUserDialog.vue +++ b/src/frontend/devops-repository/src/components/AddUserDialog/addUserDialog.vue @@ -72,12 +72,6 @@ visible: function (newVal) { if (newVal) { this.showDialog = true - this.editUserConfig = { - users: this.showData.users, - search: '', - newUser: '', - originUsers: this.showData.originUsers - } } else { this.cancel() } diff --git a/src/frontend/devops-repository/src/store/actions/permission.js b/src/frontend/devops-repository/src/store/actions/permission.js index 606bcd5592..a325473871 100644 --- a/src/frontend/devops-repository/src/store/actions/permission.js +++ b/src/frontend/devops-repository/src/store/actions/permission.js @@ -309,6 +309,10 @@ export default { commit('SET_REPO_PERMISSION_LIMIT', res) }) }, + // 获取蓝盾传输的用户组 + getUserGroupByExternal (_, { projectId, sourceId }) { + return Vue.prototype.$ajax.get(`${authPrefix}/permission/external/group/${projectId}/${sourceId}`) + }, // 获取当前repo的根目录权限 getRootPermission (_, { projectId, repoName }) { return Vue.prototype.$ajax.get( diff --git a/src/frontend/devops-repository/src/views/userGroup/importUserDialog.vue b/src/frontend/devops-repository/src/views/userGroup/importUserDialog.vue new file mode 100644 index 0000000000..acc8d25a26 --- /dev/null +++ b/src/frontend/devops-repository/src/views/userGroup/importUserDialog.vue @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + {{$t('roleName')}} + {{$t('user')}} + + + + {{row.name}} + {{ name }} + + + + + {{ $t('cancel') }} + {{ $t('confirm') }} + + + + + + + diff --git a/src/frontend/devops-repository/src/views/userGroup/index.vue b/src/frontend/devops-repository/src/views/userGroup/index.vue index 3ff4f8c325..f4febb868c 100644 --- a/src/frontend/devops-repository/src/views/userGroup/index.vue +++ b/src/frontend/devops-repository/src/views/userGroup/index.vue @@ -1,7 +1,8 @@ - + {{ $t('create') }} + {{ $t('import') }} {{row.description || '/'}} - + {{row.users.length ? row.users : '/'}} + + + {{ transformSource(row.source) }} + +