Skip to content

Commit

Permalink
feat: openapi filter 优化 #10679
Browse files Browse the repository at this point in the history
  • Loading branch information
yongyiduan committed Sep 20, 2024
1 parent 7d3a050 commit d4ddd69
Show file tree
Hide file tree
Showing 12 changed files with 501 additions and 268 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.tencent.devops.openapi.filter

import com.tencent.devops.common.web.RequestFilter
import com.tencent.devops.openapi.filter.manager.ApiFilterManagerChain
import javax.ws.rs.container.ContainerRequestContext
import javax.ws.rs.container.ContainerRequestFilter
import javax.ws.rs.container.PreMatching
import javax.ws.rs.ext.Provider

@Provider
@PreMatching
@RequestFilter
class OpenapiFilter constructor(
private val apiFilter: ApiFilterManagerChain
) : ContainerRequestFilter {

override fun filter(requestContext: ContainerRequestContext) {
apiFilter.doFilterCheck(requestContext)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.devops.openapi.filter.manager

enum class ApiFilterFlowState {
CONTINUE, // 正常会继续下一指令
AUTHORIZED, // 已授权
BREAK; // 提前结束指令,会中断Command链路
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
* 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.devops.openapi.filter

import javax.ws.rs.container.ContainerRequestContext
import javax.ws.rs.container.ContainerRequestFilter
package com.tencent.devops.openapi.filter.manager

interface ApiFilter : ContainerRequestFilter {
interface ApiFilterManager {

fun verifyJWT(requestContext: ContainerRequestContext): Boolean
fun canExecute(requestContext: FilterContext): Boolean

fun verify(requestContext: FilterContext): ApiFilterFlowState
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.tencent.devops.openapi.filter.manager

import com.google.common.cache.CacheBuilder
import com.google.common.cache.CacheLoader
import com.google.common.cache.LoadingCache
import com.tencent.devops.common.service.utils.SpringContextUtil
import org.springframework.stereotype.Service

@Service
class ApiFilterManagerCache {
private val cache: LoadingCache<Class<out ApiFilterManager>, ApiFilterManager> = CacheBuilder.newBuilder()
.maximumSize(100).build(
object : CacheLoader<Class<out ApiFilterManager>, ApiFilterManager>() {
override fun load(clazz: Class<out ApiFilterManager>): ApiFilterManager {
return SpringContextUtil.getBean(clazz)
}
}
)

fun getFilter(clazz: Class<out ApiFilterManager>): ApiFilterManager {
return cache.get(clazz)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.devops.openapi.filter.manager

import javax.ws.rs.container.ContainerRequestContext
import javax.ws.rs.core.Response

interface ApiFilterManagerChain {

fun doFilterCheck(
requestContext: FilterContext,
chain: Iterator<ApiFilterManager>
) {
if (chain.hasNext()) {
val next = chain.next()
if (next.canExecute(requestContext)) {
requestContext.setFlowState(next.verify(requestContext))
}
if (requestContext.flowState == ApiFilterFlowState.BREAK) return
doFilterCheck(requestContext, chain)
return
}

// 如果需要检查权限,那必须返回AUTHORIZED才表示已授权成功
if (requestContext.needCheckPermissions && requestContext.flowState != ApiFilterFlowState.AUTHORIZED) {
requestContext.requestContext.abortWith(
Response.status(Response.Status.FORBIDDEN)
.entity("You do not have permission to access")
.build()
)
}
}

fun FilterContext.setFlowState(state: ApiFilterFlowState) {
/*只有CONTINUE状态能够流转*/
if (flowState == ApiFilterFlowState.CONTINUE) {
flowState = state
}
}

fun doFilterCheck(requestContext: ContainerRequestContext)
}
Loading

0 comments on commit d4ddd69

Please sign in to comment.