Hi all,
I’m trying to create a SecurityContext
(an object that contains info about the logged in user) and add it in the CoroutineContext
by using a CoroutineContextElement
.
I need to do this by creating a RouteScopePlugin
during the AuthenticationChecked
hook (by using on(AuthenticationChecked)
. However, I’m not sure how to combine the current coroutine context with the context element that I create. In the base API, I could use the withContext(contextElement) { proceed() }
way, but with the new Ktor handler API, it seems like I can’t combine the coroutine contexts.
Or, if you could suggest another way in doing this, that would be appreciated too
Example Code:
data class SecurityContext(val userId: String)
class RequestContextElement(val context: SecurityContext) : AbstractCoroutineContextElement(Key) {
companion object Key : CoroutineContext.Key<RequestContextElement>
}
val CoroutineContext.securityContext: SecurityContext
get() = this[RequestContextElement]?.context ?: throw IllegalStateException("SecurityContext not set in CoroutineContext")
val RequestContextPlugin = createRouteScopedPlugin(name = "RequestContextPlugin") {
on(AuthenticationChecked) { call ->
val user = SubjectUtil.getUserFromRequest(call)
val securityContext = SecurityContext(
userId = user.id,
)
// how to proceed the rest of the execution with this combined context?
coroutineContext + RequestContextElement(requestInfo)
// this is how you would do it via the Base API
// withContext(RequestContextElement(securityContext)) {
// proceed()
// }
}
P.S.: Apologies if this is not the correct forum to post this question. I have posted this on Ktor’s reddit, however I figured it might be wise to bring this question to a broader audience.