main.dev.neeffect.nee.ctx.web.jwt.JwtAuthProvider.kt Maven / Gradle / Ivy
package dev.neeffect.nee.ctx.web.jwt
import dev.neeffect.nee.effects.Out
import dev.neeffect.nee.effects.security.SecurityCtx
import dev.neeffect.nee.effects.security.SecurityError
import dev.neeffect.nee.effects.security.SecurityErrorType
import dev.neeffect.nee.effects.security.SecurityProvider
import dev.neeffect.nee.effects.utils.merge
import dev.neeffect.nee.security.jwt.JwtConfigurationModule
import dev.neeffect.nee.security.jwt.JwtUsersCoder
import io.vavr.control.Option
class JwtAuthProvider(
private val headerVal: Option,
private val jwtConf: JwtConfigurationModule
) : SecurityProvider {
override fun getSecurityContext(): Out> =
headerVal.map { fullHeader ->
if (fullHeader.startsWith(bearerAuthHeaderPrefix)) {
val jwtToken = fullHeader.substring(bearerAuthHeaderPrefix.length)
jwtConf.jwtCoder.decodeJwt(jwtToken).map { jwt ->
jwtConf.jwtUsersCoder.decodeUser(jwt).map { user ->
Out.right>(
TokenSecurityContext(user, jwtConf.jwtUsersCoder)
)
}.getOrElse {
Out.left(SecurityErrorType.MalformedCredentials("user not decoded from $jwt"))
}
}.mapLeft { jwtError ->
Out.left>(
SecurityErrorType.MalformedCredentials(jwtError.toString())
)
}.merge()
} else {
Out.left>(
SecurityErrorType.MalformedCredentials("wrong header $fullHeader")
)
}
}.getOrElse {
Out.left>(SecurityErrorType.NoSecurityCtx)
}
companion object {
const val bearerAuthHeaderPrefix = "Bearer "
}
}
class TokenSecurityContext(val user: USER, val jwtCoder: JwtUsersCoder) :
SecurityCtx {
override fun getCurrentUser(): Out =
Out.right(user)
override fun hasRole(role: ROLE): Boolean = jwtCoder.hasRole(user, role)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy