Big refactoring #77

Merged
flecomte merged 166 commits from refactoring-component-and-immutable into master 2021-03-24 19:06:07 +01:00
5 changed files with 30 additions and 74 deletions
Showing only changes of commit 64fa0912b8 - Show all commits

View File

@@ -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)
}

View File

@@ -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> {

View File

@@ -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)
}
}

View File

@@ -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()
}
}

View File

@@ -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
}
}