From bfcbfee1200cda19f653cd784052978e7c12e595 Mon Sep 17 00:00:00 2001 From: Fabrice Lecomte Date: Mon, 26 Aug 2019 17:13:47 +0200 Subject: [PATCH] add citizen in ApplicationCall --- .../kotlin/fr/dcproject/ApplicationContext.kt | 24 +++++++++++++++++++ .../kotlin/fr/dcproject/repository/Citizen.kt | 7 ++++++ .../fr/dcproject/security/voter/Voter.kt | 2 +- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/fr/dcproject/ApplicationContext.kt diff --git a/src/main/kotlin/fr/dcproject/ApplicationContext.kt b/src/main/kotlin/fr/dcproject/ApplicationContext.kt new file mode 100644 index 0000000..66163c5 --- /dev/null +++ b/src/main/kotlin/fr/dcproject/ApplicationContext.kt @@ -0,0 +1,24 @@ +package fr.dcproject + +import fr.dcproject.security.voter.ForbiddenException +import io.ktor.application.ApplicationCall +import io.ktor.auth.authentication +import io.ktor.util.AttributeKey +import io.ktor.util.pipeline.PipelineContext +import kotlinx.coroutines.runBlocking +import org.koin.core.context.GlobalContext +import fr.dcproject.entity.Citizen as CitizenEntity +import fr.dcproject.entity.User as UserEntity +import fr.dcproject.repository.Citizen as CitizenRepository + +private val citizenAttributeKey = AttributeKey("CitizenContext") + +val ApplicationCall.citizen: CitizenEntity + get() = attributes.computeIfAbsent(citizenAttributeKey) { + runBlocking { + val user = authentication.principal() ?: throw ForbiddenException() + GlobalContext.get().koin.get().findByUser(user) ?: throw ForbiddenException("Citizen not found for this user id \"${user.id}\"") + } + } + +val PipelineContext.citizen get() = context.citizen diff --git a/src/main/kotlin/fr/dcproject/repository/Citizen.kt b/src/main/kotlin/fr/dcproject/repository/Citizen.kt index 0556ddc..778c1be 100644 --- a/src/main/kotlin/fr/dcproject/repository/Citizen.kt +++ b/src/main/kotlin/fr/dcproject/repository/Citizen.kt @@ -7,6 +7,7 @@ import fr.postgresjson.repository.RepositoryI.Direction import net.pearx.kasechange.toSnakeCase import java.util.* import fr.dcproject.entity.Citizen as CitizenEntity +import fr.dcproject.entity.User as UserEntity class Citizen(override var requester: Requester) : RepositoryI { override val entityName = CitizenEntity::class @@ -17,6 +18,12 @@ class Citizen(override var requester: Requester) : RepositoryI { .selectOne("id" to id) } + fun findByUser(user: UserEntity): CitizenEntity? { + return requester + .getFunction("find_citizen_by_user_id") + .selectOne("user_id" to user.id) + } + fun find( page: Int = 1, limit: Int = 50, diff --git a/src/main/kotlin/fr/dcproject/security/voter/Voter.kt b/src/main/kotlin/fr/dcproject/security/voter/Voter.kt index 2545bbc..c25c67f 100644 --- a/src/main/kotlin/fr/dcproject/security/voter/Voter.kt +++ b/src/main/kotlin/fr/dcproject/security/voter/Voter.kt @@ -56,7 +56,7 @@ fun ApplicationCall.can(action: ActionI, subject: Any? = null): Boolean { abstract class VoterException(message: String) : Throwable(message) class NoVoterException(action: ActionI) : VoterException("No voter found for action '$action'") class UnauthorizedException(action: ActionI) : VoterException("Unauthorized for action '$action'") -class ForbiddenException : Throwable() +class ForbiddenException(message: String? = null) : Throwable(message) val ApplicationCall.user get() = authentication.principal()