From 1e7ccea1c7b23377cbdcd0b70449777e1e629917 Mon Sep 17 00:00:00 2001 From: Henry Steinhauer Date: Thu, 11 Feb 2021 12:29:28 +0100 Subject: [PATCH] feat: Add role based autorization --- src/api/v1/tournamentsManagement.kt | 16 +++++++++------- src/features/Authorization.kt | 10 ++++++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/api/v1/tournamentsManagement.kt b/src/api/v1/tournamentsManagement.kt index 0e21e4c..1c4c6a6 100644 --- a/src/api/v1/tournamentsManagement.kt +++ b/src/api/v1/tournamentsManagement.kt @@ -10,7 +10,7 @@ import io.ktor.routing.* import withRole fun Route.tournamentManagement() { - withRole { + withRole("admin") { delete("tournaments/{id}") { val tournamentId = call.parameters["id"] val removedTournament = TournamentsController.removeTournament(tournamentId!!.toInt()) @@ -22,6 +22,14 @@ fun Route.tournamentManagement() { call.respond(addedTournament) call.request.header("Authorization") } + put("tournaments/{id}") { + val tournamentId = call.parameters["id"] + val newTournamentsValues = call.receive() + val updatedTournament = TournamentsController.updateTournament(tournamentId!!.toInt(), newTournamentsValues) + call.respond(updatedTournament) + } + } + withRole("admin", "user") { get("tournaments") { val storedTournaments = TournamentsController.getAllTournaments() call.respond(storedTournaments) @@ -31,11 +39,5 @@ fun Route.tournamentManagement() { val storedTournaments = TournamentsController.getTournament(tournamentId!!.toInt()) call.respond(storedTournaments) } - put("tournaments/{id}") { - val tournamentId = call.parameters["id"] - val newTournamentsValues = call.receive() - val updatedTournament = TournamentsController.updateTournament(tournamentId!!.toInt(), newTournamentsValues) - call.respond(updatedTournament) - } } } diff --git a/src/features/Authorization.kt b/src/features/Authorization.kt index dbcc316..effa063 100644 --- a/src/features/Authorization.kt +++ b/src/features/Authorization.kt @@ -11,7 +11,7 @@ class RoleBasedAuthorization() { class Configuration - fun interceptPipeline(pipeline: ApplicationCallPipeline) { + fun interceptPipeline(pipeline: ApplicationCallPipeline, acceptedRoles: Array) { pipeline.insertPhaseAfter(ApplicationCallPipeline.Features, Authentication.ChallengePhase) pipeline.insertPhaseAfter(Authentication.ChallengePhase, AuthorizationPhase) @@ -20,7 +20,9 @@ class RoleBasedAuthorization() { url = "https://turnierverwaltung-auth.herokuapp.com/api/v1/auth", headers = mapOf("Authorization" to call.request.header("Authorization")), ) + val role = String(status.content) if (status.statusCode == HttpStatusCode.Unauthorized.value) throw AuthenticationException() + if (!acceptedRoles.contains(role)) throw AuthenticationException() } } @@ -45,11 +47,11 @@ class AuthorizedRouteSelector(private val description: String) : override fun toString(): String = "(authorize $description)" } -fun Route.withRole(build: Route.() -> Unit) = authorizedRoute(build = build) +fun Route.withRole(vararg selectedRoles: String, build: Route.() -> Unit) = authorizedRoute(acceptedRoles = selectedRoles, build = build) -private fun Route.authorizedRoute(build: Route.() -> Unit): Route { +private fun Route.authorizedRoute(acceptedRoles: Array, build: Route.() -> Unit): Route { val authorizedRoute = createChild(AuthorizedRouteSelector("")) - application.feature(RoleBasedAuthorization).interceptPipeline(authorizedRoute) + application.feature(RoleBasedAuthorization).interceptPipeline(authorizedRoute, acceptedRoles) authorizedRoute.build() return authorizedRoute }