diff --git a/server/src/main/kotlin/net/keinekekse/app/server/books/booksRoute.kt b/server/src/main/kotlin/net/keinekekse/app/server/books/booksRoute.kt new file mode 100644 index 0000000..c63ae35 --- /dev/null +++ b/server/src/main/kotlin/net/keinekekse/app/server/books/booksRoute.kt @@ -0,0 +1,33 @@ +package books + +import books.model.BookRepository +import io.ktor.http.* +import io.ktor.server.auth.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import net.keinekekse.app.UserRoles +import org.koin.ktor.ext.inject + +fun Route.booksRoute() { + val repository: BookRepository by inject() + + authenticate(UserRoles.BOOKS_USER.roleName) { + route("/books") { + get("/books") { +// call.respondText("Test DB route") + val books = repository.allBooks() + call.respond(books) + } + get("/book/{id}") { + // TODO safe toInt conv + val id = call.parameters["id"]!!.toInt() + repository.bookById(id)?.let { call.respond(it) } + ?: call.respondText( + "Book with id $id not found", + status = HttpStatusCode.NotFound + ) + } + + } + } +} diff --git a/server/src/main/kotlin/net/keinekekse/app/server/config/routing.kt b/server/src/main/kotlin/net/keinekekse/app/server/config/routing.kt index 927f114..e5b0327 100644 --- a/server/src/main/kotlin/net/keinekekse/app/server/config/routing.kt +++ b/server/src/main/kotlin/net/keinekekse/app/server/config/routing.kt @@ -1,18 +1,19 @@ package net.keinekekse.app.server.config +import books.booksRoute import io.github.oshai.kotlinlogging.KotlinLogging import io.ktor.server.application.* import io.ktor.server.auth.* import io.ktor.server.response.* import io.ktor.server.routing.* +import net.keinekekse.app.UserRoles import net.keinekekse.app.server.VERSION -import net.keinekekse.app.server.testdb.testDbRoute private val logger = KotlinLogging.logger {} fun Application.configureRouting() { routing { - authenticate("auth-KC") { + authenticate(UserRoles.BOOKS_USER.roleName) { get("/") { val principal = call.principal() call.respondText("user: ${principal?.userId}") @@ -24,6 +25,6 @@ fun Application.configureRouting() { } } - testDbRoute() + booksRoute() } } diff --git a/server/src/main/kotlin/net/keinekekse/app/server/config/security.kt b/server/src/main/kotlin/net/keinekekse/app/server/config/security.kt index 339bcfa..f791cbd 100644 --- a/server/src/main/kotlin/net/keinekekse/app/server/config/security.kt +++ b/server/src/main/kotlin/net/keinekekse/app/server/config/security.kt @@ -7,6 +7,7 @@ import io.ktor.server.application.* import io.ktor.server.auth.* import io.ktor.server.auth.jwt.* import io.ktor.server.response.* +import net.keinekekse.app.UserRoles import java.net.URI private val logger = KotlinLogging.logger {} @@ -25,18 +26,23 @@ fun Application.configureSecurity() { val issuer = "$keycloakUrl/$keycloakRealm" authentication { - jwt("auth-KC") { - verifier( - UrlJwkProvider(URI(certUrl).toURL()), issuer - ) { - withAudience("account") - withClaim("azp", keycloakClientId) - } - challenge { _, _ -> - call.respond(HttpStatusCode.Unauthorized, "Token is not valid or has expired") - } - validate { credential -> - AppPrincipal(credential) + for (role in UserRoles.entries) { + jwt(role.roleName) { + verifier( + UrlJwkProvider(URI(certUrl).toURL()), issuer + ) { + withAudience("account") + withClaim("azp", keycloakClientId) + } + challenge { _, _ -> + call.respond(HttpStatusCode.Unauthorized, "Token is not valid or has expired") + } + validate { credential -> + val principal = AppPrincipal(credential) + if (principal.roles.contains(role.roleName) || + principal.roles.contains(UserRoles.ADMIN.roleName) + ) principal else null + } } } } diff --git a/shared/src/commonMain/kotlin/net/keinekekse/app/UserRoles.kt b/shared/src/commonMain/kotlin/net/keinekekse/app/UserRoles.kt new file mode 100644 index 0000000..4ff98d1 --- /dev/null +++ b/shared/src/commonMain/kotlin/net/keinekekse/app/UserRoles.kt @@ -0,0 +1,9 @@ +package net.keinekekse.app + +enum class UserRoles(val roleName: String) { + ADMIN("admin"), + BOOKS_ADMIN("books-admin"), + BOOKS_USER("books-user"), + BOOKS_EDITOR("books-editor") + +}