Move opinions to component

This commit is contained in:
2021-01-22 21:11:04 +01:00
parent 73e96c0c46
commit c92d0b5640
24 changed files with 244 additions and 170 deletions

View File

@@ -0,0 +1,38 @@
package fr.dcproject.component.opinion.routes
import fr.dcproject.component.article.ArticleRef
import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.opinion.OpinionVoter
import fr.dcproject.component.opinion.entity.Opinion
import fr.dcproject.utils.toUUID
import fr.dcproject.voter.assert
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 org.koin.core.KoinComponent
import java.util.UUID
import fr.dcproject.component.citizen.Citizen as CitizenEntity
import fr.dcproject.repository.OpinionRepositoryArticle as OpinionArticleRepository
@KtorExperimentalLocationsAPI
object GetCitizenOpinions {
/**
* Get all Opinion of citizen on targets by target ids
*/
@Location("/citizens/{citizen}/opinions")
class CitizenOpinions(val citizen: CitizenEntity, id: List<String>) : KoinComponent {
val id: List<UUID> = id.toUUID()
}
fun Route.getCitizenOpinions(repo: OpinionArticleRepository, voter: OpinionVoter) {
get<CitizenOpinions> {
val opinionsEntities: List<Opinion<ArticleRef>> = repo.findCitizenOpinionsByTargets(it.citizen, it.id)
voter.assert { canView(opinionsEntities, citizenOrNull) }
call.respond(opinionsEntities)
}
}
}

View File

@@ -0,0 +1,37 @@
package fr.dcproject.component.opinion.routes
import fr.dcproject.component.auth.citizen
import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.citizen.CitizenRef
import fr.dcproject.component.opinion.OpinionVoter
import fr.dcproject.routes.PaginatedRequest
import fr.dcproject.routes.PaginatedRequestI
import fr.dcproject.voter.assert
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.OpinionRepositoryArticle as OpinionArticleRepository
@KtorExperimentalLocationsAPI
object GetMyOpinionsArticle {
/**
* Get paginated opinions of citizen for all articles
*/
@Location("/citizens/{citizen}/opinions/articles")
class CitizenOpinionsArticleRequest(
val citizen: CitizenRef,
page: Int = 1,
limit: Int = 50
) : PaginatedRequestI by PaginatedRequest(page, limit)
fun Route.getMyOpinionsArticle(repo: OpinionArticleRepository, voter: OpinionVoter) {
get<CitizenOpinionsArticleRequest> {
val opinions = repo.findCitizenOpinions(citizen, it.page, it.limit)
voter.assert { canView(opinions.result, citizenOrNull) }
call.respond(opinions)
}
}
}

View File

@@ -0,0 +1,26 @@
package fr.dcproject.component.opinion.routes
import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.opinion.OpinionChoiceVoter
import fr.dcproject.component.opinion.entity.OpinionChoice
import fr.dcproject.voter.assert
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
@KtorExperimentalLocationsAPI
object GetOpinionChoice {
@Location("/opinions/{opinionChoice}")
class OpinionChoiceRequest(val opinionChoice: OpinionChoice)
fun Route.getOpinionChoice(voter: OpinionChoiceVoter) {
get<OpinionChoiceRequest> {
voter.assert { canView(it.opinionChoice, citizenOrNull) }
call.respond(it.opinionChoice)
}
}
}

View File

@@ -0,0 +1,27 @@
package fr.dcproject.component.opinion.routes
import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.opinion.OpinionChoiceVoter
import fr.dcproject.voter.assert
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.OpinionChoiceRepository as OpinionChoiceRepository
@KtorExperimentalLocationsAPI
object GetOpinionChoices {
@Location("/opinions")
class OpinionChoicesRequest(val targets: List<String> = emptyList())
fun Route.getOpinionChoices(repo: OpinionChoiceRepository, voter: OpinionChoiceVoter) {
get<OpinionChoicesRequest> {
val opinionChoices = repo.findOpinionsChoices(it.targets)
voter.assert { canView(opinionChoices, citizenOrNull) }
call.respond(opinionChoices)
}
}
}

View File

@@ -0,0 +1,50 @@
package fr.dcproject.component.opinion.routes
import fr.dcproject.component.article.ArticleForView
import fr.dcproject.component.auth.citizen
import fr.dcproject.component.auth.citizenOrNull
import fr.dcproject.component.opinion.OpinionVoter
import fr.dcproject.component.opinion.entity.OpinionChoiceRef
import fr.dcproject.component.opinion.entity.OpinionForUpdate
import fr.dcproject.utils.toUUID
import fr.dcproject.voter.assert
import io.ktor.application.call
import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.put
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.routing.Route
import java.util.UUID
import fr.dcproject.repository.OpinionRepositoryArticle as OpinionArticleRepository
@KtorExperimentalLocationsAPI
object OpinionArticle {
/**
* Put an opinion on one article
*/
@Location("/articles/{article}/opinions")
class ArticleOpinion(val article: ArticleForView) {
class Body(ids: List<String>) {
val ids: List<UUID> = ids.map { it.toUUID() }
}
}
fun Route.setOpinionOnArticle(repo: OpinionArticleRepository, voter: OpinionVoter) {
put<ArticleOpinion> {
call.receive<ArticleOpinion.Body>().ids.map { id ->
OpinionForUpdate(
choice = OpinionChoiceRef(id),
target = it.article,
createdBy = citizen
)
}.let { opinions ->
voter.assert { canCreate(opinions, citizenOrNull) }
repo.updateOpinions(opinions)
}.let {
call.respond(HttpStatusCode.Created, it)
}
}
}
}

View File

@@ -0,0 +1,22 @@
package fr.dcproject.component.opinion.routes
import fr.dcproject.component.opinion.routes.GetCitizenOpinions.getCitizenOpinions
import fr.dcproject.component.opinion.routes.GetMyOpinionsArticle.getMyOpinionsArticle
import fr.dcproject.component.opinion.routes.GetOpinionChoice.getOpinionChoice
import fr.dcproject.component.opinion.routes.GetOpinionChoices.getOpinionChoices
import fr.dcproject.component.opinion.routes.OpinionArticle.setOpinionOnArticle
import io.ktor.auth.authenticate
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.routing.Routing
import org.koin.ktor.ext.get
@KtorExperimentalLocationsAPI
fun Routing.installOpinionRoutes() {
authenticate(optional = true) {
getCitizenOpinions(get(), get())
getMyOpinionsArticle(get(), get())
setOpinionOnArticle(get(), get())
getOpinionChoice(get())
getOpinionChoices(get(), get())
}
}