diff --git a/cosec-api/src/main/kotlin/me/ahoo/cosec/api/configuration/Configuration.kt b/cosec-api/src/main/kotlin/me/ahoo/cosec/api/configuration/Configuration.kt new file mode 100644 index 00000000..046745ad --- /dev/null +++ b/cosec-api/src/main/kotlin/me/ahoo/cosec/api/configuration/Configuration.kt @@ -0,0 +1,35 @@ +/* + * Copyright [2021-present] [ahoo wang (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.api.configuration + +interface Configuration { + fun get(key: String): Configuration? + fun getRequired(key: String): Configuration = requireNotNull(get(key)) { + "Configuration[$key] is required!" + } + + fun asList(): List + fun asMap(): Map + fun asString(): String + fun asBoolean(): Boolean + fun asInt(): Int + fun asLong(): Long + fun asPojo(pojoClass: Class): T + + fun has(key: String): Boolean = get(key) != null + fun asStringList(): List = asList().map { it.asString() } + fun asStringMap(): Map = asMap().mapValues { it.value.asString() } +} + +inline fun Configuration.asPojo(): T = asPojo(T::class.java) diff --git a/cosec-api/src/main/kotlin/me/ahoo/cosec/api/context/request/Request.kt b/cosec-api/src/main/kotlin/me/ahoo/cosec/api/context/request/Request.kt index 60dacaf4..6c129a22 100644 --- a/cosec-api/src/main/kotlin/me/ahoo/cosec/api/context/request/Request.kt +++ b/cosec-api/src/main/kotlin/me/ahoo/cosec/api/context/request/Request.kt @@ -20,7 +20,6 @@ interface Request : Tenant { * Http Request: {url}:{method} */ val action: String - val remoteIp: String val origin: String val referer: String diff --git a/cosec-api/src/main/kotlin/me/ahoo/cosec/api/principal/RequestMatcher.kt b/cosec-api/src/main/kotlin/me/ahoo/cosec/api/principal/RequestMatcher.kt index c4040d17..3be1c899 100644 --- a/cosec-api/src/main/kotlin/me/ahoo/cosec/api/principal/RequestMatcher.kt +++ b/cosec-api/src/main/kotlin/me/ahoo/cosec/api/principal/RequestMatcher.kt @@ -13,11 +13,12 @@ package me.ahoo.cosec.api.principal +import me.ahoo.cosec.api.configuration.Configuration import me.ahoo.cosec.api.context.SecurityContext import me.ahoo.cosec.api.context.request.Request interface RequestMatcher { val type: String - val pattern: String + val configuration: Configuration fun match(request: Request, securityContext: SecurityContext): Boolean } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/configuration/JsonConfiguration.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/configuration/JsonConfiguration.kt new file mode 100644 index 00000000..58d390e3 --- /dev/null +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/configuration/JsonConfiguration.kt @@ -0,0 +1,84 @@ +/* + * Copyright [2021-present] [ahoo wang (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.configuration + +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.NullNode +import me.ahoo.cosec.Delegated +import me.ahoo.cosec.api.configuration.Configuration +import me.ahoo.cosec.serialization.CoSecJsonSerializer + +class JsonConfiguration( + override val delegate: JsonNode, + private val objectCodec: ObjectCodec +) : Configuration, + Delegated { + + companion object { + val EMPTY: JsonConfiguration by lazy { + JsonConfiguration(NullNode.getInstance(), CoSecJsonSerializer) + } + + fun Map.asConfiguration(): JsonConfiguration { + val jsonString = CoSecJsonSerializer.writeValueAsString(this) + return JsonConfiguration(CoSecJsonSerializer.readTree(jsonString), CoSecJsonSerializer) + } + } + + override fun get(key: String): Configuration? { + return delegate.get(key)?.let { JsonConfiguration(it, objectCodec) } + } + + override fun asList(): List { + return buildList { + val elements = delegate.elements() + while (elements.hasNext()) { + add(JsonConfiguration(elements.next(), objectCodec)) + } + } + } + + override fun asMap(): Map { + return buildMap { + val fields = delegate.fields() + while (fields.hasNext()) { + val field = fields.next() + put(field.key, JsonConfiguration(field.value, objectCodec)) + } + } + } + + override fun asString(): String { + return delegate.asText() + } + + override fun asBoolean(): Boolean { + return delegate.asBoolean() + } + + override fun asInt(): Int { + return delegate.asInt() + } + + override fun asLong(): Long { + return delegate.asLong() + } + + override fun asPojo(pojoClass: Class): T { + return delegate.traverse(objectCodec).use { + it.readValueAs(pojoClass) + } + } +} diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/MatcherConfiguration.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/MatcherConfiguration.kt new file mode 100644 index 00000000..214efefe --- /dev/null +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/MatcherConfiguration.kt @@ -0,0 +1,27 @@ +/* + * Copyright [2021-present] [ahoo wang (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 + +import me.ahoo.cosec.api.configuration.Configuration + +const val MATCHER_TYPE_KEY = "type" +const val MATCHER_PATTERN_KEY = "pattern" + +fun Configuration.getMatcherType(): String { + return getRequired(MATCHER_TYPE_KEY).asString() +} + +fun Configuration.getMatcherPattern(): String { + return getRequired(MATCHER_PATTERN_KEY).asString() +} diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/ActionMatcherFactory.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/ActionMatcherFactory.kt index 593e1c91..deb85b74 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/ActionMatcherFactory.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/ActionMatcherFactory.kt @@ -13,9 +13,10 @@ package me.ahoo.cosec.policy.action +import me.ahoo.cosec.api.configuration.Configuration import me.ahoo.cosec.api.policy.ActionMatcher interface ActionMatcherFactory { val type: String - fun create(pattern: String): ActionMatcher + fun create(configuration: Configuration): ActionMatcher } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/AllActionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/AllActionMatcher.kt index fbbe4dd2..f100913c 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/AllActionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/AllActionMatcher.kt @@ -13,15 +13,14 @@ 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 -object AllActionMatcher : ActionMatcher { +class AllActionMatcher(override val configuration: Configuration) : ActionMatcher { override val type: String get() = AllActionMatcherFactory.TYPE - override val pattern: String - get() = "*" override fun match(request: Request, securityContext: SecurityContext): Boolean { return true @@ -36,7 +35,7 @@ class AllActionMatcherFactory : ActionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ActionMatcher { - return AllActionMatcher + override fun create(configuration: Configuration): ActionMatcher { + return AllActionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/NoneActionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/NoneActionMatcher.kt index d6ab5464..9a632c38 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/NoneActionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/NoneActionMatcher.kt @@ -13,15 +13,14 @@ 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 -object NoneActionMatcher : ActionMatcher { +class NoneActionMatcher(override val configuration: Configuration) : ActionMatcher { override val type: String get() = NoneActionMatcherFactory.TYPE - override val pattern: String - get() = "!" override fun match(request: Request, securityContext: SecurityContext): Boolean { return false @@ -36,7 +35,7 @@ class NoneActionMatcherFactory : ActionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ActionMatcher { - return NoneActionMatcher + override fun create(configuration: Configuration): ActionMatcher { + return NoneActionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/PathActionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/PathActionMatcher.kt index 4dc4a067..97297658 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/PathActionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/PathActionMatcher.kt @@ -13,16 +13,18 @@ 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 +import me.ahoo.cosec.policy.getMatcherPattern import org.springframework.http.server.PathContainer import org.springframework.web.util.pattern.PathPatternParser -data class PathActionMatcher(override val pattern: String) : ActionMatcher { +class PathActionMatcher(override val configuration: Configuration) : ActionMatcher { override val type: String get() = PathActionMatcherFactory.TYPE - private val pathPattern = PathPatternParser.defaultInstance.parse(pattern) + private val pathPattern = PathPatternParser.defaultInstance.parse(configuration.getMatcherPattern()) override fun match(request: Request, securityContext: SecurityContext): Boolean { PathContainer.parsePath(request.action).let { return pathPattern.matches(it) @@ -30,12 +32,12 @@ data class PathActionMatcher(override val pattern: String) : ActionMatcher { } } -data class ReplaceablePathActionMatcher(override val pattern: String) : ActionMatcher { +class ReplaceablePathActionMatcher(override val configuration: Configuration) : ActionMatcher { override val type: String get() = PathActionMatcherFactory.TYPE override fun match(request: Request, securityContext: SecurityContext): Boolean { - val pathPattern = ActionPatternReplacer.replace(pattern, securityContext) + val pathPattern = ActionPatternReplacer.replace(configuration.getMatcherPattern(), securityContext) PathPatternParser.defaultInstance.parse(pathPattern).let { return it.matches(PathContainer.parsePath(request.action)) } @@ -50,14 +52,15 @@ class PathActionMatcherFactory : ActionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ActionMatcher { + override fun create(configuration: Configuration): ActionMatcher { + val pattern = configuration.getMatcherPattern() return if (ActionPatternReplacer.isTemplate(pattern)) { ReplaceablePathActionMatcher( - pattern + configuration ) } else { PathActionMatcher( - pattern + configuration ) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/RegularActionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/RegularActionMatcher.kt index 15162149..eb98b1ed 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/RegularActionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/RegularActionMatcher.kt @@ -13,13 +13,15 @@ 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 +import me.ahoo.cosec.policy.getMatcherPattern -data class RegularActionMatcher(override val pattern: String) : ActionMatcher { +class RegularActionMatcher(override val configuration: Configuration) : ActionMatcher { - private val matcher: Regex = pattern.toRegex(RegexOption.IGNORE_CASE) + private val matcher: Regex = configuration.getMatcherPattern().toRegex(RegexOption.IGNORE_CASE) override val type: String get() = RegularActionMatcherFactory.TYPE @@ -32,12 +34,12 @@ data class RegularActionMatcher(override val pattern: String) : ActionMatcher { } } -data class ReplaceableRegularActionMatcher(override val pattern: String) : ActionMatcher { +class ReplaceableRegularActionMatcher(override val configuration: Configuration) : ActionMatcher { override val type: String get() = RegularActionMatcherFactory.TYPE override fun match(request: Request, securityContext: SecurityContext): Boolean { - val pattern = ActionPatternReplacer.replace(pattern, securityContext) + val pattern = ActionPatternReplacer.replace(configuration.getMatcherPattern(), securityContext) return pattern.toRegex(RegexOption.IGNORE_CASE).matches(request.action) } } @@ -50,14 +52,15 @@ class RegularActionMatcherFactory : ActionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ActionMatcher { + override fun create(configuration: Configuration): ActionMatcher { + val pattern = configuration.getMatcherPattern() return if (ActionPatternReplacer.isTemplate(pattern)) { ReplaceableRegularActionMatcher( - pattern + configuration ) } else { RegularActionMatcher( - pattern + configuration ) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/AllConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/AllConditionMatcher.kt index 4d0e5e27..eee3930a 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/AllConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/AllConditionMatcher.kt @@ -13,16 +13,15 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher -object AllConditionMatcher : ConditionMatcher { +class AllConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = AllConditionMatcherFactory.TYPE - override val pattern: String - get() = "*" override fun match(request: Request, securityContext: SecurityContext): Boolean { return true @@ -37,7 +36,7 @@ class AllConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ConditionMatcher { - return AllConditionMatcher + override fun create(configuration: Configuration): ConditionMatcher { + return AllConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/AuthenticatedConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/AuthenticatedConditionMatcher.kt index 19b7a087..e9ac2cc9 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/AuthenticatedConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/AuthenticatedConditionMatcher.kt @@ -13,15 +13,14 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher -object AuthenticatedConditionMatcher : ConditionMatcher { +class AuthenticatedConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = AuthenticatedConditionMatcherFactory.TYPE - override val pattern: String - get() = "" override fun match(request: Request, securityContext: SecurityContext): Boolean { return securityContext.principal.authenticated() @@ -36,7 +35,7 @@ class AuthenticatedConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ConditionMatcher { - return AuthenticatedConditionMatcher + override fun create(configuration: Configuration): ConditionMatcher { + return AuthenticatedConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/ConditionMatcherFactory.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/ConditionMatcherFactory.kt index f08031fe..85918d53 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/ConditionMatcherFactory.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/ConditionMatcherFactory.kt @@ -13,9 +13,10 @@ package me.ahoo.cosec.policy.condition +import me.ahoo.cosec.api.configuration.Configuration import me.ahoo.cosec.api.policy.ConditionMatcher interface ConditionMatcherFactory { val type: String - fun create(pattern: String): ConditionMatcher + fun create(configuration: Configuration): ConditionMatcher } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InDefaultTenantConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InDefaultTenantConditionMatcher.kt index 55019fb4..61b99562 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InDefaultTenantConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InDefaultTenantConditionMatcher.kt @@ -13,15 +13,14 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher -object InDefaultTenantConditionMatcher : ConditionMatcher { +class InDefaultTenantConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = InDefaultTenantConditionMatcherFactory.TYPE - override val pattern: String - get() = "" override fun match(request: Request, securityContext: SecurityContext): Boolean { return securityContext.tenant.isDefaultTenant @@ -36,7 +35,7 @@ class InDefaultTenantConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ConditionMatcher { - return InDefaultTenantConditionMatcher + override fun create(configuration: Configuration): ConditionMatcher { + return InDefaultTenantConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InIpConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InIpConditionMatcher.kt index b47380a7..3dd7d6c9 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InIpConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InIpConditionMatcher.kt @@ -13,15 +13,17 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher import me.ahoo.cosec.context.request.XForwardedRemoteIpResolver +import me.ahoo.cosec.policy.getMatcherPattern -data class InIpConditionMatcher(override val pattern: String) : ConditionMatcher { +class InIpConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = InIpConditionMatcherFactory.TYPE - val ips: Set = pattern + val ips: Set = configuration.getMatcherPattern() .split(XForwardedRemoteIpResolver.DELIMITER) .dropWhile { it.isBlank() } .toSet() @@ -42,7 +44,7 @@ class InIpConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ConditionMatcher { - return InIpConditionMatcher(pattern) + override fun create(configuration: Configuration): ConditionMatcher { + return InDefaultTenantConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InPlatformTenantConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InPlatformTenantConditionMatcher.kt index ae57f9c5..a70d1d87 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InPlatformTenantConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InPlatformTenantConditionMatcher.kt @@ -13,15 +13,14 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher -object InPlatformTenantConditionMatcher : ConditionMatcher { +class InPlatformTenantConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = InPlatformTenantConditionMatcherFactory.TYPE - override val pattern: String - get() = "" override fun match(request: Request, securityContext: SecurityContext): Boolean { return securityContext.tenant.isPlatformTenant @@ -36,7 +35,7 @@ class InPlatformTenantConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ConditionMatcher { - return InPlatformTenantConditionMatcher + override fun create(configuration: Configuration): ConditionMatcher { + return InPlatformTenantConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InUserTenantConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InUserTenantConditionMatcher.kt index 044530a5..0ad024a9 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InUserTenantConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/InUserTenantConditionMatcher.kt @@ -13,15 +13,14 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher -object InUserTenantConditionMatcher : ConditionMatcher { +class InUserTenantConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = InUserTenantConditionMatcherFactory.TYPE - override val pattern: String - get() = "" override fun match(request: Request, securityContext: SecurityContext): Boolean { return securityContext.tenant.isUserTenant @@ -36,7 +35,7 @@ class InUserTenantConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ConditionMatcher { - return InUserTenantConditionMatcher + override fun create(configuration: Configuration): ConditionMatcher { + return InUserTenantConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/NoneConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/NoneConditionMatcher.kt index 147766e4..625852a4 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/NoneConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/NoneConditionMatcher.kt @@ -13,15 +13,14 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher -object NoneConditionMatcher : ConditionMatcher { +class NoneConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = NoneConditionMatcherFactory.TYPE - override val pattern: String - get() = "!" override fun match(request: Request, securityContext: SecurityContext): Boolean { return false @@ -36,7 +35,7 @@ class NoneConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ConditionMatcher { - return NoneConditionMatcher + override fun create(configuration: Configuration): ConditionMatcher { + return NoneConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/OgnlConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/OgnlConditionMatcher.kt index 26c2aaad..fb503843 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/OgnlConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/OgnlConditionMatcher.kt @@ -13,15 +13,17 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher +import me.ahoo.cosec.policy.getMatcherPattern import ognl.Ognl -data class OgnlConditionMatcher(override val pattern: String) : ConditionMatcher { +class OgnlConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = OgnlConditionMatcherFactory.TYPE - private val ognlExpression = Ognl.parseExpression(pattern) + private val ognlExpression = Ognl.parseExpression(configuration.getMatcherPattern()) override fun match(request: Request, securityContext: SecurityContext): Boolean { val ognlContext = mapOf( "request" to request, @@ -39,7 +41,7 @@ class OgnlConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = "ognl" - override fun create(pattern: String): ConditionMatcher { - return OgnlConditionMatcher(pattern) + override fun create(configuration: Configuration): ConditionMatcher { + return OgnlConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/RegularIpConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/RegularIpConditionMatcher.kt index 7d774fed..f39cab01 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/RegularIpConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/RegularIpConditionMatcher.kt @@ -13,14 +13,16 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher +import me.ahoo.cosec.policy.getMatcherPattern -data class RegularIpConditionMatcher(override val pattern: String) : ConditionMatcher { +class RegularIpConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = RegularIpConditionMatcherFactory.TYPE - private val matcher: Regex = pattern.toRegex(RegexOption.IGNORE_CASE) + private val matcher: Regex = configuration.getMatcherPattern().toRegex(RegexOption.IGNORE_CASE) override fun match(request: Request, securityContext: SecurityContext): Boolean { if (request.remoteIp.isEmpty()) { @@ -38,7 +40,7 @@ class RegularIpConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ConditionMatcher { - return RegularIpConditionMatcher(pattern) + override fun create(configuration: Configuration): ConditionMatcher { + return RegularIpConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/RequestPart.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/RequestPart.kt new file mode 100644 index 00000000..1eddd6d8 --- /dev/null +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/RequestPart.kt @@ -0,0 +1,22 @@ +/* + * Copyright [2021-present] [ahoo wang (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.condition + +object RequestPart { + const val ACTION = "action" + const val REMOTE_IP = "remoteIp" + const val ORIGIN = "origin" + const val REFERER = "referer" + const val TENANT_ID = "tenantId" +} diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/SpelConditionMatcher.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/SpelConditionMatcher.kt index 426732ed..5c0e41d6 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/SpelConditionMatcher.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/SpelConditionMatcher.kt @@ -13,22 +13,24 @@ package me.ahoo.cosec.policy.condition +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.ConditionMatcher import me.ahoo.cosec.policy.action.SPEL_PARSER +import me.ahoo.cosec.policy.getMatcherPattern import org.springframework.expression.Expression -data class SpelConditionMatcher(override val pattern: String) : ConditionMatcher { +class SpelConditionMatcher(override val configuration: Configuration) : ConditionMatcher { override val type: String get() = SpelConditionMatcherFactory.TYPE - private val expression: Expression = SPEL_PARSER.parseExpression(pattern) + private val expression: Expression = SPEL_PARSER.parseExpression(configuration.getMatcherPattern()) override fun match(request: Request, securityContext: SecurityContext): Boolean { val root = Root(request, context = securityContext) - return expression.getValue(root, Boolean::class.java)!! + return expression.getValue(root, Boolean::class.java) ?: false } data class Root( @@ -45,7 +47,7 @@ class SpelConditionMatcherFactory : ConditionMatcherFactory { override val type: String get() = TYPE - override fun create(pattern: String): ConditionMatcher { - return SpelConditionMatcher(pattern) + override fun create(configuration: Configuration): ConditionMatcher { + return SpelConditionMatcher(configuration) } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/CoSecJsonSerializer.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/CoSecJsonSerializer.kt similarity index 96% rename from cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/CoSecJsonSerializer.kt rename to cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/CoSecJsonSerializer.kt index 078cc883..c0abb259 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/CoSecJsonSerializer.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/CoSecJsonSerializer.kt @@ -11,7 +11,7 @@ * limitations under the License. */ -package me.ahoo.cosec.policy.serialization +package me.ahoo.cosec.serialization import com.fasterxml.jackson.annotation.JsonAutoDetect import com.fasterxml.jackson.annotation.PropertyAccessor diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/CoSecModule.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/CoSecModule.kt similarity index 88% rename from cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/CoSecModule.kt rename to cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/CoSecModule.kt index 766a6c39..2edfbeb3 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/CoSecModule.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/CoSecModule.kt @@ -11,7 +11,7 @@ * limitations under the License. */ -package me.ahoo.cosec.policy.serialization +package me.ahoo.cosec.serialization import com.fasterxml.jackson.databind.module.SimpleModule import me.ahoo.cosec.api.policy.ActionMatcher @@ -20,6 +20,7 @@ import me.ahoo.cosec.api.policy.Effect import me.ahoo.cosec.api.policy.Policy import me.ahoo.cosec.api.policy.PolicyType import me.ahoo.cosec.api.policy.Statement +import me.ahoo.cosec.configuration.JsonConfiguration class CoSecModule : SimpleModule() { init { @@ -35,8 +36,7 @@ class CoSecModule : SimpleModule() { addDeserializer(PolicyType::class.java, JsonPolicyTypeDeserializer) addSerializer(Policy::class.java, JsonPolicySerializer) addDeserializer(Policy::class.java, JsonPolicyDeserializer) + addSerializer(JsonConfiguration::class.java, JsonConfigurationSerializer) + addDeserializer(JsonConfiguration::class.java, JsonConfigurationDeserializer) } } - -const val MATCHER_TYPE_KEY = "type" -const val MATCHER_PATTERN_KEY = "pattern" diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonActionMatcherSerializer.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonActionMatcherSerializer.kt similarity index 65% rename from cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonActionMatcherSerializer.kt rename to cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonActionMatcherSerializer.kt index 295d98d4..efe5e31a 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonActionMatcherSerializer.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonActionMatcherSerializer.kt @@ -11,41 +11,29 @@ * limitations under the License. */ -package me.ahoo.cosec.policy.serialization +package me.ahoo.cosec.serialization import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.SerializerProvider import com.fasterxml.jackson.databind.deser.std.StdDeserializer import com.fasterxml.jackson.databind.ser.std.StdSerializer import me.ahoo.cosec.api.policy.ActionMatcher +import me.ahoo.cosec.configuration.JsonConfiguration import me.ahoo.cosec.policy.action.ActionMatcherFactoryProvider +import me.ahoo.cosec.policy.getMatcherType object JsonActionMatcherSerializer : StdSerializer(ActionMatcher::class.java) { override fun serialize(value: ActionMatcher, gen: JsonGenerator, provider: SerializerProvider) { - gen.writeStartObject() - gen.writeStringField(MATCHER_TYPE_KEY, value.type) - if (value != value::class.objectInstance) { - gen.writeStringField(MATCHER_PATTERN_KEY, value.pattern) - } - gen.writeEndObject() + gen.writePOJO(value.configuration) } } object JsonActionMatcherDeserializer : StdDeserializer(ActionMatcher::class.java) { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): ActionMatcher { - return p.codec.readTree(p).let { - val type = requireNotNull(it.get(MATCHER_TYPE_KEY).asText()) - val pattern = it.has(MATCHER_PATTERN_KEY).let { hasPattern -> - if (hasPattern) { - it.get(MATCHER_PATTERN_KEY).asText() - } else { - "" - } - } - ActionMatcherFactoryProvider.getRequired(type).create(pattern) + return p.codec.readValue(p, JsonConfiguration::class.java).let { + ActionMatcherFactoryProvider.getRequired(it.getMatcherType()).create(it) } } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonConditionMatcherSerializer.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonConditionMatcherSerializer.kt similarity index 66% rename from cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonConditionMatcherSerializer.kt rename to cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonConditionMatcherSerializer.kt index f0f45e69..6e03bc60 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonConditionMatcherSerializer.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonConditionMatcherSerializer.kt @@ -11,41 +11,29 @@ * limitations under the License. */ -package me.ahoo.cosec.policy.serialization +package me.ahoo.cosec.serialization import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.SerializerProvider import com.fasterxml.jackson.databind.deser.std.StdDeserializer import com.fasterxml.jackson.databind.ser.std.StdSerializer import me.ahoo.cosec.api.policy.ConditionMatcher +import me.ahoo.cosec.configuration.JsonConfiguration import me.ahoo.cosec.policy.condition.ConditionMatcherFactoryProvider +import me.ahoo.cosec.policy.getMatcherType object JsonConditionMatcherSerializer : StdSerializer(ConditionMatcher::class.java) { override fun serialize(value: ConditionMatcher, gen: JsonGenerator, provider: SerializerProvider) { - gen.writeStartObject() - gen.writeStringField(MATCHER_TYPE_KEY, value.type) - if (value != value::class.objectInstance) { - gen.writeStringField(MATCHER_PATTERN_KEY, value.pattern) - } - gen.writeEndObject() + gen.writePOJO(value.configuration) } } object JsonConditionMatcherDeserializer : StdDeserializer(ConditionMatcher::class.java) { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): ConditionMatcher { - return p.codec.readTree(p).let { - val type = requireNotNull(it.get(MATCHER_TYPE_KEY).asText()) - val pattern = it.has(MATCHER_PATTERN_KEY).let { hasPattern -> - if (hasPattern) { - it.get(MATCHER_PATTERN_KEY).asText() - } else { - "" - } - } - ConditionMatcherFactoryProvider.getRequired(type).create(pattern) + return p.codec.readValue(p, JsonConfiguration::class.java).let { + ConditionMatcherFactoryProvider.getRequired(it.getMatcherType()).create(it) } } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonConfigurationSerializer.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonConfigurationSerializer.kt new file mode 100644 index 00000000..7f042e72 --- /dev/null +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonConfigurationSerializer.kt @@ -0,0 +1,34 @@ +/* + * Copyright [2021-present] [ahoo wang (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.serialization + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.fasterxml.jackson.databind.ser.std.StdSerializer +import me.ahoo.cosec.configuration.JsonConfiguration + +object JsonConfigurationSerializer : StdSerializer(JsonConfiguration::class.java) { + override fun serialize(value: JsonConfiguration, gen: JsonGenerator, provider: SerializerProvider) { + gen.writeTree(value.delegate) + } +} + +object JsonConfigurationDeserializer : StdDeserializer(JsonConfiguration::class.java) { + override fun deserialize(p: JsonParser, ctxt: DeserializationContext): JsonConfiguration { + return JsonConfiguration(p.readValueAsTree(), p.codec) + } +} diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonEffectSerializer.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonEffectSerializer.kt similarity index 97% rename from cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonEffectSerializer.kt rename to cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonEffectSerializer.kt index 6969e809..de5b289b 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonEffectSerializer.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonEffectSerializer.kt @@ -11,7 +11,7 @@ * limitations under the License. */ -package me.ahoo.cosec.policy.serialization +package me.ahoo.cosec.serialization import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonPolicySerializer.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonPolicySerializer.kt similarity index 98% rename from cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonPolicySerializer.kt rename to cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonPolicySerializer.kt index a979e17b..32350edf 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonPolicySerializer.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonPolicySerializer.kt @@ -11,7 +11,7 @@ * limitations under the License. */ -package me.ahoo.cosec.policy.serialization +package me.ahoo.cosec.serialization import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonPolicyTypeSerializer.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonPolicyTypeSerializer.kt similarity index 97% rename from cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonPolicyTypeSerializer.kt rename to cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonPolicyTypeSerializer.kt index be34c51b..7f68fcd2 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonPolicyTypeSerializer.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonPolicyTypeSerializer.kt @@ -11,7 +11,7 @@ * limitations under the License. */ -package me.ahoo.cosec.policy.serialization +package me.ahoo.cosec.serialization import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonStatementSerializer.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonStatementSerializer.kt similarity index 98% rename from cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonStatementSerializer.kt rename to cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonStatementSerializer.kt index 5fe3040b..1b9f464f 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/policy/serialization/JsonStatementSerializer.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/serialization/JsonStatementSerializer.kt @@ -11,7 +11,7 @@ * limitations under the License. */ -package me.ahoo.cosec.policy.serialization +package me.ahoo.cosec.serialization import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/authorization/SimpleAuthorizationTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/authorization/SimpleAuthorizationTest.kt index 7efe72e1..4089112f 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/authorization/SimpleAuthorizationTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/authorization/SimpleAuthorizationTest.kt @@ -21,6 +21,7 @@ import me.ahoo.cosec.api.context.request.Request import me.ahoo.cosec.api.policy.Effect import me.ahoo.cosec.api.policy.Policy import me.ahoo.cosec.api.principal.CoSecPrincipal +import me.ahoo.cosec.configuration.JsonConfiguration import me.ahoo.cosec.context.SimpleSecurityContext import me.ahoo.cosec.policy.StatementData import me.ahoo.cosec.policy.action.AllActionMatcher @@ -111,7 +112,7 @@ internal class SimpleAuthorizationTest { every { statements } returns setOf( StatementData( effect = Effect.ALLOW, - actions = setOf(AllActionMatcher) + actions = setOf(AllActionMatcher(JsonConfiguration.EMPTY)) ) ) } @@ -137,7 +138,7 @@ internal class SimpleAuthorizationTest { every { statements } returns setOf( StatementData( effect = Effect.DENY, - actions = setOf(AllActionMatcher) + actions = setOf(AllActionMatcher(JsonConfiguration.EMPTY)) ) ) } @@ -161,7 +162,7 @@ internal class SimpleAuthorizationTest { every { statements } returns setOf( StatementData( effect = Effect.ALLOW, - actions = setOf(AllActionMatcher) + actions = setOf(AllActionMatcher(JsonConfiguration.EMPTY)) ) ) } @@ -192,7 +193,7 @@ internal class SimpleAuthorizationTest { every { statements } returns setOf( StatementData( effect = Effect.DENY, - actions = setOf(AllActionMatcher) + actions = setOf(AllActionMatcher(JsonConfiguration.EMPTY)) ) ) } @@ -223,7 +224,7 @@ internal class SimpleAuthorizationTest { every { statements } returns setOf( StatementData( effect = Effect.ALLOW, - actions = setOf(AllActionMatcher) + actions = setOf(AllActionMatcher(JsonConfiguration.EMPTY)) ) ) } @@ -255,7 +256,7 @@ internal class SimpleAuthorizationTest { every { statements } returns setOf( StatementData( effect = Effect.DENY, - actions = setOf(AllActionMatcher) + actions = setOf(AllActionMatcher(JsonConfiguration.EMPTY)) ) ) } diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/context/request/XForwardedRemoteIpResolverTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/context/request/XForwardedRemoteIpResolverTest.kt index 942c8340..e922ffc4 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/context/request/XForwardedRemoteIpResolverTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/context/request/XForwardedRemoteIpResolverTest.kt @@ -17,7 +17,6 @@ import io.mockk.mockk import me.ahoo.cosec.api.context.request.Request import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* - import org.junit.jupiter.api.Test class XForwardedRemoteIpResolverTest { @@ -62,4 +61,4 @@ class XForwardedRemoteIpResolverTest { } assertThat(xForwardedRemoteIpResolver.resolve(mockk()), `is`("ipAddress0")) } -} \ No newline at end of file +} diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/DefaultPolicyEvaluatorTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/DefaultPolicyEvaluatorTest.kt index ab089d1c..6c0cd0a7 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/DefaultPolicyEvaluatorTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/DefaultPolicyEvaluatorTest.kt @@ -21,7 +21,7 @@ import org.junit.jupiter.params.provider.MethodSource internal class DefaultPolicyEvaluatorTest { @ParameterizedTest - @MethodSource("me.ahoo.cosec.policy.serialization.CoSecJsonSerializerTest#serializePolicyProvider") + @MethodSource("me.ahoo.cosec.serialization.CoSecJsonSerializerTest#serializePolicyProvider") fun evaluate(policy: Policy) { DefaultPolicyEvaluator.evaluate(policy) } diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/StatementDataTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/StatementDataTest.kt index 902aa8cc..4a5a4fea 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/StatementDataTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/StatementDataTest.kt @@ -19,6 +19,8 @@ import me.ahoo.cosec.api.context.SecurityContext import me.ahoo.cosec.api.context.request.Request import me.ahoo.cosec.api.policy.Effect import me.ahoo.cosec.api.policy.VerifyResult +import me.ahoo.cosec.configuration.JsonConfiguration +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration import me.ahoo.cosec.policy.action.AllActionMatcher import me.ahoo.cosec.policy.action.PathActionMatcherFactory import me.ahoo.cosec.policy.condition.SpelConditionMatcherFactory @@ -36,7 +38,15 @@ internal class StatementDataTest { @Test fun verify() { - val statementData = StatementData(actions = setOf(PathActionMatcherFactory().create("auth/*"))) + val statementData = StatementData( + actions = setOf( + PathActionMatcherFactory().create( + mapOf( + MATCHER_PATTERN_KEY to "auth/*" + ).asConfiguration() + ) + ) + ) val request = mockk { every { action } returns "auth/login:POST" } @@ -46,8 +56,20 @@ internal class StatementDataTest { @Test fun verifyWithCondition() { val statementData = StatementData( - actions = setOf(PathActionMatcherFactory().create("order/#{principal.id}/*")), - conditions = setOf(SpelConditionMatcherFactory().create("context.principal.authenticated()")) + actions = setOf( + PathActionMatcherFactory().create( + mapOf( + MATCHER_PATTERN_KEY to "order/#{principal.id}/*" + ).asConfiguration() + ) + ), + conditions = setOf( + SpelConditionMatcherFactory().create( + mapOf( + MATCHER_PATTERN_KEY to "context.principal.authenticated()" + ).asConfiguration() + ) + ) ) val request = mockk { every { action } returns "order/1/search:POST" @@ -73,7 +95,7 @@ internal class StatementDataTest { fun verifyDeny() { val statementData = StatementData( effect = Effect.DENY, - actions = setOf(AllActionMatcher) + actions = setOf(AllActionMatcher(JsonConfiguration.EMPTY)) ) assertThat(statementData.verify(mockk(), mockk()), `is`(VerifyResult.EXPLICIT_DENY)) } diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/AllActionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/AllActionMatcherTest.kt index 647ba664..63cd67b6 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/AllActionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/AllActionMatcherTest.kt @@ -14,6 +14,7 @@ package me.ahoo.cosec.policy.action import io.mockk.mockk +import me.ahoo.cosec.configuration.JsonConfiguration import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Test @@ -21,8 +22,9 @@ import org.junit.jupiter.api.Test internal class AllActionMatcherTest { @Test fun match() { - assertThat(AllActionMatcher.type, `is`(AllActionMatcherFactory.TYPE)) - assertThat(AllActionMatcher.pattern, `is`("*")) - assertThat(AllActionMatcher.match(mockk(), mockk()), `is`(true)) + val allActionMatcher = AllActionMatcher(JsonConfiguration.EMPTY) + assertThat(allActionMatcher.type, `is`(AllActionMatcherFactory.TYPE)) + assertThat(allActionMatcher.configuration, `is`(JsonConfiguration.EMPTY)) + assertThat(allActionMatcher.match(mockk(), mockk()), `is`(true)) } } diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/NoneActionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/NoneActionMatcherTest.kt index fe2ab25b..ab8b4091 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/NoneActionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/NoneActionMatcherTest.kt @@ -14,6 +14,7 @@ package me.ahoo.cosec.policy.action import io.mockk.mockk +import me.ahoo.cosec.configuration.JsonConfiguration import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Test @@ -22,8 +23,9 @@ internal class NoneActionMatcherTest { @Test fun match() { - assertThat(NoneActionMatcher.type, `is`(NoneActionMatcherFactory.TYPE)) - assertThat(NoneActionMatcher.pattern, `is`("!")) - assertThat(NoneActionMatcher.match(mockk(), mockk()), `is`(false)) + val actionMatcher = NoneActionMatcher(JsonConfiguration.EMPTY) + assertThat(actionMatcher.type, `is`(NoneActionMatcherFactory.TYPE)) + assertThat(actionMatcher.configuration, `is`(JsonConfiguration.EMPTY)) + assertThat(actionMatcher.match(mockk(), mockk()), `is`(false)) } } diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/PathActionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/PathActionMatcherTest.kt index d5316d08..8fdfe845 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/PathActionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/PathActionMatcherTest.kt @@ -16,6 +16,8 @@ package me.ahoo.cosec.policy.action import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.request.Request +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration +import me.ahoo.cosec.policy.MATCHER_PATTERN_KEY import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Test @@ -24,7 +26,7 @@ internal class PathActionMatcherTest { @Test fun match() { - val actionMatcher = PathActionMatcher("auth/*:POST") + val actionMatcher = PathActionMatcher(mapOf(MATCHER_PATTERN_KEY to "auth/*:POST").asConfiguration()) val request = mockk { every { action } returns "auth/login:POST" } diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/RegularActionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/RegularActionMatcherTest.kt index b182852a..0f4edc02 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/RegularActionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/RegularActionMatcherTest.kt @@ -16,6 +16,8 @@ package me.ahoo.cosec.policy.action import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.request.Request +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration +import me.ahoo.cosec.policy.MATCHER_PATTERN_KEY import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.jupiter.params.ParameterizedTest @@ -28,7 +30,7 @@ internal class RegularActionMatcherTest { @ParameterizedTest @MethodSource("parameters") fun match(pattern: String, actions: List, expected: Boolean) { - val actionMatcher = RegularActionMatcher(pattern) + val actionMatcher = RegularActionMatcher(mapOf(MATCHER_PATTERN_KEY to pattern).asConfiguration()) actions.forEach { val request = mockk { every { action } returns it diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/ReplaceablePathActionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/ReplaceablePathActionMatcherTest.kt index 9e67f369..e8afa206 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/ReplaceablePathActionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/ReplaceablePathActionMatcherTest.kt @@ -17,6 +17,8 @@ import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.SecurityContext import me.ahoo.cosec.api.context.request.Request +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration +import me.ahoo.cosec.policy.MATCHER_PATTERN_KEY import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.jupiter.api.Test @@ -31,7 +33,8 @@ internal class ReplaceablePathActionMatcherTest { } } - val actionMatcher = ReplaceablePathActionMatcher("order/#{principal.id}/*") + val actionMatcher = + ReplaceablePathActionMatcher(mapOf(MATCHER_PATTERN_KEY to "order/#{principal.id}/*").asConfiguration()) val request1 = mockk() { every { action diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/ReplaceableRegularActionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/ReplaceableRegularActionMatcherTest.kt index debcf476..12b108aa 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/ReplaceableRegularActionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/action/ReplaceableRegularActionMatcherTest.kt @@ -17,6 +17,8 @@ import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.SecurityContext import me.ahoo.cosec.api.context.request.Request +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration +import me.ahoo.cosec.policy.MATCHER_PATTERN_KEY import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.jupiter.api.Test @@ -31,7 +33,8 @@ internal class ReplaceableRegularActionMatcherTest { } } - val replaceableRegularActionMatcher = ReplaceableRegularActionMatcher("order/#{principal.id}/1") + val replaceableRegularActionMatcher = + ReplaceableRegularActionMatcher(mapOf(MATCHER_PATTERN_KEY to "order/#{principal.id}/1").asConfiguration()) val request1 = mockk() { every { action diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/AllConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/AllConditionMatcherTest.kt index 1706e107..c8e495f9 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/AllConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/AllConditionMatcherTest.kt @@ -14,6 +14,7 @@ package me.ahoo.cosec.policy.condition import io.mockk.mockk +import me.ahoo.cosec.configuration.JsonConfiguration import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Test @@ -22,8 +23,9 @@ internal class AllConditionMatcherTest { @Test fun match() { - assertThat(AllConditionMatcher.type, `is`(AllConditionMatcherFactory.TYPE)) - assertThat(AllConditionMatcher.pattern, `is`("*")) - assertThat(AllConditionMatcher.match(mockk(), mockk()), `is`(true)) + val conditionMatcher = AllConditionMatcher(JsonConfiguration.EMPTY) + assertThat(conditionMatcher.type, `is`(AllConditionMatcherFactory.TYPE)) + assertThat(conditionMatcher.configuration, `is`(JsonConfiguration.EMPTY)) + assertThat(conditionMatcher.match(mockk(), mockk()), `is`(true)) } } diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/AuthenticatedConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/AuthenticatedConditionMatcherTest.kt index 385df253..58a3c504 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/AuthenticatedConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/AuthenticatedConditionMatcherTest.kt @@ -17,6 +17,7 @@ import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.SecurityContext import me.ahoo.cosec.api.context.request.Request +import me.ahoo.cosec.configuration.JsonConfiguration import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Test @@ -28,8 +29,9 @@ class AuthenticatedConditionMatcherTest { val context: SecurityContext = mockk() { every { principal.authenticated() } returns true } - assertThat(AuthenticatedConditionMatcher.type, `is`(AuthenticatedConditionMatcherFactory.TYPE)) - assertThat(AuthenticatedConditionMatcher.pattern, `is`("")) - assertThat(AuthenticatedConditionMatcher.match(request, context), `is`(true)) + val conditionMatcher = AuthenticatedConditionMatcher(JsonConfiguration.EMPTY) + assertThat(conditionMatcher.type, `is`(AuthenticatedConditionMatcherFactory.TYPE)) + assertThat(conditionMatcher.configuration, `is`(JsonConfiguration.EMPTY)) + assertThat(conditionMatcher.match(request, context), `is`(true)) } -} \ No newline at end of file +} diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InDefaultTenantConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InDefaultTenantConditionMatcherTest.kt index 0fd9d083..1baf79ed 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InDefaultTenantConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InDefaultTenantConditionMatcherTest.kt @@ -17,7 +17,7 @@ import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.SecurityContext import me.ahoo.cosec.api.context.request.Request -import org.junit.jupiter.api.Assertions.* +import me.ahoo.cosec.configuration.JsonConfiguration import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.jupiter.api.Test @@ -29,8 +29,9 @@ class InDefaultTenantConditionMatcherTest { val context: SecurityContext = mockk() { every { tenant.isDefaultTenant } returns true } - assertThat(InDefaultTenantConditionMatcher.type, `is`(InDefaultTenantConditionMatcherFactory.TYPE)) - assertThat(InDefaultTenantConditionMatcher.pattern, `is`("")) - assertThat(InDefaultTenantConditionMatcher.match(request, context), `is`(true)) + val conditionMatcher = InDefaultTenantConditionMatcher(JsonConfiguration.EMPTY) + assertThat(conditionMatcher.type, `is`(InDefaultTenantConditionMatcherFactory.TYPE)) + assertThat(conditionMatcher.configuration, `is`(JsonConfiguration.EMPTY)) + assertThat(conditionMatcher.match(request, context), `is`(true)) } -} \ No newline at end of file +} diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InIpConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InIpConditionMatcherTest.kt index 63d44413..0523383b 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InIpConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InIpConditionMatcherTest.kt @@ -16,13 +16,16 @@ package me.ahoo.cosec.policy.condition import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.request.Request -import me.ahoo.cosec.policy.condition.InIpConditionMatcher +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration +import me.ahoo.cosec.policy.MATCHER_PATTERN_KEY +import me.ahoo.cosec.policy.getMatcherPattern import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Test class InIpConditionMatcherTest { - private val conditionMatcher = InIpConditionMatcher("remoteIp,remoteIp1") + private val conditionMatcher = + InIpConditionMatcher(mapOf(MATCHER_PATTERN_KEY to "remoteIp,remoteIp1").asConfiguration()) @Test fun match() { @@ -30,7 +33,7 @@ class InIpConditionMatcherTest { every { remoteIp } returns "remoteIp" } assertThat(conditionMatcher.type, `is`(InIpConditionMatcherFactory.TYPE)) - assertThat(conditionMatcher.pattern, `is`("remoteIp,remoteIp1")) + assertThat(conditionMatcher.configuration.getMatcherPattern(), `is`("remoteIp,remoteIp1")) assertThat(conditionMatcher.ips, `is`(setOf("remoteIp", "remoteIp1"))) assertThat(conditionMatcher.match(request, mockk()), `is`(true)) } @@ -42,4 +45,4 @@ class InIpConditionMatcherTest { } assertThat(conditionMatcher.match(requestNotMatch, mockk()), `is`(false)) } -} \ No newline at end of file +} diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InPlatformTenantConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InPlatformTenantConditionMatcherTest.kt index c9b3f5d1..1fd26eb1 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InPlatformTenantConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InPlatformTenantConditionMatcherTest.kt @@ -17,7 +17,7 @@ import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.SecurityContext import me.ahoo.cosec.api.context.request.Request -import org.junit.jupiter.api.Assertions.* +import me.ahoo.cosec.configuration.JsonConfiguration import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.jupiter.api.Test @@ -29,8 +29,9 @@ class InPlatformTenantConditionMatcherTest { val context: SecurityContext = mockk { every { tenant.isPlatformTenant } returns true } - assertThat(InPlatformTenantConditionMatcher.type, `is`(InPlatformTenantConditionMatcherFactory.TYPE)) - assertThat(InPlatformTenantConditionMatcher.pattern, `is`("")) - assertThat(InPlatformTenantConditionMatcher.match(request, context), `is`(true)) + val conditionMatcher = InPlatformTenantConditionMatcher(JsonConfiguration.EMPTY) + assertThat(conditionMatcher.type, `is`(InPlatformTenantConditionMatcherFactory.TYPE)) + assertThat(conditionMatcher.configuration, `is`(JsonConfiguration.EMPTY)) + assertThat(conditionMatcher.match(request, context), `is`(true)) } -} \ No newline at end of file +} diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InUserTenantConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InUserTenantConditionMatcherTest.kt index c6afc493..d40b856f 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InUserTenantConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/InUserTenantConditionMatcherTest.kt @@ -17,7 +17,7 @@ import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.SecurityContext import me.ahoo.cosec.api.context.request.Request -import org.junit.jupiter.api.Assertions.* +import me.ahoo.cosec.configuration.JsonConfiguration import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.jupiter.api.Test @@ -29,8 +29,9 @@ class InUserTenantConditionMatcherTest { val context: SecurityContext = mockk { every { tenant.isUserTenant } returns true } - assertThat(InUserTenantConditionMatcher.type, `is`(InUserTenantConditionMatcherFactory.TYPE)) - assertThat(InUserTenantConditionMatcher.pattern, `is`("")) - assertThat(InUserTenantConditionMatcher.match(request, context), `is`(true)) + val conditionMatcher = InUserTenantConditionMatcher(JsonConfiguration.EMPTY) + assertThat(conditionMatcher.type, `is`(InUserTenantConditionMatcherFactory.TYPE)) + assertThat(conditionMatcher.configuration, `is`(JsonConfiguration.EMPTY)) + assertThat(conditionMatcher.match(request, context), `is`(true)) } -} \ No newline at end of file +} diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/NoneConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/NoneConditionMatcherTest.kt index 6d796cdd..f1313e63 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/NoneConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/NoneConditionMatcherTest.kt @@ -14,6 +14,7 @@ package me.ahoo.cosec.policy.condition import io.mockk.mockk +import me.ahoo.cosec.configuration.JsonConfiguration import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Test @@ -22,8 +23,9 @@ internal class NoneConditionMatcherTest { @Test fun match() { - assertThat(NoneConditionMatcher.type, `is`(NoneConditionMatcherFactory.TYPE)) - assertThat(NoneConditionMatcher.pattern, `is`("!")) - assertThat(NoneConditionMatcher.match(mockk(), mockk()), `is`(false)) + val conditionMatcher = NoneConditionMatcher(JsonConfiguration.EMPTY) + assertThat(conditionMatcher.type, `is`(NoneConditionMatcherFactory.TYPE)) + assertThat(conditionMatcher.configuration, `is`(JsonConfiguration.EMPTY)) + assertThat(conditionMatcher.match(mockk(), mockk()), `is`(false)) } } diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/OgnlConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/OgnlConditionMatcherTest.kt index df06fa2e..c62e7ed1 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/OgnlConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/OgnlConditionMatcherTest.kt @@ -17,6 +17,8 @@ import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.SecurityContext import me.ahoo.cosec.api.context.request.Request +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration +import me.ahoo.cosec.policy.MATCHER_PATTERN_KEY import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.* import org.junit.jupiter.params.ParameterizedTest @@ -29,7 +31,7 @@ internal class OgnlConditionMatcherTest { @ParameterizedTest @MethodSource("parametersForActions") fun matchRequest(expression: String, actions: List, expected: Boolean) { - val conditionMatcher = OgnlConditionMatcher(expression) + val conditionMatcher = OgnlConditionMatcher(mapOf(MATCHER_PATTERN_KEY to expression).asConfiguration()) actions.forEach { val request = mockk { every { action } returns it @@ -41,7 +43,7 @@ internal class OgnlConditionMatcherTest { @ParameterizedTest @MethodSource("parametersForContext") fun matchContext(expression: String, principalIds: List, expected: Boolean) { - val conditionMatcher = OgnlConditionMatcher(expression) + val conditionMatcher = OgnlConditionMatcher(mapOf(MATCHER_PATTERN_KEY to expression).asConfiguration()) principalIds.forEach { val context = mockk { every { principal } returns mockk { diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/RegularIpConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/RegularIpConditionMatcherTest.kt index d2090691..5fb3261e 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/RegularIpConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/RegularIpConditionMatcherTest.kt @@ -16,13 +16,15 @@ package me.ahoo.cosec.policy.condition import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.request.Request -import me.ahoo.cosec.policy.condition.RegularIpConditionMatcher +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration +import me.ahoo.cosec.policy.MATCHER_PATTERN_KEY import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Test class RegularIpConditionMatcherTest { - private val conditionMatcher = RegularIpConditionMatcher("192\\.168\\.0\\.[0-9]*") + private val conditionMatcher = + RegularIpConditionMatcher(mapOf(MATCHER_PATTERN_KEY to "192\\.168\\.0\\.[0-9]*").asConfiguration()) @Test fun matchWhenRemoteIpIsNull() { @@ -47,4 +49,4 @@ class RegularIpConditionMatcherTest { } assertThat(conditionMatcher.match(requestNotMatch, mockk()), `is`(false)) } -} \ No newline at end of file +} diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/SpelConditionMatcherTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/SpelConditionMatcherTest.kt index d274e49d..e7a91dd3 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/SpelConditionMatcherTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/condition/SpelConditionMatcherTest.kt @@ -16,6 +16,8 @@ package me.ahoo.cosec.policy.condition import io.mockk.every import io.mockk.mockk import me.ahoo.cosec.api.context.SecurityContext +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration +import me.ahoo.cosec.policy.MATCHER_PATTERN_KEY import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` import org.junit.jupiter.api.Test @@ -23,13 +25,14 @@ import org.junit.jupiter.api.Test internal class SpelConditionMatcherTest { @Test fun simpleMatch() { - val conditionMatcher = SpelConditionMatcher("1==1") + val conditionMatcher = SpelConditionMatcher(mapOf(MATCHER_PATTERN_KEY to "1==1").asConfiguration()) assertThat(conditionMatcher.match(mockk(), mockk()), `is`(true)) } @Test fun match() { - val conditionMatcher = SpelConditionMatcher("context.principal.id=='1'") + val conditionMatcher = + SpelConditionMatcher(mapOf(MATCHER_PATTERN_KEY to "context.principal.id=='1'").asConfiguration()) val securityContext = mockk() { every { principal } returns mockk { every { id } returns "1" diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/serialization/CoSecJsonSerializerTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/serialization/CoSecJsonSerializerTest.kt similarity index 63% rename from cosec-core/src/test/kotlin/me/ahoo/cosec/policy/serialization/CoSecJsonSerializerTest.kt rename to cosec-core/src/test/kotlin/me/ahoo/cosec/serialization/CoSecJsonSerializerTest.kt index ba519ab2..5ff91200 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/policy/serialization/CoSecJsonSerializerTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/serialization/CoSecJsonSerializerTest.kt @@ -11,7 +11,7 @@ * limitations under the License. */ -package me.ahoo.cosec.policy.serialization +package me.ahoo.cosec.serialization import com.fasterxml.jackson.core.type.TypeReference import me.ahoo.cosec.api.policy.ActionMatcher @@ -20,6 +20,9 @@ import me.ahoo.cosec.api.policy.Effect import me.ahoo.cosec.api.policy.Policy import me.ahoo.cosec.api.policy.PolicyType import me.ahoo.cosec.api.policy.Statement +import me.ahoo.cosec.configuration.JsonConfiguration.Companion.asConfiguration +import me.ahoo.cosec.policy.MATCHER_PATTERN_KEY +import me.ahoo.cosec.policy.MATCHER_TYPE_KEY import me.ahoo.cosec.policy.PolicyData import me.ahoo.cosec.policy.StatementData import me.ahoo.cosec.policy.action.AllActionMatcherFactory @@ -54,7 +57,7 @@ internal class CoSecJsonSerializerTest { output, ActionMatcher::class.java ) - assertThat(input, `is`(actionMatcher)) + assertThat(input, instanceOf(actionMatcher.javaClass)) } @ParameterizedTest @@ -65,7 +68,7 @@ internal class CoSecJsonSerializerTest { output, ConditionMatcher::class.java ) - assertThat(input, `is`(conditionMatcher)) + assertThat(input, instanceOf(conditionMatcher.javaClass)) } @ParameterizedTest @@ -76,7 +79,7 @@ internal class CoSecJsonSerializerTest { output, Statement::class.java ) - assertThat(input, `is`(statement)) + assertThat(input, instanceOf(statement.javaClass)) } @ParameterizedTest @@ -87,7 +90,7 @@ internal class CoSecJsonSerializerTest { output, Policy::class.java ) - assertThat(input, `is`(policy)) + assertThat(input, instanceOf(policy.javaClass)) } @Test @@ -99,7 +102,8 @@ internal class CoSecJsonSerializerTest { output, policySetType ) - assertThat(input, `is`(input)) + assertThat(input, instanceOf(input.javaClass)) + assertThat(input, hasSize(input.size)) } @Test @@ -121,7 +125,7 @@ internal class CoSecJsonSerializerTest { output, PolicyType::class.java ) - assertThat(input, `is`(input)) + assertThat(input, sameInstance(input)) } @Test @@ -132,35 +136,75 @@ internal class CoSecJsonSerializerTest { output, WithPolicyType::class.java ) - assertThat(input, `is`(input)) + assertThat(input, sameInstance(input)) } companion object { @JvmStatic fun serializeActionMatcherProvider(): Stream { return Stream.of( - AllActionMatcherFactory().create(""), - NoneActionMatcherFactory().create(""), - PathActionMatcherFactory().create(".*"), - PathActionMatcherFactory().create("#{principal.id}.*"), - RegularActionMatcherFactory().create(".*"), - RegularActionMatcherFactory().create("#{principal.id}.*") + AllActionMatcherFactory().create(mapOf(MATCHER_TYPE_KEY to AllActionMatcherFactory.TYPE).asConfiguration()), + NoneActionMatcherFactory().create(mapOf(MATCHER_TYPE_KEY to NoneActionMatcherFactory.TYPE).asConfiguration()), + PathActionMatcherFactory().create( + mapOf( + MATCHER_TYPE_KEY to PathActionMatcherFactory.TYPE, + MATCHER_PATTERN_KEY to ".*" + ).asConfiguration() + ), + PathActionMatcherFactory().create( + mapOf( + MATCHER_TYPE_KEY to PathActionMatcherFactory.TYPE, + MATCHER_PATTERN_KEY to "#{principal.id}.*" + ).asConfiguration() + ), + RegularActionMatcherFactory().create( + mapOf( + MATCHER_TYPE_KEY to RegularActionMatcherFactory.TYPE, + MATCHER_PATTERN_KEY to ".*" + ).asConfiguration() + ), + RegularActionMatcherFactory().create( + mapOf( + MATCHER_TYPE_KEY to RegularActionMatcherFactory.TYPE, + MATCHER_PATTERN_KEY to "#{principal.id}.*" + ).asConfiguration() + ) ) } @JvmStatic fun serializeConditionMatcherProvider(): Stream { return Stream.of( - AllConditionMatcherFactory().create(""), - NoneConditionMatcherFactory().create(""), - AuthenticatedConditionMatcherFactory().create(""), - InDefaultTenantConditionMatcherFactory().create(""), - InPlatformTenantConditionMatcherFactory().create(""), - InUserTenantConditionMatcherFactory().create(""), - InIpConditionMatcherFactory().create("ip0,ip1"), - RegularIpConditionMatcherFactory().create("192\\.168\\.0\\.[0-9]*"), - SpelConditionMatcherFactory().create("context.principal.id=='1'"), - OgnlConditionMatcherFactory().create("action == \"auth/login:POST\"") + AllConditionMatcherFactory().create(mapOf(MATCHER_TYPE_KEY to AllConditionMatcherFactory.TYPE).asConfiguration()), + NoneConditionMatcherFactory().create(mapOf(MATCHER_TYPE_KEY to NoneConditionMatcherFactory.TYPE).asConfiguration()), + AuthenticatedConditionMatcherFactory().create(mapOf(MATCHER_TYPE_KEY to AuthenticatedConditionMatcherFactory.TYPE).asConfiguration()), + InDefaultTenantConditionMatcherFactory().create(mapOf(MATCHER_TYPE_KEY to InDefaultTenantConditionMatcherFactory.TYPE).asConfiguration()), + InPlatformTenantConditionMatcherFactory().create(mapOf(MATCHER_TYPE_KEY to InPlatformTenantConditionMatcherFactory.TYPE).asConfiguration()), + InUserTenantConditionMatcherFactory().create(mapOf(MATCHER_TYPE_KEY to InUserTenantConditionMatcherFactory.TYPE).asConfiguration()), + InIpConditionMatcherFactory().create( + mapOf( + MATCHER_TYPE_KEY to InIpConditionMatcherFactory.TYPE, + MATCHER_PATTERN_KEY to "ip0,ip1" + ).asConfiguration() + ), + RegularIpConditionMatcherFactory().create( + mapOf( + MATCHER_TYPE_KEY to RegularIpConditionMatcherFactory.TYPE, + MATCHER_PATTERN_KEY to "192\\.168\\.0\\.[0-9]*" + ).asConfiguration() + ), + SpelConditionMatcherFactory().create( + mapOf( + MATCHER_TYPE_KEY to SpelConditionMatcherFactory.TYPE, + MATCHER_PATTERN_KEY to "context.principal.id=='1'" + ).asConfiguration() + ), + OgnlConditionMatcherFactory().create( + mapOf( + MATCHER_TYPE_KEY to OgnlConditionMatcherFactory.TYPE, + MATCHER_PATTERN_KEY to "action == \"auth/login:POST\"" + ).asConfiguration() + ) ) } diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/serialization/JsonConfigurationSerializerTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/serialization/JsonConfigurationSerializerTest.kt new file mode 100644 index 00000000..75620377 --- /dev/null +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/serialization/JsonConfigurationSerializerTest.kt @@ -0,0 +1,49 @@ +/* + * Copyright [2021-present] [ahoo wang (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.serialization + +import me.ahoo.cosec.api.configuration.asPojo +import me.ahoo.cosec.configuration.JsonConfiguration +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.* +import org.junit.jupiter.api.Test + +class JsonConfigurationSerializerTest { + + val json = """ + {"type":"path","methods":["GET","POST"],"pattern":"#{principal.id}.*","part":{"kind":"request","name":"remoteIp"}} + """.trimIndent() + + @Test + fun serialize() { + val jsonConfiguration = CoSecJsonSerializer.readValue(json, JsonConfiguration::class.java) + assertThat(jsonConfiguration.has("type"), equalTo(true)) + assertThat(jsonConfiguration.has("path"), equalTo(false)) + assertThat(jsonConfiguration.getRequired("type").asString(), equalTo("path")) + assertThat(jsonConfiguration.getRequired("methods").asStringList(), equalTo(listOf("GET", "POST"))) + assertThat(jsonConfiguration.getRequired("pattern").asString(), equalTo("#{principal.id}.*")) + assertThat( + jsonConfiguration.getRequired("part").asStringMap(), + equalTo(mapOf("kind" to "request", "name" to "remoteIp")) + ) + assertThat( + jsonConfiguration.getRequired("part").asPojo(), + equalTo(Part("request", "remoteIp")) + ) + val jsonString = CoSecJsonSerializer.writeValueAsString(jsonConfiguration) + assertThat(jsonString, equalTo(json)) + } + + data class Part(val kind: String, val name: String) +} diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/tenant/SimpleTenantTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/tenant/SimpleTenantTest.kt index b6fc2872..8e8cb42d 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/tenant/SimpleTenantTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/tenant/SimpleTenantTest.kt @@ -32,4 +32,4 @@ class SimpleTenantTest { fun isUserTenant() { assertThat(SimpleTenant("userTenantId").isUserTenant, equalTo(true)) } -} \ No newline at end of file +} diff --git a/cosec-redis/src/test/kotlin/me/ahoo/cosec/redis/PolicyCodecExecutorTest.kt b/cosec-redis/src/test/kotlin/me/ahoo/cosec/redis/PolicyCodecExecutorTest.kt index 6d3f44ee..31d06b7a 100644 --- a/cosec-redis/src/test/kotlin/me/ahoo/cosec/redis/PolicyCodecExecutorTest.kt +++ b/cosec-redis/src/test/kotlin/me/ahoo/cosec/redis/PolicyCodecExecutorTest.kt @@ -19,7 +19,7 @@ import me.ahoo.cosec.api.policy.Policy import me.ahoo.cosec.api.policy.PolicyType import me.ahoo.cosec.policy.PolicyData import me.ahoo.cosec.policy.StatementData -import me.ahoo.cosec.policy.serialization.CoSecJsonSerializer +import me.ahoo.cosec.serialization.CoSecJsonSerializer import me.ahoo.cosid.test.MockIdGenerator import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.`is` diff --git a/cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/CoSecAutoConfiguration.kt b/cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/CoSecAutoConfiguration.kt index 78965c65..0ed67063 100644 --- a/cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/CoSecAutoConfiguration.kt +++ b/cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/CoSecAutoConfiguration.kt @@ -12,7 +12,7 @@ */ package me.ahoo.cosec.spring.boot.starter -import me.ahoo.cosec.policy.serialization.CoSecModule +import me.ahoo.cosec.serialization.CoSecModule import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.EnableConfigurationProperties diff --git a/cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/authorization/cache/CoSecCacheAutoConfiguration.kt b/cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/authorization/cache/CoSecCacheAutoConfiguration.kt index 6d3bb779..b2fd8d82 100644 --- a/cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/authorization/cache/CoSecCacheAutoConfiguration.kt +++ b/cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/authorization/cache/CoSecCacheAutoConfiguration.kt @@ -24,12 +24,12 @@ import me.ahoo.cache.spring.redis.codec.ObjectToJsonCodecExecutor import me.ahoo.cache.spring.redis.codec.SetToSetCodecExecutor import me.ahoo.cosec.api.policy.Policy import me.ahoo.cosec.authorization.PermissionRepository -import me.ahoo.cosec.policy.serialization.CoSecJsonSerializer import me.ahoo.cosec.redis.GlobalPolicyIndexCache import me.ahoo.cosec.redis.GlobalPolicyIndexKey import me.ahoo.cosec.redis.PolicyCache import me.ahoo.cosec.redis.RedisPermissionRepository import me.ahoo.cosec.redis.RolePolicyCache +import me.ahoo.cosec.serialization.CoSecJsonSerializer import me.ahoo.cosec.spring.boot.starter.ConditionalOnCoSecEnabled import me.ahoo.cosid.IdGenerator import org.springframework.beans.factory.annotation.Qualifier diff --git a/cosec-spring-boot-starter/src/test/kotlin/me/ahoo/cosec/spring/boot/starter/CoSecAutoConfigurationTest.kt b/cosec-spring-boot-starter/src/test/kotlin/me/ahoo/cosec/spring/boot/starter/CoSecAutoConfigurationTest.kt index 9359aba2..d34d04c7 100644 --- a/cosec-spring-boot-starter/src/test/kotlin/me/ahoo/cosec/spring/boot/starter/CoSecAutoConfigurationTest.kt +++ b/cosec-spring-boot-starter/src/test/kotlin/me/ahoo/cosec/spring/boot/starter/CoSecAutoConfigurationTest.kt @@ -13,7 +13,7 @@ package me.ahoo.cosec.spring.boot.starter -import me.ahoo.cosec.policy.serialization.CoSecModule +import me.ahoo.cosec.serialization.CoSecModule import org.assertj.core.api.AssertionsForInterfaceTypes.assertThat import org.junit.jupiter.api.Test import org.springframework.boot.test.context.assertj.AssertableApplicationContext diff --git a/cosec-webflux/src/main/kotlin/me/ahoo/cosec/webflux/ReactiveSecurityFilter.kt b/cosec-webflux/src/main/kotlin/me/ahoo/cosec/webflux/ReactiveSecurityFilter.kt index d6a17dac..9bb43183 100644 --- a/cosec-webflux/src/main/kotlin/me/ahoo/cosec/webflux/ReactiveSecurityFilter.kt +++ b/cosec-webflux/src/main/kotlin/me/ahoo/cosec/webflux/ReactiveSecurityFilter.kt @@ -17,7 +17,7 @@ import me.ahoo.cosec.api.authorization.Authorization import me.ahoo.cosec.api.authorization.AuthorizeResult import me.ahoo.cosec.context.SecurityContextParser import me.ahoo.cosec.context.request.RequestParser -import me.ahoo.cosec.policy.serialization.CoSecJsonSerializer +import me.ahoo.cosec.serialization.CoSecJsonSerializer import me.ahoo.cosec.webflux.ReactiveSecurityContexts.writeSecurityContext import me.ahoo.cosec.webflux.ServerWebExchanges.setSecurityContext import org.springframework.http.HttpStatus diff --git a/cosec-webmvc/src/main/kotlin/me/ahoo/cosec/servlet/AbstractAuthorizationInterceptor.kt b/cosec-webmvc/src/main/kotlin/me/ahoo/cosec/servlet/AbstractAuthorizationInterceptor.kt index 6e684e35..d0fba07a 100644 --- a/cosec-webmvc/src/main/kotlin/me/ahoo/cosec/servlet/AbstractAuthorizationInterceptor.kt +++ b/cosec-webmvc/src/main/kotlin/me/ahoo/cosec/servlet/AbstractAuthorizationInterceptor.kt @@ -16,7 +16,7 @@ import me.ahoo.cosec.api.authorization.Authorization import me.ahoo.cosec.context.SecurityContextHolder import me.ahoo.cosec.context.SecurityContextParser import me.ahoo.cosec.context.request.RequestParser -import me.ahoo.cosec.policy.serialization.CoSecJsonSerializer +import me.ahoo.cosec.serialization.CoSecJsonSerializer import me.ahoo.cosec.servlet.ServletRequests.setSecurityContext import org.springframework.http.HttpStatus import javax.servlet.http.HttpServletRequest diff --git a/document/cosec-policy.schema.json b/document/cosec-policy.schema.json index 594b7717..8d90a0e0 100644 --- a/document/cosec-policy.schema.json +++ b/document/cosec-policy.schema.json @@ -79,11 +79,30 @@ "ognl" ] }, + "requestPart": { + "enum": [ + "action", + "tenantId", + "remoteIp", + "origin", + "referer" + ] + }, "actionMatcher": { "type": "object", + "additionalProperties": { + "type": "string" + }, "properties": { "type": { - "$ref": "#/definitions/actionType" + "anyOf": [ + { + "$ref": "#/definitions/actionType" + }, + { + "type": "string" + } + ] }, "pattern": { "type": "string" @@ -95,9 +114,19 @@ }, "conditionMatcher": { "type": "object", + "additionalProperties": { + "type": "string" + }, "properties": { "type": { - "$ref": "#/definitions/conditionType" + "anyOf": [ + { + "$ref": "#/definitions/conditionType" + }, + { + "type": "string" + } + ] }, "pattern": { "type": "string" diff --git a/gradle.properties b/gradle.properties index f29c8d94..258862aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ # limitations under the License. # group=me.ahoo.cosec -version=1.6.9 +version=1.7.0 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