Skip to content

Commit

Permalink
Merge pull request #9354 from fcfang123/issue-9353
Browse files Browse the repository at this point in the history
 feat:蓝盾APP Oauth2授权登录实现 #9353
  • Loading branch information
bkci-bot authored Nov 27, 2023
2 parents 247ddeb + d747a47 commit 4c0d851
Show file tree
Hide file tree
Showing 66 changed files with 2,652 additions and 191 deletions.
4 changes: 2 additions & 2 deletions scripts/render_tpl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ sed_script=$(mktemp /tmp/XXXXXX.sed)

usage () {
echo "Usage: $0 [-c] [-n] [-E k=v, -E k=v] tpl_path ..."
}
}

usage_and_exit () {
usage
Expand All @@ -34,7 +34,7 @@ target_file_path () {
echo ${_target_file%.tpl}
}

[[ $# -eq 0 ]] && usage_and_exit 1
[[ $# -eq 0 ]] && usage_and_exit 1
declare -i DRY_RUN=0 CHECK=0
declare MODULE=""
declare -a EXTRA_ENV=()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.tencent.devops.auth.api.oauth2

import com.tencent.devops.auth.pojo.dto.Oauth2AuthorizationCodeDTO
import com.tencent.devops.auth.pojo.vo.Oauth2AuthorizationInfoVo
import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_USER_ID
import com.tencent.devops.common.api.pojo.Result
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.POST
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.MediaType

@Api(tags = ["OAUTH2_ENDPOINT"], description = "oauth2相关")
@Path("/desktop/oauth2/endpoint")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
interface Oauth2DesktopEndpointResource {
@GET
@Path("/getAuthorizationInformation")
@ApiOperation("获取授权信息")
fun getAuthorizationInformation(
@HeaderParam(AUTH_HEADER_DEVOPS_USER_ID)
@ApiParam("待校验用户ID", required = true)
userId: String,
@QueryParam("clientId")
@ApiParam("客户端ID", required = true)
clientId: String,
@QueryParam("redirectUri")
@ApiParam("跳转链接", required = true)
redirectUri: String
): Result<Oauth2AuthorizationInfoVo>

@POST
@Path("/getAuthorizationCode")
@ApiOperation("获取授权码")
fun getAuthorizationCode(
@HeaderParam(AUTH_HEADER_DEVOPS_USER_ID)
@ApiParam("待校验用户ID", required = true)
userId: String,
@QueryParam("clientId")
@ApiParam("客户端ID", required = true)
clientId: String,
@QueryParam("redirectUri")
@ApiParam("跳转链接", required = true)
redirectUri: String,
@ApiParam("oauth2获取授权码请求报文体", required = true)
authorizationCodeDTO: Oauth2AuthorizationCodeDTO
): Result<String>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.tencent.devops.auth.api.oauth2

import com.tencent.devops.auth.pojo.Oauth2AccessTokenRequest
import com.tencent.devops.auth.pojo.dto.Oauth2AuthorizationCodeDTO
import com.tencent.devops.auth.pojo.vo.Oauth2AccessTokenVo
import com.tencent.devops.auth.pojo.vo.Oauth2AuthorizationInfoVo
import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_USER_ID
import com.tencent.devops.common.api.auth.AUTH_HEADER_OAUTH2_AUTHORIZATION
import com.tencent.devops.common.api.auth.AUTH_HEADER_OAUTH2_CLIENT_ID
import com.tencent.devops.common.api.auth.AUTH_HEADER_OAUTH2_CLIENT_SECRET
import com.tencent.devops.common.api.pojo.Result
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.POST
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.MediaType

@Api(tags = ["OAUTH2_ENDPOINT"], description = "oauth2相关")
@Path("/service/oauth2/endpoint")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
interface Oauth2ServiceEndpointResource {
@GET
@Path("/getAuthorizationInformation")
@ApiOperation("获取授权信息")
fun getAuthorizationInformation(
@HeaderParam(AUTH_HEADER_DEVOPS_USER_ID)
@ApiParam("待校验用户ID", required = true)
userId: String,
@QueryParam("clientId")
@ApiParam("客户端ID", required = true)
clientId: String,
@QueryParam("redirectUri")
@ApiParam("跳转链接", required = true)
redirectUri: String
): Result<Oauth2AuthorizationInfoVo>

@POST
@Path("/getAuthorizationCode")
@ApiOperation("获取授权码")
fun getAuthorizationCode(
@HeaderParam(AUTH_HEADER_DEVOPS_USER_ID)
@ApiParam("待校验用户ID", required = true)
userId: String,
@QueryParam("clientId")
@ApiParam("客户端ID", required = true)
clientId: String,
@QueryParam("redirectUri")
@ApiParam("跳转链接", required = true)
redirectUri: String,
@ApiParam("oauth2获取授权码请求报文体", required = true)
authorizationCodeDTO: Oauth2AuthorizationCodeDTO
): Result<String>

@POST
@Path("/getAccessToken")
@ApiOperation("获取accessToken")
fun getAccessToken(
@HeaderParam(AUTH_HEADER_OAUTH2_CLIENT_ID)
@ApiParam("客户端id", required = true)
clientId: String,
@HeaderParam(AUTH_HEADER_OAUTH2_CLIENT_SECRET)
@ApiParam("客户端秘钥", required = true)
clientSecret: String,
@ApiParam("oauth2获取token请求报文体", required = true)
accessTokenRequest: Oauth2AccessTokenRequest
): Result<Oauth2AccessTokenVo?>

@POST
@Path("/verifyAccessToken")
@ApiOperation("校验accessToken")
fun verifyAccessToken(
@HeaderParam(AUTH_HEADER_OAUTH2_CLIENT_ID)
@ApiParam("客户端id", required = true)
clientId: String,
@HeaderParam(AUTH_HEADER_OAUTH2_CLIENT_SECRET)
@ApiParam("客户端秘钥", required = true)
clientSecret: String,
@HeaderParam(AUTH_HEADER_OAUTH2_AUTHORIZATION)
@ApiParam("access token", required = true)
accessToken: String
): Result<String>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.tencent.devops.auth.api.oauth2

import com.tencent.devops.auth.pojo.dto.ClientDetailsDTO
import com.tencent.devops.auth.pojo.dto.ScopeOperationDTO
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import javax.ws.rs.Consumes
import javax.ws.rs.DELETE
import javax.ws.rs.POST
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.MediaType
import com.tencent.devops.common.api.pojo.Result

@Api(tags = ["OP_OAUTH2"], description = "oauth2相关-op接口")
@Path("/op/oauth2/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
interface OpOauth2Resource {
@POST
@Path("/createClientDetails")
@ApiOperation("新增Oauth2客户端信息")
fun createClientDetails(
@ApiParam("Oauth2客户端请求实体", required = true)
clientDetailsDTO: ClientDetailsDTO
): Result<Boolean>

@DELETE
@Path("/deleteClientDetails")
@ApiOperation("删除Oauth2客户端信息")
fun deleteClientDetails(
@ApiParam("客户端ID", required = true)
@QueryParam("clientId")
clientId: String
): Result<Boolean>

@POST
@Path("/createScopeOperation")
@ApiOperation("新增Oauth2授权操作信息")
fun createScopeOperation(
@ApiParam("Oauth2授权操作信息请求实体", required = true)
scopeOperationDTO: ScopeOperationDTO
): Result<Boolean>

@DELETE
@Path("/deleteScopeOperation")
@ApiOperation("删除Oauth2授权操作信息")
fun deleteScopeOperation(
@ApiParam("授权操作ID", required = true)
@QueryParam("operationId")
operationId: String
): Result<Boolean>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.tencent.devops.auth.api.service

import com.tencent.devops.auth.pojo.vo.UserAndDeptInfoVo
import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_USER_ID
import com.tencent.devops.common.api.pojo.Result
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.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.MediaType

@Api(tags = ["SERVICE_SECURITY"], description = "安全相关")
@Path("/service/security")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
interface ServiceSecurityResource {
@GET
@Path("/getUserSecurityInfo")
@ApiOperation("获取安全相关信息")
fun getUserSecurityInfo(
@HeaderParam(AUTH_HEADER_DEVOPS_USER_ID)
@ApiParam("用户ID", required = true)
userId: String,
@ApiParam("项目ID", required = true)
@QueryParam("projectCode")
projectCode: String
): Result<UserAndDeptInfoVo>
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,24 @@ object AuthMessageCode {
const val ERROR_MIGRATE_AUTH_COMPARE_FAIL = "2121061" // 迁移项目{0}失败,权限策略对比失败
const val ERROR_CREATOR_NOT_EXIST = "2121062" // 创建人离职
const val ERROR_RESOURCE_CREATE_FAIL = "2121063" // 资源创建失败
const val ERROR_CLIENT_NOT_EXIST = "2121064" // 客户端{0}不存在
const val INVALID_AUTHORIZATION_TYPE = "2121065" // 授权类型{0}不合法
const val INVALID_REDIRECT_URI = "2121066" // 跳转链接{0}不合法
const val INVALID_CLIENT_SECRET = "2121067" // 客户端{0}密钥不合法
const val INVALID_AUTHORIZATION_CODE = "2121068" // 授权码不合法
const val INVALID_AUTHORIZATION_EXPIRED = "2121069" // 授权码已过期
const val ERROR_REFRESH_TOKEN_NOT_FOUND = "2121070" // refresh_token不能为空
const val INVALID_REFRESH_TOKEN = "2121071" // refresh_token不合法
const val ERROR_REFRESH_TOKEN_EXPIRED = "2121072" // refresh token已过期
const val ERROR_ACCESS_TOKEN_NOT_FOUND = "2121073" // access token不能为空
const val INVALID_ACCESS_TOKEN = "2121074" // access token不合法
const val ERROR_ACCESS_TOKEN_EXPIRED = "2121075" // access token已过期
const val INVALID_SCOPE = "2121076" // scope不合法

const val ERROR_MONITOR_SPACE_NOT_EXIST = "2121077" // 监控空间不存在
const val ERROR_MONITOR_READ_ONLY_ACTIONS_NOT_EXIST = "2121078" // 业务只读组不存在
const val ERROR_MONITOR_OPS_ACTIONS_NOT_EXIST = "2121079" // 业务运维组不存在

const val ERROR_WATER_MARK_NOT_EXIST = "2121080" // 水印信息不存在
const val ERROR_USER_NOT_EXIST = "2121081" // 用户不存在
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.tencent.devops.auth.pojo

import com.fasterxml.jackson.annotation.JsonProperty
import io.swagger.annotations.ApiModel
import io.swagger.annotations.ApiModelProperty

@ApiModel("用户部门详细信息")
data class BkUserDeptInfo(
@ApiModelProperty("id")
val id: String?,
@ApiModelProperty("部门名称")
val name: String?,
@ApiModelProperty("部门详细名称")
@JsonProperty("full_name")
val fullName: String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.tencent.devops.auth.pojo

import com.fasterxml.jackson.annotation.JsonProperty
import io.swagger.annotations.ApiModel
import io.swagger.annotations.ApiModelProperty

@ApiModel("用户额外信息")
data class BkUserExtras(
@ApiModelProperty("性别")
val gender: String?,
@ApiModelProperty("postName")
@JsonProperty("postname")
val postName: String?
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ data class BkUserInfo(
@ApiModelProperty("用户名")
val username: String,
@ApiModelProperty("是否启用")
val enabled: Boolean
val enabled: Boolean,
@ApiModelProperty("用户额外信息")
val extras: BkUserExtras?,
@ApiModelProperty("用户部门")
val departments: List<BkUserDeptInfo>?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.tencent.devops.auth.pojo

import io.swagger.annotations.ApiModel
import io.swagger.annotations.ApiModelProperty

@ApiModel("Oauth2客户端详情")
data class ClientDetailsInfo(
@ApiModelProperty("客户端id", required = true)
val clientId: String,
@ApiModelProperty("客户端密钥", required = true)
val clientSecret: String,
@ApiModelProperty("客户端名称", required = true)
val clientName: String,
@ApiModelProperty("授权类型", required = true)
val authorizedGrantTypes: String,
@ApiModelProperty("跳转链接", required = true)
val redirectUri: String,
@ApiModelProperty("授权范围", required = true)
val scope: String,
@ApiModelProperty("accessToken有效期", required = true)
val accessTokenValidity: Long,
@ApiModelProperty("refreshToken有效期", required = true)
val refreshTokenValidity: Long,
@ApiModelProperty("图标", required = true)
val icon: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.tencent.devops.auth.pojo

import io.swagger.annotations.ApiModel
import io.swagger.annotations.ApiModelProperty

@ApiModel("oauth2获取token请求报文体")
data class Oauth2AccessTokenRequest(
@ApiModelProperty("授权类型", required = true)
val grantType: String,
@ApiModelProperty("授权码,用于授权码模式", required = false)
val code: String? = null,
@ApiModelProperty("refreshToken,用于刷新授权码模式", required = false)
val refreshToken: String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.tencent.devops.auth.pojo.dto

import io.swagger.annotations.ApiModel
import io.swagger.annotations.ApiModelProperty

@ApiModel("Oauth2客户端请求实体")
data class ClientDetailsDTO(
@ApiModelProperty("客户端ID")
val clientId: String,
@ApiModelProperty("客户端秘钥")
val clientSecret: String,
@ApiModelProperty("客户端名称")
val clientName: String,
@ApiModelProperty("授权操作范围")
val scope: String,
@ApiModelProperty("图标")
val icon: String,
@ApiModelProperty("授权模式")
val authorizedGrantTypes: String,
@ApiModelProperty("跳转链接")
val webServerRedirectUri: String,
@ApiModelProperty("access_token有效时间")
val accessTokenValidity: Long,
@ApiModelProperty("refresh_token有效时间")
val refreshTokenValidity: Long,
@ApiModelProperty("创建人")
val createUser: String? = null,
@ApiModelProperty("更新人")
val updateUser: String? = null
)
Loading

0 comments on commit 4c0d851

Please sign in to comment.