Skip to content

Commit

Permalink
feat: add CompositeActionMatcher (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ahoo-Wang authored Mar 24, 2023
1 parent bb83ab6 commit dbee28d
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright [2021-present] [ahoo wang <[email protected]> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.ahoo.cosec.policy.action

import me.ahoo.cosec.api.configuration.Configuration
import me.ahoo.cosec.api.context.SecurityContext
import me.ahoo.cosec.api.context.request.Request
import me.ahoo.cosec.api.policy.ActionMatcher

class CompositeActionMatcher(
override val type: String,
private val actionMatchers: List<ActionMatcher>,
override val configuration: Configuration
) : ActionMatcher {

override fun match(request: Request, securityContext: SecurityContext): Boolean {
return actionMatchers.any { pathActionMatcher ->
pathActionMatcher.match(request, securityContext)
}
}
}

class CompositeActionMatcherFactory : ActionMatcherFactory {
companion object {
const val TYPE = "composite"
}

override val type: String
get() = TYPE

override fun create(configuration: Configuration): ActionMatcher {
configuration.asList().let { actionMatcherConfigurations ->
val actionMatchers = actionMatcherConfigurations.map { actionMatcherConfiguration ->
actionMatcherConfiguration.asObject(ActionMatcher::class.java)
}
return CompositeActionMatcher(TYPE, actionMatchers, configuration)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,6 @@ class ReplaceablePathActionMatcher(
}
}

class CompositePathActionMatcher(
private val actionMatchers: List<ActionMatcher>,
override val configuration: Configuration
) : ActionMatcher {
override val type: String
get() = PathActionMatcherFactory.TYPE

override fun match(request: Request, securityContext: SecurityContext): Boolean {
return actionMatchers.any { pathActionMatcher ->
pathActionMatcher.match(request, securityContext)
}
}
}

class PathActionMatcherFactory : ActionMatcherFactory {
companion object {
const val TYPE = "path"
Expand Down Expand Up @@ -99,7 +85,8 @@ class PathActionMatcherFactory : ActionMatcherFactory {
asList()
.map { it.stringAsActionMatcher() }
.let { actionMatchers ->
return CompositePathActionMatcher(
return CompositeActionMatcher(
type = TYPE,
actionMatchers = actionMatchers,
configuration = this
)
Expand All @@ -118,7 +105,8 @@ class PathActionMatcherFactory : ActionMatcherFactory {
if (actionMatchers.size == 1) {
return actionMatchers.first()
}
return CompositePathActionMatcher(
return CompositeActionMatcher(
type = TYPE,
actionMatchers = actionMatchers,
configuration = this
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ import me.ahoo.cosec.policy.action.PathActionMatcherFactory

object JsonActionMatcherSerializer : StdSerializer<ActionMatcher>(ActionMatcher::class.java) {
override fun serialize(value: ActionMatcher, gen: JsonGenerator, provider: SerializerProvider) {
if (value.configuration.isString || value.configuration.isArray) {
if (value.type == PathActionMatcherFactory.TYPE &&
(value.configuration.isString || value.configuration.isArray)
) {
gen.writePOJO(value.configuration)
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
#
me.ahoo.cosec.policy.action.AllActionMatcherFactory
me.ahoo.cosec.policy.action.PathActionMatcherFactory
me.ahoo.cosec.policy.action.CompositeActionMatcherFactory
17 changes: 17 additions & 0 deletions cosec-core/src/test/resources/test-policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,23 @@
}
}
}
},
{
"name": "TestComposite",
"effect": "allow",
"action": {
"composite": [
"/user/#{principal.id}/*",
{
"path": {
"method": "POST",
"pattern": [
"/user/#{principal.id}/order/*"
]
}
}
]
}
}
]
}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# limitations under the License.
#
group=me.ahoo.cosec
version=1.16.5
version=1.16.6
description=RBAC-based And Policy-based Multi-Tenant Reactive Security Framework
website=https://github.com/Ahoo-Wang/CoSec
issues=https://github.com/Ahoo-Wang/CoSec/issues
Expand Down
22 changes: 22 additions & 0 deletions schema/action.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
"path": {
"$ref": "#/definitions/pathActionMatcher"
},
"composite": {
"$ref": "#/definitions/compositeActionMatcher"
},
"all": {
"$ref": "#/definitions/allActionMatcher"
}
Expand Down Expand Up @@ -84,6 +87,25 @@
"required": [
"pattern"
]
},
"compositeActionMatcher": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/pathActionMatcher"
}
}
}
]
},
"minItems": 1
}
}
}
Expand Down

0 comments on commit dbee28d

Please sign in to comment.