Skip to content

Commit

Permalink
Feature: support request.header. for PathConditionMatcher (#49)
Browse files Browse the repository at this point in the history
- Feature: support `request.header.` for `PathConditionMatcher`
- Breaking: remove `TenantId` from `Request`
- Breaking: `CoSecPrincipal.id` as  `Principal.getName()`
  • Loading branch information
Ahoo-Wang authored Jan 4, 2023
1 parent a6270e1 commit c11ef90
Show file tree
Hide file tree
Showing 45 changed files with 95 additions and 554 deletions.
5 changes: 1 addition & 4 deletions cosec-api/src/main/kotlin/me/ahoo/cosec/api/CoSec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
*/
package me.ahoo.cosec.api

import me.ahoo.cosec.api.internal.InternalIds

/**
* CoSec const.
*
Expand All @@ -23,6 +21,5 @@ object CoSec {
const val COSEC = "cosec"
const val COSEC_PREFIX = "$COSEC."

@JvmField
val DEFAULT = InternalIds.wrap("0")
const val DEFAULT = "(0)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@

package me.ahoo.cosec.api.context.request

import me.ahoo.cosec.api.tenant.Tenant

interface Request : Tenant {
interface Request {
val path: String
val method: String
val remoteIp: String
val origin: String
val referer: String

fun getHeader(key: String): String
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package me.ahoo.cosec.api.principal

import me.ahoo.cosec.api.CoSec
import me.ahoo.cosec.api.internal.InternalIds.wrap
import java.security.Principal

/**
Expand All @@ -26,7 +25,12 @@ interface CoSecPrincipal : Principal, PolicyCapable, RoleCapable {
//endregion
val id: String

override fun getName(): String
/**
* @see id
*/
override fun getName(): String {
return id
}

val attrs: Map<String, Any>
fun anonymous(): Boolean {
Expand All @@ -38,22 +42,19 @@ interface CoSecPrincipal : Principal, PolicyCapable, RoleCapable {
}

companion object {
const val NAME_KEY = "name"

//region ROOT 根账号拥有所有权限
const val ROOT_KEY = "cosec.root"

val ROOT_NAME: String = System.getProperty(ROOT_KEY, CoSec.COSEC)
val ROOT_ID: String = System.getProperty(ROOT_KEY, CoSec.COSEC)

//endregion
//region ANONYMOUS 未认证状态下的用户

val ANONYMOUS_ID = CoSec.DEFAULT

val ANONYMOUS_NAME = wrap("anonymous")

fun CoSecPrincipal.isRoot(): Boolean {
return ROOT_NAME == name
return ROOT_ID == id
}
}
}
11 changes: 5 additions & 6 deletions cosec-api/src/main/kotlin/me/ahoo/cosec/api/tenant/Tenant.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package me.ahoo.cosec.api.tenant

import me.ahoo.cosec.api.CoSec
import me.ahoo.cosec.api.internal.InternalIds.wrap

/**
* Tenant for splitting customer boundaries horizontally.
Expand Down Expand Up @@ -49,20 +48,20 @@ interface Tenant {
get() = !isDefaultTenant && !isPlatformTenant

companion object {
const val TENANT_ID_KEY = "tenantId"

/**
* 根平台租户ID.
*/
@JvmField
val PLATFORM_TENANT_ID = wrap("platform")

@JvmField
val DEFAULT_TENANT_ID = CoSec.DEFAULT
const val PLATFORM_TENANT_ID = "(platform)"
const val DEFAULT_TENANT_ID = CoSec.DEFAULT

@JvmStatic
fun isPlatform(tenantId: String): Boolean {
return PLATFORM_TENANT_ID == tenantId
}

@JvmStatic
fun isDefault(tenantId: String): Boolean {
return DEFAULT_TENANT_ID == tenantId
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,6 @@ class SimpleAuthorization(private val permissionRepository: PermissionRepository
return AuthorizeResult.ALLOW.toMono()
}

if (
context.principal.authenticated() &&
!request.isDefaultTenant &&
request.tenantId != context.tenant.tenantId
) {
return IllegalTenantContextException(request, context).toMono()
}

return verifyGlobalPolicies(request, context)
.flatMap { globalVerifyResult: VerifyResult ->
if (globalVerifyResult == VerifyResult.IMPLICIT_DENY) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package me.ahoo.cosec.policy
import me.ahoo.cosec.api.context.request.Request
import me.ahoo.cosec.api.policy.Policy
import me.ahoo.cosec.api.policy.PolicyEvaluator
import me.ahoo.cosec.api.tenant.Tenant
import me.ahoo.cosec.context.SimpleSecurityContext
import me.ahoo.cosec.principal.SimpleTenantPrincipal

Expand All @@ -32,8 +31,10 @@ object DefaultPolicyEvaluator : PolicyEvaluator {
get() = "mockOrigin"
override val referer: String
get() = "mockReferer"
override val tenantId: String
get() = Tenant.DEFAULT_TENANT_ID

override fun getHeader(key: String): String {
return ""
}
}
private val mockContext = SimpleSecurityContext(SimpleTenantPrincipal.ANONYMOUS)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ abstract class PartConditionMatcher(
override val type: String,
final override val configuration: Configuration
) : ConditionMatcher {
val partExtractor: PartExtractor = configuration
private val partExtractor: PartExtractor = configuration
.getRequired(CONDITION_MATCHER_PART_KEY).asString()
.let {
DefaultPartExtractor(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ object RequestParts {
const val REMOTE_IP = PREFIX + "remoteIp"
const val ORIGIN = PREFIX + "origin"
const val REFERER = PREFIX + "referer"
const val TENANT_ID = PREFIX + "tenantId"
const val HEADER_PREFIX = PREFIX + "header."
}

object SecurityContextParts {
Expand All @@ -49,11 +49,16 @@ data class DefaultPartExtractor(val part: String) : PartExtractor {
RequestParts.REMOTE_IP -> request.remoteIp
RequestParts.ORIGIN -> request.origin
RequestParts.REFERER -> request.referer
RequestParts.TENANT_ID -> request.tenantId
SecurityContextParts.TENANT_ID -> securityContext.tenant.tenantId
SecurityContextParts.PRINCIPAL_ID -> securityContext.principal.id
SecurityContextParts.PRINCIPAL_NAME -> securityContext.principal.name
else -> throw IllegalArgumentException("Unsupported part: $part")
else -> {
if (part.startsWith(RequestParts.HEADER_PREFIX)) {
val headerKey = part.substring(RequestParts.HEADER_PREFIX.length)
return request.getHeader(headerKey)
}
throw IllegalArgumentException("Unsupported part: $part")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,13 @@ import me.ahoo.cosec.api.principal.CoSecPrincipal
*/
data class SimplePrincipal(
override val id: String,
private val name: String,
override val policies: Set<String> = emptySet(),
override val roles: Set<String> = emptySet(),
override val attrs: Map<String, Any> = emptyMap()
) : CoSecPrincipal {

companion object {
@JvmField
val ANONYMOUS: CoSecPrincipal = SimplePrincipal(CoSecPrincipal.ANONYMOUS_ID, CoSecPrincipal.ANONYMOUS_NAME)
}

override fun getName(): String {
return name
val ANONYMOUS: CoSecPrincipal = SimplePrincipal(CoSecPrincipal.ANONYMOUS_ID)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ import com.fasterxml.jackson.databind.ser.std.StdSerializer
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.api.tenant.Tenant.Companion.TENANT_ID_KEY
import me.ahoo.cosec.policy.PolicyData

const val POLICY_ID_KEY = "id"
const val POLICY_NAME_KEY = "name"
const val POLICY_CATEGORY_KEY = "category"
const val POLICY_DESCRIPTION_KEY = "description"
const val POLICY_TYPE_KEY = "type"
const val TENANT_ID_KEY = "tenantId"
const val POLICY_STATEMENTS_KEY = "statements"

object JsonPolicySerializer : StdSerializer<Policy>(Policy::class.java) {
Expand Down
Loading

0 comments on commit c11ef90

Please sign in to comment.