67 lines
2.6 KiB
Kotlin
67 lines
2.6 KiB
Kotlin
package com.restapi
|
|
|
|
import com.restapi.config.AppConfig.Companion.appConfig
|
|
import com.restapi.config.Role
|
|
import com.restapi.config.Roles
|
|
import com.restapi.domain.EntityModel
|
|
import io.javalin.http.Context
|
|
import io.javalin.http.Handler
|
|
import io.javalin.http.HttpStatus
|
|
import io.javalin.security.AccessManager
|
|
import io.javalin.security.RouteRole
|
|
import org.slf4j.LoggerFactory
|
|
import com.restapi.domain.Session.currentRoles
|
|
import com.restapi.domain.Session.database
|
|
|
|
class AppAccessManager : AccessManager {
|
|
private val logger = LoggerFactory.getLogger("Access")
|
|
private fun loadEntityActionRole(entity: String?, action: String?): List<String> {
|
|
if (entity == null || action == null) return emptyList()
|
|
|
|
return database.find(EntityModel::class.java)
|
|
.where()
|
|
.eq("name", entity)
|
|
.findOne()
|
|
?.actions
|
|
?.filter { it.equals(action, ignoreCase = true) }
|
|
?.map { "role_${entity}_$it" } ?: emptyList()
|
|
}
|
|
|
|
override fun manage(handler: Handler, ctx: Context, routeRoles: Set<RouteRole>) {
|
|
val pathParamMap = ctx.pathParamMap()
|
|
val regex = Regex("^[a-zA-Z0-9\\-_\\.]+$")
|
|
|
|
if (pathParamMap.values.count { !regex.matches(it) } > 0) {
|
|
ctx.status(HttpStatus.FORBIDDEN).result("invalid request")
|
|
} else {
|
|
val entity = pathParamMap["entity"]
|
|
val action = pathParamMap["action"]
|
|
|
|
val allowedRoles = routeRoles.map { it as Roles }.flatMap { it.roles.toList() }.flatMap { role ->
|
|
when (role) {
|
|
Role.DbOps -> listOf("ROLE_DB_OPS")
|
|
Role.Entity -> loadEntityActionRole(entity, action)
|
|
is Role.Standard -> role.action.toList().map { "ROLE_${entity}_${it}" }
|
|
is Role.Explicit -> role.roles
|
|
}.map(String::uppercase)
|
|
}
|
|
|
|
val isAllowed = currentRoles().count { allowedRoles.contains(it) } > 0
|
|
logger.debug(
|
|
"entity - {}, action {}, user roles = {}, allowed = {}, isAllowed? {}, enforce? {}",
|
|
entity,
|
|
action,
|
|
currentRoles(),
|
|
allowedRoles,
|
|
isAllowed,
|
|
appConfig.enforceRoleRestriction()
|
|
)
|
|
if (isAllowed || !appConfig.enforceRoleRestriction() || allowedRoles.isEmpty()) {
|
|
//if role is allowed, or enforcement is turned off or no roles are explicitly allowed
|
|
handler.handle(ctx)
|
|
} else {
|
|
ctx.status(HttpStatus.FORBIDDEN).result("user not allowed to do this")
|
|
}
|
|
}
|
|
}
|
|
} |