ktor
ktor copied to clipboard
How do I find out the request handler before processing?
How do I find out the request handler before processing?
I made a custom feature that should check the user's permissions to use the request. Can I monitor what handler the router is accessing? Can this looks like that? if (!User.accessTo.contains(REQUEST_HANDLER_NAME_OR_SOMETHING)){ call.respond(HttpStatusCode.BadRequest) }
import io.ktor.application.*
import io.ktor.http.HttpStatusCode
import io.ktor.pipeline.*
import io.ktor.response.respond
import io.ktor.sessions.*
import io.ktor.util.AttributeKey
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
data class UserRights(
val haveFullAccess:Boolean,
val accessTo:List<String>,
val canUpdate:Boolean,
val canDelete:Boolean,
val canBan:Boolean,
val canMute:Boolean)
var User = UserRights(false, listOf(""),false,false,false,false)
class RightsChecker(configuration: Configuration) {
val prop = configuration.prop // get snapshot of config into immutable property
class Configuration {
var prop = "value"
}
companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, RightsChecker> {
override val key = AttributeKey<RightsChecker>("RightsChecker")
override fun install(pipeline: ApplicationCallPipeline, configure: Configuration.() -> Unit): RightsChecker {
val configuration = RightsChecker.Configuration().apply(configure)
val feature = RightsChecker(configuration)
val FilterPhase = PipelinePhase("CallFilter")
pipeline.insertPhaseAfter(ApplicationCallPipeline.Infrastructure, FilterPhase)
pipeline.intercept(FilterPhase) {
val session = call.sessions.get<SessionData>() ?: SessionData(0, "Guest")
println(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) + " User ${session.userID}, ${session.role} connected")
when (session.role) {
"Guest" -> User = UserRights(
haveFullAccess = false,
accessTo = listOf(""),
canUpdate = false,
canDelete = false,
canBan = false,
canMute = false)
"User" -> User = UserRights(
haveFullAccess = false,
accessTo = listOf("lUsers"),
canUpdate = false,
canDelete = false,
canBan = false,
canMute = false)
"Moder" -> User = UserRights(
haveFullAccess = false,
accessTo = listOf("lUsers"),
canUpdate = true,
canDelete = false,
canBan = false,
canMute = true)
"Admin" -> User = UserRights(
haveFullAccess = true,
accessTo = listOf("lUsers"),
canUpdate = true,
canDelete = true,
canBan = true,
canMute = true)
}
if (!User.accessTo.contains(**REQUEST_HANDLER_NAME_OR_SOMETHING**)){
call.respond(HttpStatusCode.BadRequest)
}
}
pipeline.intercept(ApplicationCallPipeline.Call) {
val session = call.sessions.get<SessionData>() ?: SessionData(0,"Guest")
println(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME)+" User ${session.userID}, ${session.role} call answered")
}
return feature
}
}
}
You might want to use a route interceptor: https://ktor.io/advanced/pipeline/route.html
If you cannot use it, or doesn't fit your needs, please consider joining our slack channel so we can discuss it, since it is a better channel for this kind of questions ( Rationale here: https://ktor.io/quickstart/faq.html#feedback ).
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.