#24 Move voter code to an external library
This commit is contained in:
@@ -87,6 +87,7 @@ dependencies {
|
||||
implementation("com.auth0:java-jwt:3.8.2")
|
||||
implementation("com.github.jasync-sql:jasync-postgresql:1.0.7")
|
||||
implementation("fr.postgresjson:postgresjson:$postgresjson_version")
|
||||
implementation("fr.ktor-voter:ktor-voter:1.0.0")
|
||||
implementation("com.sendgrid:sendgrid-java:4.4.1")
|
||||
implementation("io.lettuce:lettuce-core:5.2.2.RELEASE")
|
||||
implementation("com.rabbitmq:amqp-client:5.8.0")
|
||||
|
||||
@@ -13,6 +13,8 @@ import fr.dcproject.event.EventSubscriber
|
||||
import fr.dcproject.event.configEvent
|
||||
import fr.dcproject.routes.*
|
||||
import fr.dcproject.security.voter.*
|
||||
import fr.ktorVoter.AuthorizationVoter
|
||||
import fr.ktorVoter.ForbiddenException
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.ktor.application.Application
|
||||
import io.ktor.application.ApplicationCall
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package fr.dcproject
|
||||
|
||||
import fr.dcproject.entity.User
|
||||
import fr.dcproject.entity.UserI
|
||||
import fr.dcproject.security.voter.ForbiddenException
|
||||
import fr.ktorVoter.ForbiddenException
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.auth.authentication
|
||||
import io.ktor.util.AttributeKey
|
||||
@@ -26,3 +27,5 @@ val ApplicationCall.citizenOrNull: CitizenEntity?
|
||||
|
||||
val PipelineContext<Unit, ApplicationCall>.citizen get() = context.citizen
|
||||
val PipelineContext<Unit, ApplicationCall>.citizenOrNull get() = context.citizenOrNull
|
||||
|
||||
val ApplicationCall.user get() = authentication.principal<User>()
|
||||
|
||||
@@ -6,7 +6,7 @@ import fr.dcproject.event.ArticleUpdate
|
||||
import fr.dcproject.repository.Article.Filter
|
||||
import fr.dcproject.security.voter.ArticleVoter.Action.CREATE
|
||||
import fr.dcproject.security.voter.ArticleVoter.Action.VIEW
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import fr.dcproject.views.ArticleViewManager
|
||||
import fr.postgresjson.repository.RepositoryI
|
||||
import io.ktor.application.application
|
||||
|
||||
@@ -9,7 +9,7 @@ import fr.dcproject.routes.CitizenPaths.CitizensRequest
|
||||
import fr.dcproject.routes.CitizenPaths.CurrentCitizenRequest
|
||||
import fr.dcproject.security.voter.CitizenVoter.Action.CHANGE_PASSWORD
|
||||
import fr.dcproject.security.voter.CitizenVoter.Action.VIEW
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import fr.postgresjson.repository.RepositoryI.Direction
|
||||
import io.ktor.application.call
|
||||
import io.ktor.auth.UserPasswordCredential
|
||||
|
||||
@@ -5,7 +5,7 @@ import fr.dcproject.entity.Comment
|
||||
import fr.dcproject.entity.CommentRef
|
||||
import fr.dcproject.routes.CommentPaths.CreateCommentRequest.Content
|
||||
import fr.dcproject.security.voter.CommentVoter.Action.*
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import io.ktor.application.call
|
||||
import io.ktor.features.NotFoundException
|
||||
import io.ktor.http.HttpStatusCode
|
||||
|
||||
@@ -6,7 +6,7 @@ import fr.dcproject.entity.Citizen
|
||||
import fr.dcproject.repository.CommentArticle.Sort
|
||||
import fr.dcproject.security.voter.CommentVoter.Action.CREATE
|
||||
import fr.dcproject.security.voter.CommentVoter.Action.VIEW
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -5,7 +5,7 @@ import fr.dcproject.entity.Citizen
|
||||
import fr.dcproject.entity.ConstitutionRef
|
||||
import fr.dcproject.security.voter.CommentVoter.Action.CREATE
|
||||
import fr.dcproject.security.voter.CommentVoter.Action.VIEW
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -4,7 +4,7 @@ import fr.dcproject.citizen
|
||||
import fr.dcproject.entity.request.Constitution
|
||||
import fr.dcproject.security.voter.ConstitutionVoter.Action.CREATE
|
||||
import fr.dcproject.security.voter.ConstitutionVoter.Action.VIEW
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import fr.postgresjson.repository.RepositoryI
|
||||
import io.ktor.application.call
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -4,7 +4,7 @@ import fr.dcproject.citizen
|
||||
import fr.dcproject.entity.ArticleRef
|
||||
import fr.dcproject.entity.Citizen
|
||||
import fr.dcproject.security.voter.FollowVoter.Action.*
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.*
|
||||
|
||||
@@ -4,7 +4,7 @@ import fr.dcproject.citizen
|
||||
import fr.dcproject.entity.CitizenRef
|
||||
import fr.dcproject.entity.ConstitutionRef
|
||||
import fr.dcproject.security.voter.FollowVoter.Action.*
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.*
|
||||
|
||||
@@ -7,7 +7,7 @@ import fr.dcproject.entity.request.RequestBuilder
|
||||
import fr.dcproject.entity.request.getContent
|
||||
import fr.dcproject.security.voter.OpinionVoter.Action.CREATE
|
||||
import fr.dcproject.security.voter.OpinionVoter.Action.VIEW
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import fr.dcproject.utils.toUUID
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.application.call
|
||||
|
||||
@@ -2,7 +2,7 @@ package fr.dcproject.routes
|
||||
|
||||
import fr.dcproject.entity.OpinionChoice
|
||||
import fr.dcproject.security.voter.OpinionChoiceVoter.Action.VIEW
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import io.ktor.application.call
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
|
||||
@@ -8,7 +8,7 @@ import fr.dcproject.routes.VoteArticlePaths.ArticleVoteRequest
|
||||
import fr.dcproject.routes.VoteArticlePaths.CommentVoteRequest
|
||||
import fr.dcproject.security.voter.VoteVoter.Action.CREATE
|
||||
import fr.dcproject.security.voter.VoteVoter.Action.VIEW
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import fr.dcproject.utils.toUUID
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
|
||||
@@ -4,7 +4,7 @@ import fr.dcproject.citizen
|
||||
import fr.dcproject.entity.Citizen
|
||||
import fr.dcproject.routes.VoteConstitutionPaths.ConstitutionVoteRequest.Content
|
||||
import fr.dcproject.security.voter.VoteVoter.Action.CREATE
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -12,7 +12,7 @@ import fr.dcproject.security.voter.WorkgroupVoter.Action.UPDATE
|
||||
import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.ADD as ADD_MEMBERS
|
||||
import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.UPDATE as UPDATE_MEMBERS
|
||||
import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.REMOVE as REMOVE_MEMBERS
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.ktorVoter.assertCan
|
||||
import fr.dcproject.utils.toUUID
|
||||
import fr.postgresjson.repository.RepositoryI
|
||||
import io.ktor.application.ApplicationCall
|
||||
|
||||
@@ -3,6 +3,11 @@ package fr.dcproject.security.voter
|
||||
import fr.dcproject.entity.ArticleAuthI
|
||||
import fr.dcproject.entity.ArticleI
|
||||
import fr.dcproject.entity.UserI
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import fr.ktorVoter.checkClass
|
||||
import io.ktor.application.ApplicationCall
|
||||
import fr.dcproject.entity.Comment as CommentEntity
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.isSubclassOf
|
||||
|
||||
class WrongClassException(
|
||||
expected: KClass<*>,
|
||||
current: KClass<*>?
|
||||
) : VoterException("Can not define authorization with class $current. Need $expected")
|
||||
|
||||
fun Voter.checkClass(
|
||||
expected: KClass<*>,
|
||||
subject: Any?
|
||||
) {
|
||||
if (subject != null && !subject::class.isSubclassOf(expected)) {
|
||||
throw WrongClassException(expected, subject::class)
|
||||
} else if (subject == null) {
|
||||
throw WrongClassException(expected, null)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,10 @@ package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.CitizenBasicI
|
||||
import fr.dcproject.entity.UserI
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.Comment
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import io.ktor.application.ApplicationCall
|
||||
|
||||
class CommentVoter : Voter {
|
||||
|
||||
@@ -3,6 +3,10 @@ package fr.dcproject.security.voter
|
||||
import fr.dcproject.entity.Comment
|
||||
import fr.dcproject.entity.ConstitutionSimple
|
||||
import fr.dcproject.entity.UserI
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import io.ktor.application.ApplicationCall
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import io.ktor.application.ApplicationCall
|
||||
import fr.dcproject.entity.Follow as FollowEntity
|
||||
import fr.dcproject.entity.User as UserEntity
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.OpinionChoice
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import io.ktor.application.ApplicationCall
|
||||
|
||||
class OpinionChoiceVoter : Voter {
|
||||
|
||||
@@ -2,6 +2,10 @@ package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.ArticleAuthI
|
||||
import fr.dcproject.entity.Opinion
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import io.ktor.application.ApplicationCall
|
||||
|
||||
class OpinionVoter : Voter {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import io.ktor.application.ApplicationCall
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.User
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.application.ApplicationCallPipeline
|
||||
import io.ktor.application.ApplicationFeature
|
||||
import io.ktor.auth.authentication
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.util.AttributeKey
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import io.ktor.util.pipeline.PipelineContext
|
||||
|
||||
interface ActionI
|
||||
|
||||
interface Voter {
|
||||
fun supports(action: ActionI, call: ApplicationCall, subject: Any? = null): Boolean
|
||||
fun vote(action: ActionI, call: ApplicationCall, subject: Any? = null): Vote
|
||||
}
|
||||
|
||||
fun List<Voter>.can(action: ActionI, call: ApplicationCall, subject: Any? = null): Boolean {
|
||||
val listOfSubject: List<Any?> = if (subject !is List<*>) listOf(subject) else subject
|
||||
val votes: List<Vote> = listOfSubject.flatMap { subject ->
|
||||
this
|
||||
.filter { it.supports(action, call, subject) }
|
||||
.ifEmpty { throw NoVoterException(action) }
|
||||
.map { it.vote(action, call, subject) }
|
||||
}
|
||||
|
||||
return votes.all { it in listOf(Vote.GRANTED, Vote.ABSTAIN) } and votes.any { it == Vote.GRANTED }
|
||||
}
|
||||
|
||||
enum class Vote {
|
||||
GRANTED,
|
||||
ABSTAIN,
|
||||
DENIED;
|
||||
|
||||
companion object {
|
||||
fun isGranted(lambda: () -> Boolean): Vote {
|
||||
return if (lambda()) GRANTED else DENIED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val votersAttributeKey = AttributeKey<List<Voter>>("voters")
|
||||
|
||||
fun ApplicationCall.assertCan(action: ActionI, subject: Any? = null, agreeIfNullOrEmpty: Boolean = true) {
|
||||
val isNullOrEmpty = (subject == null || (subject is Collection<*> && subject.isNullOrEmpty()))
|
||||
if (!can(action, subject) && !agreeIfNullOrEmpty && isNullOrEmpty) {
|
||||
throw UnauthorizedException(action)
|
||||
}
|
||||
}
|
||||
|
||||
fun PipelineContext<Unit, ApplicationCall>.assertCan(action: ActionI, subject: Any? = null, agreeIfNullOrEmpty: Boolean = true) =
|
||||
context.assertCan(action, subject, agreeIfNullOrEmpty)
|
||||
|
||||
fun PipelineContext<Unit, ApplicationCall>.can(action: ActionI, subject: Any? = null) =
|
||||
context.can(action, subject)
|
||||
|
||||
fun ApplicationCall.can(action: ActionI, subject: Any? = null): Boolean {
|
||||
val voters = attributes[votersAttributeKey]
|
||||
|
||||
return voters.can(action, this, subject)
|
||||
}
|
||||
|
||||
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(message: String? = null) : Throwable(message)
|
||||
|
||||
val ApplicationCall.user get() = authentication.principal<User>()
|
||||
|
||||
class AuthorizationVoter {
|
||||
|
||||
/**
|
||||
* Configuration for [AuthorizationVoter] feature.
|
||||
*/
|
||||
class Configuration {
|
||||
var voters = mutableListOf<Voter>()
|
||||
fun voter(voter: Voter) = voters.add(voter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Object for installing feature
|
||||
*/
|
||||
companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, AuthorizationVoter> {
|
||||
|
||||
override val key = AttributeKey<AuthorizationVoter>("Voter")
|
||||
|
||||
@KtorExperimentalAPI
|
||||
override fun install(
|
||||
pipeline: ApplicationCallPipeline,
|
||||
configure: Configuration.() -> Unit
|
||||
): AuthorizationVoter {
|
||||
val configuration = Configuration().apply(configure)
|
||||
|
||||
pipeline.intercept(ApplicationCallPipeline.Features) {
|
||||
context.attributes.put(votersAttributeKey, configuration.voters)
|
||||
|
||||
try {
|
||||
proceed()
|
||||
} catch (e: VoterException) {
|
||||
context.respond(HttpStatusCode.Forbidden)
|
||||
}
|
||||
}
|
||||
|
||||
return AuthorizationVoter()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,11 @@ package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.citizenOrNull
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import fr.ktorVoter.VoterException
|
||||
import io.ktor.application.ApplicationCall
|
||||
|
||||
class WorkgroupVoter : Voter {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.can
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
@@ -34,7 +37,7 @@ internal class ArticleVoterTest {
|
||||
)
|
||||
|
||||
init {
|
||||
mockkStatic("fr.dcproject.security.voter.VoterKt")
|
||||
mockkStatic("fr.dcproject.ApplicationContextKt")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.entity.CitizenBasic
|
||||
import fr.dcproject.entity.CitizenI
|
||||
import fr.dcproject.entity.User
|
||||
import fr.dcproject.entity.UserI
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.can
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.mockk.every
|
||||
@@ -46,7 +52,7 @@ internal class CitizenVoterTest {
|
||||
).apply { deletedAt = DateTime.now() }
|
||||
|
||||
init {
|
||||
mockkStatic("fr.dcproject.security.voter.VoterKt")
|
||||
mockkStatic("fr.dcproject.ApplicationContextKt")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.can
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.mockk.every
|
||||
@@ -66,7 +69,7 @@ internal class CommentVoterTest {
|
||||
)
|
||||
|
||||
init {
|
||||
mockkStatic("fr.dcproject.security.voter.VoterKt")
|
||||
mockkStatic("fr.dcproject.ApplicationContextKt")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.can
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.mockk.every
|
||||
@@ -56,7 +59,7 @@ internal class FollowVoterTest {
|
||||
)
|
||||
|
||||
init {
|
||||
mockkStatic("fr.dcproject.security.voter.VoterKt")
|
||||
mockkStatic("fr.dcproject.ApplicationContextKt")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.can
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.mockk.every
|
||||
@@ -40,7 +43,7 @@ internal class OpinionChoiceVoterTest {
|
||||
)
|
||||
|
||||
init {
|
||||
mockkStatic("fr.dcproject.security.voter.VoterKt")
|
||||
mockkStatic("fr.dcproject.ApplicationContextKt")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.can
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.mockk.every
|
||||
@@ -55,7 +58,7 @@ internal class OpinionVoterTest {
|
||||
)
|
||||
|
||||
init {
|
||||
mockkStatic("fr.dcproject.security.voter.VoterKt")
|
||||
mockkStatic("fr.dcproject.ApplicationContextKt")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.can
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.mockk.every
|
||||
@@ -12,6 +14,7 @@ import org.joda.time.DateTime
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@@ -70,7 +73,7 @@ internal class VoteVoterTest {
|
||||
)
|
||||
|
||||
init {
|
||||
mockkStatic("fr.dcproject.security.voter.VoterKt")
|
||||
mockkStatic("fr.dcproject.ApplicationContextKt")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.VoterException
|
||||
import fr.ktorVoter.can
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.mockk.every
|
||||
@@ -66,7 +70,7 @@ internal class WorkgroupVoterTest {
|
||||
private val workgroupref = WorkgroupRef()
|
||||
|
||||
init {
|
||||
mockkStatic("fr.dcproject.security.voter.VoterKt")
|
||||
mockkStatic("fr.dcproject.ApplicationContextKt")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user