ktor icon indicating copy to clipboard operation
ktor copied to clipboard

How do I find out the request handler before processing?

Open NickTsaizer opened this issue 5 years ago • 2 comments

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
        }
    }
}

NickTsaizer avatar Aug 01 '18 13:08 NickTsaizer

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 ).

soywiz avatar Aug 03 '18 10:08 soywiz

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

oleg-larshin avatar Aug 10 '20 15:08 oleg-larshin