Big refactoring #77
@@ -41,9 +41,7 @@ import fr.dcproject.component.workgroup.routes.members.UpdateMemberOfWorkgroup.u
|
||||
import fr.dcproject.event.EventNotification
|
||||
import fr.dcproject.event.EventSubscriber
|
||||
import fr.dcproject.routes.*
|
||||
import fr.dcproject.security.voter.OpinionChoiceVoter
|
||||
import fr.ktorVoter.AuthorizationVoter
|
||||
import fr.ktorVoter.VoterException
|
||||
import fr.dcproject.voter.VoterDeniedException
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.ktor.application.*
|
||||
import io.ktor.auth.*
|
||||
@@ -89,12 +87,6 @@ fun Application.module(env: Env = PROD) {
|
||||
|
||||
install(Locations)
|
||||
|
||||
install(AuthorizationVoter) {
|
||||
voters = listOf(
|
||||
OpinionChoiceVoter()
|
||||
)
|
||||
}
|
||||
|
||||
HttpClient(Jetty) {
|
||||
engine {
|
||||
}
|
||||
@@ -176,7 +168,7 @@ fun Application.module(env: Env = PROD) {
|
||||
voteArticle(get(), get(), get(), get())
|
||||
voteConstitution(get(), get())
|
||||
opinionArticle(get(), get())
|
||||
opinionChoice(get())
|
||||
opinionChoice(get(), get())
|
||||
definition()
|
||||
}
|
||||
|
||||
@@ -198,7 +190,7 @@ fun Application.module(env: Env = PROD) {
|
||||
exception<NotFoundException> { e ->
|
||||
call.respond(HttpStatusCode.NotFound, e.message!!)
|
||||
}
|
||||
exception<VoterException> {
|
||||
exception<VoterDeniedException> {
|
||||
if (call.user == null) call.respond(HttpStatusCode.Unauthorized)
|
||||
else call.respond(HttpStatusCode.Forbidden)
|
||||
}
|
||||
|
||||
@@ -23,10 +23,7 @@ import fr.dcproject.event.publisher.Publisher
|
||||
import fr.dcproject.messages.Mailer
|
||||
import fr.dcproject.messages.NotificationEmailSender
|
||||
import fr.dcproject.repository.CommentConstitutionRepository
|
||||
import fr.dcproject.security.voter.ConstitutionVoter
|
||||
import fr.dcproject.security.voter.FollowVoter
|
||||
import fr.dcproject.security.voter.OpinionVoter
|
||||
import fr.dcproject.security.voter.VoteVoter
|
||||
import fr.dcproject.security.voter.*
|
||||
import fr.postgresjson.connexion.Connection
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import fr.postgresjson.migration.Migrations
|
||||
@@ -131,6 +128,7 @@ val KoinModule = module {
|
||||
single { VoteVoter() }
|
||||
single { FollowVoter() }
|
||||
single { OpinionVoter() }
|
||||
single { OpinionChoiceVoter() }
|
||||
|
||||
// Elasticsearch Client
|
||||
single<RestClient> {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package fr.dcproject.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.entity.OpinionChoice
|
||||
import fr.dcproject.security.voter.OpinionChoiceVoter.Action.VIEW
|
||||
import fr.ktorVoter.assertCan
|
||||
import fr.ktorVoter.assertCanAll
|
||||
import fr.dcproject.security.voter.OpinionChoiceVoter
|
||||
import fr.dcproject.voter.assert
|
||||
import io.ktor.application.*
|
||||
import io.ktor.locations.*
|
||||
import io.ktor.response.*
|
||||
@@ -20,17 +20,17 @@ object OpinionChoicePaths {
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
fun Route.opinionChoice(repo: OpinionChoiceRepository) {
|
||||
fun Route.opinionChoice(repo: OpinionChoiceRepository, voter: OpinionChoiceVoter) {
|
||||
get<OpinionChoicePaths.OpinionChoiceRequest> {
|
||||
assertCan(VIEW, it.opinionChoice)
|
||||
voter.assert { canView(it.opinionChoice, citizenOrNull) }
|
||||
|
||||
call.respond(it.opinionChoice)
|
||||
}
|
||||
|
||||
get<OpinionChoicePaths.OpinionChoicesRequest> {
|
||||
val opinions = repo.findOpinionsChoices(it.targets)
|
||||
assertCanAll(VIEW, opinions)
|
||||
val opinionChoices = repo.findOpinionsChoices(it.targets)
|
||||
voter.assert { canView(opinionChoices, citizenOrNull) }
|
||||
|
||||
call.respond(opinions)
|
||||
call.respond(opinionChoices)
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,15 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.entity.OpinionChoice
|
||||
import fr.dcproject.voter.NoSubjectDefinedException
|
||||
import fr.ktorVoter.*
|
||||
import io.ktor.application.*
|
||||
import fr.dcproject.voter.Voter
|
||||
import fr.dcproject.voter.VoterResponse
|
||||
|
||||
class OpinionChoiceVoter : Voter<ApplicationCall> {
|
||||
enum class Action : ActionI {
|
||||
VIEW
|
||||
}
|
||||
class OpinionChoiceVoter : Voter() {
|
||||
fun canView(subjects: List<OpinionChoice>, citizen: CitizenI?): VoterResponse =
|
||||
canAll(subjects) { canView(it, citizen) }
|
||||
|
||||
override fun invoke(action: Any, context: ApplicationCall, subject: Any?): VoterResponseI {
|
||||
if (!((action is Action) &&
|
||||
(subject is OpinionChoice?))) return abstain()
|
||||
|
||||
if (action == Action.VIEW) {
|
||||
if (subject is OpinionChoice) {
|
||||
fun canView(subject: OpinionChoice, citizen: CitizenI?): VoterResponse {
|
||||
return granted()
|
||||
}
|
||||
throw NoSubjectDefinedException(action)
|
||||
}
|
||||
|
||||
return abstain()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,19 +3,12 @@ package unit.voter
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.component.auth.User
|
||||
import fr.dcproject.component.auth.UserI
|
||||
import fr.dcproject.component.auth.user
|
||||
import fr.dcproject.component.citizen.CitizenBasic
|
||||
import fr.dcproject.component.citizen.CitizenCart
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.entity.OpinionChoice
|
||||
import fr.dcproject.security.voter.OpinionChoiceVoter
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.can
|
||||
import fr.ktorVoter.canAll
|
||||
import io.ktor.application.*
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import fr.dcproject.voter.Vote.GRANTED
|
||||
import io.mockk.mockkStatic
|
||||
import org.amshove.kluent.`should be`
|
||||
import org.joda.time.DateTime
|
||||
@@ -68,32 +61,16 @@ internal class OpinionChoiceVoterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `support opinion choice`(): Unit = OpinionChoiceVoter().run {
|
||||
val p = object : ActionI {}
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
this(OpinionChoiceVoter.Action.VIEW, it, choice1).vote `should be` Vote.GRANTED
|
||||
this(OpinionChoiceVoter.Action.VIEW, it, article1).vote `should be` Vote.ABSTAIN
|
||||
this(p, it, choice1).vote `should be` Vote.ABSTAIN
|
||||
}
|
||||
fun `can be view the opinion choice`() {
|
||||
OpinionChoiceVoter()
|
||||
.canView(choice1, tesla)
|
||||
.vote `should be` GRANTED
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can be view the opinion choice`(): Unit = listOf(OpinionChoiceVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
can(OpinionChoiceVoter.Action.VIEW, it, choice1) `should be` true
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can be view the opinion choice list`(): Unit = listOf(OpinionChoiceVoter()).run {
|
||||
mockk<ApplicationCall> {
|
||||
every { user } returns tesla.user
|
||||
}.let {
|
||||
canAll(OpinionChoiceVoter.Action.VIEW, it, listOf(choice1)) `should be` true
|
||||
}
|
||||
fun `can be view the opinion choice list`() {
|
||||
OpinionChoiceVoter()
|
||||
.canView(listOf(choice1), tesla)
|
||||
.vote `should be` GRANTED
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user