Create OpinionChoice

This commit is contained in:
2020-02-11 23:03:12 +01:00
parent 42781565dd
commit ec6e39b130
8 changed files with 127 additions and 6 deletions

View File

@@ -39,6 +39,7 @@ import java.util.concurrent.CompletionException
import fr.dcproject.repository.Article as RepositoryArticle
import fr.dcproject.repository.Citizen as RepositoryCitizen
import fr.dcproject.repository.Constitution as RepositoryConstitution
import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository
import fr.dcproject.repository.User as UserRepository
fun main(args: Array<String>): Unit = io.ktor.server.jetty.EngineMain.main(args)
@@ -121,6 +122,14 @@ fun Application.module(env: Env = PROD) {
get<RepositoryCitizen>().findById(id, true) ?: throw NotFoundException("Citizen $values not found")
}
}
convert<OpinionChoice> {
decode { values, _ ->
val id = values.singleOrNull()?.let { UUID.fromString(it) }
?: throw InternalError("Cannot convert $values to UUID")
get<OpinionChoiceRepository>().findOpinionChoiceById(id) ?: throw NotFoundException("OpinionChoice $values not found")
}
}
}
install(Locations) {
@@ -133,7 +142,8 @@ fun Application.module(env: Env = PROD) {
CitizenVoter(),
CommentVoter(),
VoteVoter(),
FollowVoter()
FollowVoter(),
OpinionChoiceVoter()
)
}
@@ -186,6 +196,7 @@ fun Application.module(env: Env = PROD) {
commentConstitution(get())
voteArticle(get(), get(), get())
voteConstitution(get())
opinionChoice(get())
definition()
}
}

View File

@@ -15,6 +15,7 @@ import fr.dcproject.repository.CommentGeneric as CommentGenericRepository
import fr.dcproject.repository.Constitution as ConstitutionRepository
import fr.dcproject.repository.FollowArticle as FollowArticleRepository
import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository
import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository
import fr.dcproject.repository.User as UserRepository
import fr.dcproject.repository.VoteArticle as VoteArticleRepository
import fr.dcproject.repository.VoteComment as VoteCommentRepository
@@ -57,6 +58,7 @@ val Module = module {
single { VoteArticleRepository(get()) }
single { VoteConstitutionRepository(get()) }
single { VoteCommentRepository(get()) }
single { OpinionChoiceRepository(get()) }
single { Migrations(connection = get(), directory = config.sqlFiles) }

View File

@@ -0,0 +1,16 @@
package fr.dcproject.entity
import fr.postgresjson.entity.immutable.EntityCreatedAt
import fr.postgresjson.entity.immutable.EntityCreatedAtImp
import fr.postgresjson.entity.immutable.UuidEntity
import fr.postgresjson.entity.mutable.EntityDeletedAt
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
import java.util.*
class OpinionChoice(
id: UUID,
val name: String,
val target: List<String>
) : UuidEntity(id),
EntityCreatedAt by EntityCreatedAtImp(),
EntityDeletedAt by EntityDeletedAtImp()

View File

@@ -0,0 +1,37 @@
package fr.dcproject.routes
import fr.dcproject.entity.OpinionChoice
import fr.dcproject.security.voter.OpinionVoter.Action.VIEW
import fr.dcproject.security.voter.assertCan
import io.ktor.application.call
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.get
import io.ktor.response.respond
import io.ktor.routing.Route
import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository
@KtorExperimentalLocationsAPI
object OpinionChoicePaths {
@Location("/opinions/{opinionChoice}")
class OpinionChoiceRequest(val opinionChoice: OpinionChoice)
@Location("/opinions")
class OpinionChoicesRequest(val targets: List<String>)
}
@KtorExperimentalLocationsAPI
fun Route.opinionChoice(repo: OpinionChoiceRepository) {
get<OpinionChoicePaths.OpinionChoiceRequest> {
assertCan(VIEW, it.opinionChoice)
call.respond(it.opinionChoice)
}
get<OpinionChoicePaths.OpinionChoicesRequest> {
val opinions = repo.findOpinionsChoices(it.targets)
assertCan(VIEW, opinions)
call.respond(opinions)
}
}

View File

@@ -0,0 +1,34 @@
package fr.dcproject.security.voter
import fr.dcproject.entity.OpinionChoice
import io.ktor.application.ApplicationCall
class OpinionChoiceVoter : Voter {
enum class Action : ActionI {
VIEW
}
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean {
return (action is Action)
.and(subject is OpinionChoice? || subject is List<*>)
}
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote {
if (action == Action.VIEW) {
if (subject is OpinionChoice) {
return Vote.GRANTED
}
if (subject is List<*>) {
subject.forEach {
if (it !is OpinionChoice) {
return Vote.DENIED
}
}
return Vote.GRANTED
}
return Vote.DENIED
}
return Vote.ABSTAIN
}
}