From 03401f711e054acebaf8e6fc18f1332b27a7fe30 Mon Sep 17 00:00:00 2001 From: Fabrice Lecomte Date: Mon, 5 Oct 2020 15:00:34 +0200 Subject: [PATCH] Update ktor-voter to version 2.2.0 --- build.gradle.kts | 6 +- src/main/kotlin/Application.kt | 6 +- src/main/kotlin/Module.kt | 8 +- src/main/kotlin/entity/Article.kt | 28 ++++--- src/main/kotlin/routes/Article.kt | 23 +++--- src/main/kotlin/routes/Citizen.kt | 20 +++-- src/main/kotlin/routes/Comment.kt | 22 ++--- src/main/kotlin/routes/CommentArticle.kt | 21 +++-- src/main/kotlin/routes/CommentConstitution.kt | 20 +++-- src/main/kotlin/routes/Constitution.kt | 17 ++-- src/main/kotlin/routes/FollowArticle.kt | 15 ++-- src/main/kotlin/routes/FollowConstitution.kt | 15 ++-- src/main/kotlin/routes/OpinionArticle.kt | 22 +++-- src/main/kotlin/routes/OpinionChoice.kt | 13 ++- src/main/kotlin/routes/VoteArticle.kt | 22 +++-- src/main/kotlin/routes/Workgroup.kt | 14 ++-- src/main/kotlin/voter/ArticleVoter.kt | 39 ++++----- src/main/kotlin/voter/CitizenVoter.kt | 20 ++--- src/main/kotlin/voter/CommentVoter.kt | 19 ++--- src/main/kotlin/voter/ConstitutionVoter.kt | 12 ++- src/main/kotlin/voter/FollowVoter.kt | 12 ++- src/main/kotlin/voter/OpinionChoiceVoter.kt | 10 +-- src/main/kotlin/voter/OpinionVoter.kt | 37 ++++----- src/main/kotlin/voter/VoteVoter.kt | 15 ++-- src/main/kotlin/voter/WorkgroupVoter.kt | 18 ++--- src/test/kotlin/ArticleTest.kt | 4 +- src/test/kotlin/ConstitutionTest.kt | 3 +- src/test/kotlin/FollowTest.kt | 3 +- src/test/kotlin/ViewTest.kt | 6 +- src/test/kotlin/VoteTest.kt | 5 +- .../kotlin/security/voter/ArticleVoterTest.kt | 80 +++++++++++-------- .../kotlin/security/voter/CitizenVoterTest.kt | 26 +++--- .../kotlin/security/voter/CommentVoterTest.kt | 56 ++++++++----- .../kotlin/security/voter/FollowVoterTest.kt | 28 ++++--- .../security/voter/OpinionChoiceVoterTest.kt | 16 ++-- .../kotlin/security/voter/OpinionVoterTest.kt | 28 ++++--- .../kotlin/security/voter/VoteVoterTest.kt | 41 +++++----- .../security/voter/WorkgroupVoterTest.kt | 37 +++++---- 38 files changed, 403 insertions(+), 384 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 14a4ff0..365afee 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.owasp.dependencycheck.reporting.ReportGenerator -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.slf4j.LoggerFactory val ktor_version: String by project @@ -139,7 +139,7 @@ dependencies { implementation("com.auth0:java-jwt:3.8.2") implementation("com.github.jasync-sql:jasync-postgresql:1.0.7") implementation("com.github.flecomte:postgres-json:1.2.1") - implementation("com.github.flecomte:ktor-voter:1.0.1") + implementation("com.github.flecomte:ktor-voter:2.2.1") 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") @@ -152,7 +152,7 @@ dependencies { testImplementation("org.koin:koin-test:$koinVersion") testImplementation("io.mockk:mockk:1.9.3") testImplementation("org.junit.jupiter:junit-jupiter:5.5.0") - testImplementation("org.amshove.kluent:kluent:1.4") + testImplementation("org.amshove.kluent:kluent:1.61") testImplementation("io.cucumber:cucumber-java8:$cucumber_version") testImplementation("io.cucumber:cucumber-junit:$cucumber_version") } diff --git a/src/main/kotlin/Application.kt b/src/main/kotlin/Application.kt index 4b459ff..47979f7 100644 --- a/src/main/kotlin/Application.kt +++ b/src/main/kotlin/Application.kt @@ -38,6 +38,7 @@ import io.ktor.response.respond import io.ktor.routing.Routing import io.ktor.util.KtorExperimentalAPI import io.ktor.websocket.WebSockets +import kotlinx.coroutines.ExperimentalCoroutinesApi import org.eclipse.jetty.util.log.Slf4jLog import org.koin.core.qualifier.named import org.koin.ktor.ext.Koin @@ -58,6 +59,7 @@ fun main(args: Array): Unit = io.ktor.server.jetty.EngineMain.main(args) enum class Env { PROD, TEST, CUCUMBER } +@ExperimentalCoroutinesApi @KtorExperimentalAPI @KtorExperimentalLocationsAPI @Suppress("unused") // Referenced in application.conf @@ -173,8 +175,8 @@ fun Application.module(env: Env = PROD) { } install(AuthorizationVoter) { - voters = mutableListOf( - ArticleVoter(), + voters = listOf( + ArticleVoter(get()), ConstitutionVoter(), CitizenVoter(), CommentVoter(), diff --git a/src/main/kotlin/Module.kt b/src/main/kotlin/Module.kt index c107cea..039bdb6 100644 --- a/src/main/kotlin/Module.kt +++ b/src/main/kotlin/Module.kt @@ -16,9 +16,9 @@ import fr.dcproject.views.ArticleViewManager import fr.postgresjson.connexion.Connection import fr.postgresjson.connexion.Requester import fr.postgresjson.migration.Migrations -import io.ktor.client.HttpClient -import io.ktor.client.features.websocket.WebSockets -import io.ktor.util.KtorExperimentalAPI +import io.ktor.client.* +import io.ktor.client.features.websocket.* +import io.ktor.util.* import io.lettuce.core.RedisClient import io.lettuce.core.api.async.RedisAsyncCommands import org.apache.http.HttpHost @@ -123,7 +123,7 @@ val Module = module { single { ArticleViewManager(get()) } - // Mailler + // Mailer single { Mailer(Config.sendGridKey) } // SSO Manager for connection diff --git a/src/main/kotlin/entity/Article.kt b/src/main/kotlin/entity/Article.kt index b468868..0007e62 100644 --- a/src/main/kotlin/entity/Article.kt +++ b/src/main/kotlin/entity/Article.kt @@ -19,6 +19,7 @@ class Article( override val createdBy: CitizenBasic, workgroup: WorkgroupSimple? = null ) : ArticleFull, + ArticleForUpdateI, ArticleAuthI, ArticleSimple(id, title, createdBy, draft, workgroup), Viewable by ViewableImp() { @@ -26,19 +27,28 @@ class Article( tags = tags.distinct() } } - +interface ArticleForUpdateI: ArticleI, EntityVersioning, TargetI { + val title: String + val anonymous: Boolean + val content: String + val description: String + val draft: Boolean + val createdBy: CitizenRef + val workgroup: WorkgroupRef? +} class ArticleForUpdate( id: UUID?, - val title: String, - val anonymous: Boolean = true, - val content: String, - val description: String, + override val title: String, + override val anonymous: Boolean = true, + override val content: String, + override val description: String, tags: List = emptyList(), - val draft: Boolean = false, - val createdBy: CitizenRef, - val workgroup: WorkgroupRef? = null, + override val draft: Boolean = false, + override val createdBy: CitizenRef, + override val workgroup: WorkgroupRef? = null, versionId: UUID? -) : ArticleRefVersioning(id, versionId = versionId ?: UUID.randomUUID()) { +) : ArticleForUpdateI, + ArticleRefVersioning(id, versionId = versionId ?: UUID.randomUUID()) { val tags: List = tags.distinct() val isNew = versionId == null } diff --git a/src/main/kotlin/routes/Article.kt b/src/main/kotlin/routes/Article.kt index 8dc5a3b..c3f1efd 100644 --- a/src/main/kotlin/routes/Article.kt +++ b/src/main/kotlin/routes/Article.kt @@ -3,34 +3,29 @@ package fr.dcproject.routes import fr.dcproject.citizen import fr.dcproject.citizenOrNull import fr.dcproject.entity.ArticleForUpdate -import fr.dcproject.entity.CitizenRef import fr.dcproject.entity.WorkgroupRef -import fr.dcproject.entity.WorkgroupSimple import fr.dcproject.event.ArticleUpdate import fr.dcproject.event.raiseEvent import fr.dcproject.repository.Article.Filter -import fr.dcproject.repository.Workgroup as WorkgroupRepository import fr.dcproject.security.voter.ArticleVoter.Action.CREATE import fr.dcproject.security.voter.ArticleVoter.Action.UPDATE import fr.dcproject.security.voter.ArticleVoter.Action.VIEW import fr.dcproject.views.ArticleViewManager import fr.ktorVoter.assertCan +import fr.ktorVoter.assertCanAll import fr.postgresjson.repository.RepositoryI -import io.ktor.application.ApplicationCall -import io.ktor.application.call -import io.ktor.locations.KtorExperimentalLocationsAPI -import io.ktor.locations.Location -import io.ktor.locations.get -import io.ktor.locations.post -import io.ktor.request.receive -import io.ktor.response.respond -import io.ktor.routing.Route +import io.ktor.application.* +import io.ktor.locations.* +import io.ktor.request.* +import io.ktor.response.* +import io.ktor.routing.* import kotlinx.coroutines.launch import org.koin.core.KoinComponent import org.koin.core.inject import java.util.* import fr.dcproject.entity.Article as ArticleEntity import fr.dcproject.repository.Article as ArticleRepository +import fr.dcproject.repository.Workgroup as WorkgroupRepository @KtorExperimentalLocationsAPI object ArticlesPaths { @@ -90,7 +85,7 @@ object ArticlesPaths { tags = tags, draft = draft, createdBy = call.citizen, - workgroup = if (workgroup != null) workgroupRepository.findById(workgroup.id) as WorkgroupSimple else null, + workgroup = if (workgroup != null) workgroupRepository.findById(workgroup.id) else null, versionId = versionId ) } @@ -108,7 +103,7 @@ fun Route.article(repo: ArticleRepository, viewManager: ArticleViewManager) { it.search, Filter(createdById = it.createdBy, workgroupId = it.workgroup) ) - assertCan(VIEW, articles.result) + assertCanAll(VIEW, articles.result) call.respond(articles) } diff --git a/src/main/kotlin/routes/Citizen.kt b/src/main/kotlin/routes/Citizen.kt index b693882..dbe1036 100644 --- a/src/main/kotlin/routes/Citizen.kt +++ b/src/main/kotlin/routes/Citizen.kt @@ -11,17 +11,15 @@ 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.ktorVoter.assertCan +import fr.ktorVoter.assertCanAll import fr.postgresjson.repository.RepositoryI.Direction -import io.ktor.application.call -import io.ktor.auth.UserPasswordCredential -import io.ktor.http.HttpStatusCode -import io.ktor.locations.KtorExperimentalLocationsAPI -import io.ktor.locations.Location -import io.ktor.locations.get -import io.ktor.locations.put -import io.ktor.request.receive -import io.ktor.response.respond -import io.ktor.routing.Route +import io.ktor.application.* +import io.ktor.auth.* +import io.ktor.http.* +import io.ktor.locations.* +import io.ktor.request.* +import io.ktor.response.* +import io.ktor.routing.* import fr.dcproject.repository.Citizen as CitizenRepository import fr.dcproject.repository.User as UserRepository @@ -58,7 +56,7 @@ fun Route.citizen( ) { get { val citizens = repo.find(it.page, it.limit, it.sort, it.direction, it.search) - assertCan(VIEW, citizens.result) + assertCanAll(VIEW, citizens.result) call.respond(citizens) } diff --git a/src/main/kotlin/routes/Comment.kt b/src/main/kotlin/routes/Comment.kt index 36e0f59..94091bd 100644 --- a/src/main/kotlin/routes/Comment.kt +++ b/src/main/kotlin/routes/Comment.kt @@ -4,17 +4,19 @@ import fr.dcproject.citizen 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.CommentVoter.Action.CREATE +import fr.dcproject.security.voter.CommentVoter.Action.UPDATE +import fr.dcproject.security.voter.CommentVoter.Action.VIEW import fr.ktorVoter.assertCan -import io.ktor.application.call -import io.ktor.features.NotFoundException -import io.ktor.http.HttpStatusCode +import fr.ktorVoter.assertCanAll +import io.ktor.application.* +import io.ktor.features.* +import io.ktor.http.* import io.ktor.locations.* -import io.ktor.request.receive -import io.ktor.request.receiveText -import io.ktor.response.respond -import io.ktor.routing.Route -import io.ktor.util.KtorExperimentalAPI +import io.ktor.request.* +import io.ktor.response.* +import io.ktor.routing.* +import io.ktor.util.* import java.util.* import fr.dcproject.repository.CommentGeneric as CommentRepository @@ -58,7 +60,7 @@ fun Route.comment(repo: CommentRepository) { it.limit ) - assertCan(VIEW, comments.result) + assertCanAll(VIEW, comments.result) call.respond(HttpStatusCode.OK, comments) } diff --git a/src/main/kotlin/routes/CommentArticle.kt b/src/main/kotlin/routes/CommentArticle.kt index 6222f0f..347c5b6 100644 --- a/src/main/kotlin/routes/CommentArticle.kt +++ b/src/main/kotlin/routes/CommentArticle.kt @@ -7,16 +7,13 @@ import fr.dcproject.repository.CommentArticle.Sort import fr.dcproject.security.voter.CommentVoter.Action.CREATE import fr.dcproject.security.voter.CommentVoter.Action.VIEW import fr.ktorVoter.assertCan -import io.ktor.application.ApplicationCall -import io.ktor.application.call -import io.ktor.http.HttpStatusCode -import io.ktor.locations.KtorExperimentalLocationsAPI -import io.ktor.locations.Location -import io.ktor.locations.get -import io.ktor.locations.post -import io.ktor.request.receive -import io.ktor.response.respond -import io.ktor.routing.Route +import fr.ktorVoter.assertCanAll +import io.ktor.application.* +import io.ktor.http.* +import io.ktor.locations.* +import io.ktor.request.* +import io.ktor.response.* +import io.ktor.routing.* import fr.dcproject.entity.Comment as CommentEntity import fr.dcproject.repository.CommentArticle as CommentArticleRepository @@ -61,7 +58,7 @@ fun Route.commentArticle(repo: CommentArticleRepository) { get { val comment = repo.findByTarget(it.article, it.page, it.limit, it.sort) if (comment.result.isNotEmpty()) { - assertCan(VIEW, comment.result) + assertCanAll(VIEW, comment.result) } call.respond(HttpStatusCode.OK, comment) } @@ -76,7 +73,7 @@ fun Route.commentArticle(repo: CommentArticleRepository) { get { repo.findByCitizen(it.citizen).let { comments -> - assertCan(VIEW, comments.result) + assertCanAll(VIEW, comments.result) call.respond(comments) } } diff --git a/src/main/kotlin/routes/CommentConstitution.kt b/src/main/kotlin/routes/CommentConstitution.kt index 889b9ad..574fd4b 100644 --- a/src/main/kotlin/routes/CommentConstitution.kt +++ b/src/main/kotlin/routes/CommentConstitution.kt @@ -6,15 +6,13 @@ import fr.dcproject.entity.ConstitutionRef import fr.dcproject.security.voter.CommentVoter.Action.CREATE import fr.dcproject.security.voter.CommentVoter.Action.VIEW import fr.ktorVoter.assertCan -import io.ktor.application.call -import io.ktor.http.HttpStatusCode -import io.ktor.locations.KtorExperimentalLocationsAPI -import io.ktor.locations.Location -import io.ktor.locations.get -import io.ktor.locations.post -import io.ktor.request.receiveText -import io.ktor.response.respond -import io.ktor.routing.Route +import fr.ktorVoter.assertCanAll +import io.ktor.application.* +import io.ktor.http.* +import io.ktor.locations.* +import io.ktor.request.* +import io.ktor.response.* +import io.ktor.routing.* import fr.dcproject.entity.Comment as CommentEntity import fr.dcproject.repository.CommentConstitution as CommentConstitutionRepository @@ -31,7 +29,7 @@ object CommentConstitutionPaths { fun Route.commentConstitution(repo: CommentConstitutionRepository) { get { val comments = repo.findByTarget(it.constitution) - assertCan(VIEW, comments.result) + assertCanAll(VIEW, comments.result) call.respond(HttpStatusCode.OK, comments) } @@ -50,7 +48,7 @@ fun Route.commentConstitution(repo: CommentConstitutionRepository) { get { val comments = repo.findByCitizen(it.citizen) - assertCan(VIEW, comments.result) + assertCanAll(VIEW, comments.result) call.respond(comments) } } \ No newline at end of file diff --git a/src/main/kotlin/routes/Constitution.kt b/src/main/kotlin/routes/Constitution.kt index a78765a..95b7ded 100644 --- a/src/main/kotlin/routes/Constitution.kt +++ b/src/main/kotlin/routes/Constitution.kt @@ -7,17 +7,14 @@ import fr.dcproject.entity.ConstitutionSimple import fr.dcproject.security.voter.ConstitutionVoter.Action.CREATE import fr.dcproject.security.voter.ConstitutionVoter.Action.VIEW import fr.ktorVoter.assertCan +import fr.ktorVoter.assertCanAll import fr.postgresjson.entity.immutable.UuidEntity import fr.postgresjson.repository.RepositoryI -import io.ktor.application.ApplicationCall -import io.ktor.application.call -import io.ktor.locations.KtorExperimentalLocationsAPI -import io.ktor.locations.Location -import io.ktor.locations.get -import io.ktor.locations.post -import io.ktor.request.receive -import io.ktor.response.respond -import io.ktor.routing.Route +import io.ktor.application.* +import io.ktor.locations.* +import io.ktor.request.* +import io.ktor.response.* +import io.ktor.routing.* import java.util.* import fr.dcproject.entity.Constitution as ConstitutionEntity import fr.dcproject.repository.Constitution as ConstitutionRepository @@ -86,7 +83,7 @@ object ConstitutionPaths { fun Route.constitution(repo: ConstitutionRepository) { get { val constitutions = repo.find(it.page, it.limit, it.sort, it.direction, it.search) - assertCan(VIEW, constitutions.result) + assertCanAll(VIEW, constitutions.result) call.respond(constitutions) } diff --git a/src/main/kotlin/routes/FollowArticle.kt b/src/main/kotlin/routes/FollowArticle.kt index 8ae7b15..ab40658 100644 --- a/src/main/kotlin/routes/FollowArticle.kt +++ b/src/main/kotlin/routes/FollowArticle.kt @@ -3,13 +3,16 @@ package fr.dcproject.routes 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.FollowVoter.Action.CREATE +import fr.dcproject.security.voter.FollowVoter.Action.DELETE +import fr.dcproject.security.voter.FollowVoter.Action.VIEW import fr.ktorVoter.assertCan -import io.ktor.application.call -import io.ktor.http.HttpStatusCode +import fr.ktorVoter.assertCanAll +import io.ktor.application.* +import io.ktor.http.* import io.ktor.locations.* -import io.ktor.response.respond -import io.ktor.routing.Route +import io.ktor.response.* +import io.ktor.routing.* import fr.dcproject.entity.Follow as FollowEntity import fr.dcproject.repository.FollowArticle as FollowArticleRepository @@ -48,7 +51,7 @@ fun Route.followArticle(repo: FollowArticleRepository) { get { val follows = repo.findByCitizen(it.citizen) if (follows.result.isNotEmpty()) { - assertCan(VIEW, follows.result) + assertCanAll(VIEW, follows.result) } call.respond(follows) } diff --git a/src/main/kotlin/routes/FollowConstitution.kt b/src/main/kotlin/routes/FollowConstitution.kt index 1b7e8b4..6f95a18 100644 --- a/src/main/kotlin/routes/FollowConstitution.kt +++ b/src/main/kotlin/routes/FollowConstitution.kt @@ -3,13 +3,16 @@ package fr.dcproject.routes 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.FollowVoter.Action.CREATE +import fr.dcproject.security.voter.FollowVoter.Action.DELETE +import fr.dcproject.security.voter.FollowVoter.Action.VIEW import fr.ktorVoter.assertCan -import io.ktor.application.call -import io.ktor.http.HttpStatusCode +import fr.ktorVoter.assertCanAll +import io.ktor.application.* +import io.ktor.http.* import io.ktor.locations.* -import io.ktor.response.respond -import io.ktor.routing.Route +import io.ktor.response.* +import io.ktor.routing.* import fr.dcproject.entity.Follow as FollowEntity import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository @@ -47,7 +50,7 @@ fun Route.followConstitution(repo: FollowConstitutionRepository) { get { val follows = repo.findByCitizen(it.citizen) - assertCan(VIEW, follows.result) + assertCanAll(VIEW, follows.result) call.respond(follows) } } diff --git a/src/main/kotlin/routes/OpinionArticle.kt b/src/main/kotlin/routes/OpinionArticle.kt index 5e6c666..58e562c 100644 --- a/src/main/kotlin/routes/OpinionArticle.kt +++ b/src/main/kotlin/routes/OpinionArticle.kt @@ -5,18 +5,16 @@ import fr.dcproject.entity.CitizenRef import fr.dcproject.entity.OpinionChoiceRef import fr.dcproject.security.voter.OpinionVoter.Action.CREATE import fr.dcproject.security.voter.OpinionVoter.Action.VIEW -import fr.ktorVoter.assertCan import fr.dcproject.utils.toUUID -import io.ktor.application.call -import io.ktor.http.HttpStatusCode -import io.ktor.locations.KtorExperimentalLocationsAPI -import io.ktor.locations.Location -import io.ktor.locations.get -import io.ktor.locations.put -import io.ktor.request.receive -import io.ktor.response.respond -import io.ktor.routing.Route -import io.ktor.util.KtorExperimentalAPI +import fr.ktorVoter.assertCan +import fr.ktorVoter.assertCanAll +import io.ktor.application.* +import io.ktor.http.* +import io.ktor.locations.* +import io.ktor.request.* +import io.ktor.response.* +import io.ktor.routing.* +import io.ktor.util.* import org.koin.core.KoinComponent import org.koin.core.get import java.util.* @@ -67,7 +65,7 @@ fun Route.opinionArticle(repo: OpinionArticleRepository) { } get { - assertCan(VIEW, it.opinionsEntities) + assertCanAll(VIEW, it.opinionsEntities) call.respond(it.opinionsEntities) } diff --git a/src/main/kotlin/routes/OpinionChoice.kt b/src/main/kotlin/routes/OpinionChoice.kt index b23d714..a80ce97 100644 --- a/src/main/kotlin/routes/OpinionChoice.kt +++ b/src/main/kotlin/routes/OpinionChoice.kt @@ -3,12 +3,11 @@ package fr.dcproject.routes import fr.dcproject.entity.OpinionChoice import fr.dcproject.security.voter.OpinionChoiceVoter.Action.VIEW import fr.ktorVoter.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.ktorVoter.assertCanAll +import io.ktor.application.* +import io.ktor.locations.* +import io.ktor.response.* +import io.ktor.routing.* import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository @KtorExperimentalLocationsAPI @@ -30,7 +29,7 @@ fun Route.opinionChoice(repo: OpinionChoiceRepository) { get { val opinions = repo.findOpinionsChoices(it.targets) - assertCan(VIEW, opinions) + assertCanAll(VIEW, opinions) call.respond(opinions) } diff --git a/src/main/kotlin/routes/VoteArticle.kt b/src/main/kotlin/routes/VoteArticle.kt index 8aa21a0..8838871 100644 --- a/src/main/kotlin/routes/VoteArticle.kt +++ b/src/main/kotlin/routes/VoteArticle.kt @@ -8,17 +8,15 @@ 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.ktorVoter.assertCan import fr.dcproject.utils.toUUID -import io.ktor.application.call -import io.ktor.http.HttpStatusCode -import io.ktor.locations.KtorExperimentalLocationsAPI -import io.ktor.locations.Location -import io.ktor.locations.get -import io.ktor.locations.put -import io.ktor.request.receive -import io.ktor.response.respond -import io.ktor.routing.Route +import fr.ktorVoter.assertCan +import fr.ktorVoter.assertCanAll +import io.ktor.application.* +import io.ktor.http.* +import io.ktor.locations.* +import io.ktor.request.* +import io.ktor.response.* +import io.ktor.routing.* import java.util.* import fr.dcproject.entity.Article as ArticleEntity import fr.dcproject.entity.Vote as VoteEntity @@ -79,7 +77,7 @@ fun Route.voteArticle(repo: VoteArticleRepository, voteCommentRepo: VoteComment, get { val votes = repo.findByCitizen(it.citizen, it.page, it.limit) - assertCan(VIEW, votes.result) + assertCanAll(VIEW, votes.result) call.respond(votes) } @@ -87,7 +85,7 @@ fun Route.voteArticle(repo: VoteArticleRepository, voteCommentRepo: VoteComment, get { val votes = repo.findCitizenVotesByTargets(it.citizen, it.id) if (votes.isNotEmpty()) { - assertCan(VIEW, votes) + assertCanAll(VIEW, votes) } call.respond(votes) } diff --git a/src/main/kotlin/routes/Workgroup.kt b/src/main/kotlin/routes/Workgroup.kt index b198d88..df01bae 100644 --- a/src/main/kotlin/routes/Workgroup.kt +++ b/src/main/kotlin/routes/Workgroup.kt @@ -11,14 +11,14 @@ import fr.dcproject.security.voter.WorkgroupVoter.Action.UPDATE import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW import fr.dcproject.utils.toUUID import fr.ktorVoter.assertCan +import fr.ktorVoter.assertCanAll import fr.postgresjson.repository.RepositoryI -import io.ktor.application.ApplicationCall -import io.ktor.application.call -import io.ktor.http.HttpStatusCode +import io.ktor.application.* +import io.ktor.http.* import io.ktor.locations.* -import io.ktor.request.receive -import io.ktor.response.respond -import io.ktor.routing.Route +import io.ktor.request.* +import io.ktor.response.* +import io.ktor.routing.* import java.util.* import fr.dcproject.entity.Workgroup as WorkgroupEntity import fr.dcproject.repository.Workgroup as WorkgroupRepository @@ -115,7 +115,7 @@ fun Route.workgroup(repo: WorkgroupRepository) { get { val workgroups = repo.find(it.page, it.limit, it.sort, it.direction, it.search, Filter(createdById = it.createdBy, members = it.members)) - assertCan(VIEW, workgroups.result) + assertCanAll(VIEW, workgroups.result) call.respond(workgroups) } diff --git a/src/main/kotlin/voter/ArticleVoter.kt b/src/main/kotlin/voter/ArticleVoter.kt index db65314..f92468b 100644 --- a/src/main/kotlin/voter/ArticleVoter.kt +++ b/src/main/kotlin/voter/ArticleVoter.kt @@ -2,7 +2,7 @@ package fr.dcproject.security.voter import fr.dcproject.citizenOrNull import fr.dcproject.entity.ArticleAuthI -import fr.dcproject.entity.ArticleForUpdate +import fr.dcproject.entity.ArticleForUpdateI import fr.dcproject.entity.ArticleI import fr.dcproject.entity.Citizen as CitizenEntity import fr.dcproject.entity.CitizenI @@ -11,16 +11,15 @@ import fr.dcproject.repository.Article as ArticleRepo import fr.dcproject.user import fr.ktorVoter.ActionI import fr.ktorVoter.Vote +import fr.ktorVoter.Vote.Companion.toVote import fr.ktorVoter.Voter -import fr.ktorVoter.checkClass import io.ktor.application.ApplicationCall import org.koin.core.KoinComponent import org.koin.core.inject import fr.dcproject.entity.Comment as CommentEntity import fr.dcproject.entity.Vote as VoteEntity -class ArticleVoter : Voter, KoinComponent { - private val articleRepo: ArticleRepo by inject() +class ArticleVoter(private val articleRepo: ArticleRepo) : Voter { enum class Action : ActionI { CREATE, UPDATE, @@ -28,17 +27,16 @@ class ArticleVoter : Voter, KoinComponent { DELETE } - override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { - return (action is Action || action is CommentVoter.Action || action is VoteVoter.Action) - .and(subject is ArticleI? || subject is VoteEntity<*> || subject is CommentEntity<*>) - } + override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote { + if (!((action is Action || action is CommentVoter.Action || action is VoteVoter.Action) + && (subject is ArticleI? || subject is VoteEntity<*> || subject is CommentEntity<*>)) + ) return Vote.ABSTAIN - override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { - val user = call.user + val user = context.user if (action == Action.CREATE && user is UserI) return Vote.GRANTED if (action == Action.VIEW) return view(subject, user) if (action == Action.DELETE) return delete(subject, user) - if (action == Action.UPDATE) return update(subject, call.citizenOrNull) + if (action == Action.UPDATE) return update(subject, context.citizenOrNull) if (action is CommentVoter.Action) return voteForComment(action, subject) if (action is VoteVoter.Action) return voteForVote(action, subject) if (action is Action) return Vote.DENIED @@ -47,7 +45,6 @@ class ArticleVoter : Voter, KoinComponent { } private fun view(subject: Any?, user: UserI?): Vote { - checkClass(ArticleAuthI::class, subject) if (subject is ArticleAuthI<*>) { return if (subject.isDeleted()) Vote.DENIED else if (subject.draft && (user == null || subject.createdBy.user.id != user.id)) Vote.DENIED @@ -57,7 +54,6 @@ class ArticleVoter : Voter, KoinComponent { } private fun delete(subject: Any?, user: UserI?): Vote { - checkClass(ArticleAuthI::class, subject) if (subject is ArticleAuthI<*>) { if (user is UserI && subject.createdBy.user.id == user.id) { return Vote.GRANTED @@ -67,15 +63,14 @@ class ArticleVoter : Voter, KoinComponent { } private fun update(subject: Any?, citizen: CitizenEntity?): Vote { - checkClass(ArticleForUpdate::class, subject) - if (subject is ArticleForUpdate) { - /* The new Article must by created by the same citizen of the connected citizen */ - if (citizen is CitizenI && subject.createdBy.id == citizen.id) { - /* The creator must be the same of the creator of preview version of article */ - if(articleRepo.findVerionsByVersionsId(1, 1, subject.versionId).result.first().createdBy.id == citizen.id) { - return Vote.GRANTED - } - return Vote.DENIED + /* The new Article must by created by the same citizen of the connected citizen */ + if (subject is ArticleForUpdateI && citizen is CitizenI && subject.createdBy.id == citizen.id) { + /* The creator must be the same of the creator of preview version of article */ + return toVote { + articleRepo + .findVerionsByVersionsId(1, 1, subject.versionId) + .result.first() + .createdBy.id == citizen.id } } return Vote.DENIED diff --git a/src/main/kotlin/voter/CitizenVoter.kt b/src/main/kotlin/voter/CitizenVoter.kt index 9e2c8c2..dfc8210 100644 --- a/src/main/kotlin/voter/CitizenVoter.kt +++ b/src/main/kotlin/voter/CitizenVoter.kt @@ -10,7 +10,7 @@ import io.ktor.application.ApplicationCall import io.ktor.locations.KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI -class CitizenVoter : Voter { +class CitizenVoter : Voter { enum class Action : ActionI { CREATE, UPDATE, @@ -19,13 +19,11 @@ class CitizenVoter : Voter { CHANGE_PASSWORD } - override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { - return (action is Action) - .and(subject is CitizenBasicI?) - } + override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote { + if (!((action is Action) + && (subject is CitizenBasicI?))) return Vote.ABSTAIN - override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { - val user = call.user + val user = context.user if (action == Action.CREATE && user != null) { return Vote.GRANTED } @@ -56,14 +54,10 @@ class CitizenVoter : Voter { return if (user.id == userToChange.id) { Vote.GRANTED } else { - Vote.ABSTAIN + Vote.DENIED } } - if (action is Action) { - return Vote.DENIED - } - - return Vote.ABSTAIN + return Vote.DENIED } } diff --git a/src/main/kotlin/voter/CommentVoter.kt b/src/main/kotlin/voter/CommentVoter.kt index 8f8bc41..00f9749 100644 --- a/src/main/kotlin/voter/CommentVoter.kt +++ b/src/main/kotlin/voter/CommentVoter.kt @@ -7,7 +7,7 @@ import fr.ktorVoter.Vote import fr.ktorVoter.Voter import io.ktor.application.ApplicationCall -class CommentVoter : Voter { +class CommentVoter : Voter { enum class Action : ActionI { CREATE, UPDATE, @@ -15,15 +15,12 @@ class CommentVoter : Voter { DELETE } - override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { - return (action is Action) - .and(subject is Comment<*>?) - } + override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote { + if (!(action is Action && subject is Comment<*>?)) return Vote.ABSTAIN - override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { - val user = call.user + val user = context.user - if (subject !is Comment<*>) { + if (subject == null) { return Vote.DENIED } @@ -50,10 +47,6 @@ class CommentVoter : Voter { return Vote.DENIED } - if (action is Action) { - return Vote.DENIED - } - - return Vote.ABSTAIN + return Vote.DENIED } } diff --git a/src/main/kotlin/voter/ConstitutionVoter.kt b/src/main/kotlin/voter/ConstitutionVoter.kt index 2bbcbe9..773330c 100644 --- a/src/main/kotlin/voter/ConstitutionVoter.kt +++ b/src/main/kotlin/voter/ConstitutionVoter.kt @@ -10,7 +10,7 @@ import fr.ktorVoter.Voter import io.ktor.application.ApplicationCall import fr.dcproject.entity.Vote as VoteEntity -class ConstitutionVoter : Voter { +class ConstitutionVoter : Voter { enum class Action : ActionI { CREATE, UPDATE, @@ -18,13 +18,11 @@ class ConstitutionVoter : Voter { DELETE } - override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { - return (action is Action || action is CommentVoter.Action || action is VoteVoter.Action) - .and(subject is ConstitutionSimple<*, *>? || subject is VoteEntity<*> || subject is Comment<*>) - } + override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote { + if(!((action is Action || action is CommentVoter.Action || action is VoteVoter.Action) + && (subject is ConstitutionSimple<*, *>? || subject is VoteEntity<*> || subject is Comment<*>))) return Vote.ABSTAIN - override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { - val user = call.user + val user = context.user if (action == Action.CREATE && user != null) { return Vote.GRANTED } diff --git a/src/main/kotlin/voter/FollowVoter.kt b/src/main/kotlin/voter/FollowVoter.kt index 312c2cc..0d81f69 100644 --- a/src/main/kotlin/voter/FollowVoter.kt +++ b/src/main/kotlin/voter/FollowVoter.kt @@ -8,20 +8,18 @@ import io.ktor.application.ApplicationCall import fr.dcproject.entity.Follow as FollowEntity import fr.dcproject.entity.User as UserEntity -class FollowVoter : Voter { +class FollowVoter : Voter { enum class Action : ActionI { CREATE, DELETE, VIEW } - override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { - return (action is Action) - .and(subject is FollowEntity<*>?) - } + override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote { + if (!((action is Action) + && (subject is FollowEntity<*>?))) return Vote.ABSTAIN - override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { - val user = call.user + val user = context.user if (action == Action.CREATE) { return if (user != null) Vote.GRANTED else Vote.DENIED diff --git a/src/main/kotlin/voter/OpinionChoiceVoter.kt b/src/main/kotlin/voter/OpinionChoiceVoter.kt index 280e8d6..b4beacd 100644 --- a/src/main/kotlin/voter/OpinionChoiceVoter.kt +++ b/src/main/kotlin/voter/OpinionChoiceVoter.kt @@ -6,17 +6,15 @@ import fr.ktorVoter.Vote import fr.ktorVoter.Voter import io.ktor.application.ApplicationCall -class OpinionChoiceVoter : Voter { +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?) - } + override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote { + if (!((action is Action) + && (subject is OpinionChoice?))) return Vote.ABSTAIN - override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { if (action == Action.VIEW) { if (subject is OpinionChoice) { return Vote.GRANTED diff --git a/src/main/kotlin/voter/OpinionVoter.kt b/src/main/kotlin/voter/OpinionVoter.kt index 571b165..9104dfc 100644 --- a/src/main/kotlin/voter/OpinionVoter.kt +++ b/src/main/kotlin/voter/OpinionVoter.kt @@ -1,49 +1,46 @@ package fr.dcproject.security.voter +import fr.dcproject.entity.Article 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.Vote.Companion.toVote import fr.ktorVoter.Voter import io.ktor.application.ApplicationCall -class OpinionVoter : Voter { +class OpinionVoter : Voter { enum class Action : ActionI { CREATE, VIEW, DELETE } - override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { - return (action is Action) - .and(subject is Opinion<*>? || subject is ArticleAuthI<*>) - } + override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote { + if (!((action is Action) + && (subject is Opinion<*>? || subject is ArticleAuthI<*>))) return Vote.ABSTAIN - override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { - val user = call.user + val user = context.user if (action == Action.CREATE) { - return if (user != null && ( - (subject is ArticleAuthI<*> && !subject.isDeleted()) || - (subject is Opinion<*> && subject.createdBy.user.id == user.id) - )) Vote.GRANTED - else Vote.DENIED + return toVote { + user != null && ( + (subject is ArticleAuthI<*> && !subject.isDeleted()) || + (subject is Opinion<*> && subject.createdBy.user.id == user.id) + ) + } } if (action == Action.VIEW) { - if (subject is Opinion<*>) { - return Vote.GRANTED - } - return Vote.DENIED + return toVote { subject is Opinion<*> || subject is Article } } if (action == Action.DELETE) { - return if (subject is Opinion<*> && + return toVote { + subject is Opinion<*> && user != null && subject.createdBy.user.id == user.id - ) - Vote.GRANTED - else Vote.DENIED + } } return Vote.ABSTAIN diff --git a/src/main/kotlin/voter/VoteVoter.kt b/src/main/kotlin/voter/VoteVoter.kt index bd1e7f2..70e839b 100644 --- a/src/main/kotlin/voter/VoteVoter.kt +++ b/src/main/kotlin/voter/VoteVoter.kt @@ -7,23 +7,22 @@ import fr.ktorVoter.Voter import io.ktor.application.ApplicationCall import fr.dcproject.entity.Vote as VoteEntity -class VoteVoter : Voter { +class VoteVoter : Voter { enum class Action : ActionI { CREATE, VIEW } - override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { - return action is Action && subject is VoteEntity<*>? - } + override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote { + if (!(action is Action && subject is VoteEntity<*>?)) return Vote.ABSTAIN - override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { - val user = call.user - if (action == Action.CREATE && user != null) { + val user = context.user ?: return Vote.DENIED + + if (action == Action.CREATE) { return Vote.GRANTED } - if (action == Action.VIEW && user != null) { + if (action == Action.VIEW) { if (subject is VoteEntity<*>) { return if (subject.createdBy.user.id != user.id) { Vote.DENIED diff --git a/src/main/kotlin/voter/WorkgroupVoter.kt b/src/main/kotlin/voter/WorkgroupVoter.kt index 5192c77..29f6154 100644 --- a/src/main/kotlin/voter/WorkgroupVoter.kt +++ b/src/main/kotlin/voter/WorkgroupVoter.kt @@ -9,7 +9,7 @@ import fr.ktorVoter.Voter import fr.ktorVoter.VoterException import io.ktor.application.ApplicationCall -class WorkgroupVoter : Voter { +class WorkgroupVoter : Voter { enum class Action : ActionI { CREATE, UPDATE, @@ -24,13 +24,11 @@ class WorkgroupVoter : Voter { REMOVE, } - override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { - return (action is Action || action is ActionMembers) - .and(subject is WorkgroupI?) - } + override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote { + if (!((action is Action || action is ActionMembers) + && (subject is WorkgroupI? || (subject is List<*> && subject.first() is WorkgroupI)))) return Vote.ABSTAIN - override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { - val user = call.user + val user = context.user if (subject is WorkgroupI && action == Action.CREATE && user is UserI) { return Vote.GRANTED } @@ -62,7 +60,7 @@ class WorkgroupVoter : Voter { if (action == ActionMembers.ADD) { // TODO create ROLES - return Vote.isGranted { + return Vote.toVote { user is UserI && subject is WorkgroupWithAuthI<*> && subject.hasRole(Role.MASTER, user) @@ -71,7 +69,7 @@ class WorkgroupVoter : Voter { if (action == ActionMembers.UPDATE) { // TODO create ROLES - return Vote.isGranted { + return Vote.toVote { user is UserI && subject is WorkgroupWithAuthI<*> && subject.hasRole(Role.MASTER, user) @@ -80,7 +78,7 @@ class WorkgroupVoter : Voter { if (action == ActionMembers.REMOVE) { // TODO create ROLES - return Vote.isGranted { + return Vote.toVote { user is UserI && subject is WorkgroupWithAuthI<*> && subject.hasRole(Role.MASTER, user) diff --git a/src/test/kotlin/ArticleTest.kt b/src/test/kotlin/ArticleTest.kt index 3d447c6..1744d28 100644 --- a/src/test/kotlin/ArticleTest.kt +++ b/src/test/kotlin/ArticleTest.kt @@ -6,7 +6,7 @@ import fr.postgresjson.serializer.deserialize import fr.postgresjson.serializer.serialize import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.util.KtorExperimentalAPI -import org.amshove.kluent.`should equal` +import org.amshove.kluent.`should be equal to` import org.amshove.kluent.shouldBe import org.intellij.lang.annotations.Language import org.joda.time.DateTime @@ -96,6 +96,6 @@ class ArticleTest { @Test fun `test Article Deserialize`() { val article2: Article = articleJson.deserialize()!! - article2.id.toString() `should equal` "83b0b60a-5ab3-44f2-b243-1dc469a7564f" + article2.id.toString() `should be equal to` "83b0b60a-5ab3-44f2-b243-1dc469a7564f" } } diff --git a/src/test/kotlin/ConstitutionTest.kt b/src/test/kotlin/ConstitutionTest.kt index bd69fff..d362a31 100644 --- a/src/test/kotlin/ConstitutionTest.kt +++ b/src/test/kotlin/ConstitutionTest.kt @@ -6,6 +6,7 @@ import fr.postgresjson.serializer.deserialize import fr.postgresjson.serializer.serialize import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.util.KtorExperimentalAPI +import org.amshove.kluent.`should be equal to` import org.amshove.kluent.`should equal` import org.amshove.kluent.shouldBe import org.intellij.lang.annotations.Language @@ -101,6 +102,6 @@ class ConstitutionTest { @Test fun `test Constitution Deserialize`() { val constitution2: Constitution = constitutionJson.deserialize()!! - constitution2.id.toString() `should equal` "15814bb6-8d90-4c6a-a456-c3939a8ec75e" + constitution2.id.toString() `should be equal to` "15814bb6-8d90-4c6a-a456-c3939a8ec75e" } } diff --git a/src/test/kotlin/FollowTest.kt b/src/test/kotlin/FollowTest.kt index 49a7cff..66aa221 100644 --- a/src/test/kotlin/FollowTest.kt +++ b/src/test/kotlin/FollowTest.kt @@ -3,6 +3,7 @@ import fr.postgresjson.serializer.deserialize import fr.postgresjson.serializer.serialize import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.util.KtorExperimentalAPI +import org.amshove.kluent.`should be equal to` import org.amshove.kluent.`should equal` import org.amshove.kluent.shouldBe import org.intellij.lang.annotations.Language @@ -103,6 +104,6 @@ class FollowTest { @Test fun `test Follow Article Deserialize`() { val follow: Follow = followJson.deserialize()!! - follow.id.toString() `should equal` "bae81585-d985-4d7a-9b58-3a13e911688a" + follow.id.toString() `should be equal to` "bae81585-d985-4d7a-9b58-3a13e911688a" } } diff --git a/src/test/kotlin/ViewTest.kt b/src/test/kotlin/ViewTest.kt index 6e903e6..60f21fc 100644 --- a/src/test/kotlin/ViewTest.kt +++ b/src/test/kotlin/ViewTest.kt @@ -6,7 +6,7 @@ import fr.dcproject.views.ArticleViewManager import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.server.testing.withTestApplication import io.ktor.util.KtorExperimentalAPI -import org.amshove.kluent.`should equal` +import org.amshove.kluent.`should be equal to` import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS @@ -61,8 +61,8 @@ class ViewTest { val afterView = viewManager.getViewsCount(article) /* Check if view has increment */ - afterView.total `should equal` startView.total + 4 - afterView.unique `should equal` startView.unique + 3 + afterView.total `should be equal to` startView.total + 4 + afterView.unique `should be equal to` startView.unique + 3 } } } diff --git a/src/test/kotlin/VoteTest.kt b/src/test/kotlin/VoteTest.kt index 0526eef..d012a4b 100644 --- a/src/test/kotlin/VoteTest.kt +++ b/src/test/kotlin/VoteTest.kt @@ -3,6 +3,7 @@ import fr.postgresjson.serializer.deserialize import fr.postgresjson.serializer.serialize import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.util.KtorExperimentalAPI +import org.amshove.kluent.`should be equal to` import org.amshove.kluent.`should equal` import org.amshove.kluent.shouldBe import org.intellij.lang.annotations.Language @@ -125,7 +126,7 @@ class VoteTest { @Test fun `test Vote Article Deserialize`() { val vote: Vote
= voteJson.deserialize()!! - vote.id.toString() `should equal` "032acc3d-e8c5-4cb2-9297-bec913ff8d9b" - vote.note.toString() `should equal` "-1" + vote.id.toString() `should be equal to` "032acc3d-e8c5-4cb2-9297-bec913ff8d9b" + vote.note.toString() `should be equal to` "-1" } } diff --git a/src/test/kotlin/security/voter/ArticleVoterTest.kt b/src/test/kotlin/security/voter/ArticleVoterTest.kt index 9014168..06cfa88 100644 --- a/src/test/kotlin/security/voter/ArticleVoterTest.kt +++ b/src/test/kotlin/security/voter/ArticleVoterTest.kt @@ -1,9 +1,12 @@ package fr.dcproject.security.voter +import fr.dcproject.citizenOrNull import fr.dcproject.entity.* import fr.dcproject.user import fr.ktorVoter.Vote import fr.ktorVoter.can +import fr.ktorVoter.canAll +import fr.postgresjson.connexion.Paginated import io.ktor.application.ApplicationCall import io.mockk.every import io.mockk.mockk @@ -13,11 +16,12 @@ 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.repository.Article as ArticleRepo @TestInstance(TestInstance.Lifecycle.PER_CLASS) @Tag("voter") -internal class ArticleVoterTest { - val tesla = CitizenBasic( +class ArticleVoterTest { + private val tesla = Citizen( user = User( username = "nicolas-tesla", roles = listOf(UserI.Roles.ROLE_USER) @@ -26,7 +30,7 @@ internal class ArticleVoterTest { email = "tesla@best.com", name = CitizenI.Name("Nicolas", "Tesla") ) - val einstein = CitizenBasic( + private val einstein = Citizen( user = User( username = "albert-einstein", roles = listOf(UserI.Roles.ROLE_USER) @@ -36,24 +40,30 @@ internal class ArticleVoterTest { name = CitizenI.Name("Albert", "Einstein") ) + private fun getRepo(article: Article): ArticleRepo { + return mockk { + every { findVerionsByVersionsId(1, 1, any()) } returns Paginated(listOf(article), 0, 1, 1) + } + } + init { mockkStatic("fr.dcproject.ApplicationContextKt") } @Test - fun `creator can be view the article`() = ArticleVoter().run { + fun `creator can be view the article`(): Unit { val article = getArticle(tesla).apply { draft = true } - - mockk { - every { user } returns tesla.user - }.let { - supports(ArticleVoter.Action.VIEW, it, article) `should be` true - vote(ArticleVoter.Action.VIEW, it, article) `should be` Vote.GRANTED + ArticleVoter(getRepo(article)).run { + mockk { + every { user } returns tesla.user + }.let { + this(ArticleVoter.Action.VIEW, it, article) `should be` Vote.GRANTED + } } } @Test - fun `other user can be view the article`() = listOf(ArticleVoter()).run { + fun `other user can be view the article`(): Unit = listOf(ArticleVoter(mockk())).run { val article = getArticle(tesla) mockk { @@ -64,19 +74,19 @@ internal class ArticleVoterTest { } @Test - fun `other user can be view the article list`() = listOf(ArticleVoter()).run { + fun `other user can be view the article list`(): Unit = listOf(ArticleVoter(mockk())).run { val article = getArticle(tesla) val article2 = getArticle(tesla) mockk { every { user } returns einstein.user }.let { - can(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` true + canAll(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` true } } @Test - fun `the no creator can not be view the article on draft`() = listOf(ArticleVoter()).run { + fun `the no creator can not be view the article on draft`(): Unit = listOf(ArticleVoter(mockk())).run { val article = getArticle(tesla).apply { draft = true } mockk { @@ -87,19 +97,19 @@ internal class ArticleVoterTest { } @Test - fun `the no creator can not be view list of articles if one is on draft`() = listOf(ArticleVoter()).run { + fun `the no creator can not be view list of articles if one is on draft`(): Unit = listOf(ArticleVoter(mockk())).run { val article = getArticle(tesla) val article2 = getArticle(tesla).apply { draft = true } mockk { every { user } returns einstein.user }.let { - can(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` false + canAll(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` false } } @Test - fun `can not view deleted article`() = listOf(ArticleVoter()).run { + fun `can not view deleted article`(): Unit = listOf(ArticleVoter(mockk())).run { val article = getArticle(tesla).apply { deletedAt = DateTime.now() } mockk { @@ -110,7 +120,7 @@ internal class ArticleVoterTest { } @Test - fun `can delete article if owner`() = listOf(ArticleVoter()).run { + fun `can delete article if owner`(): Unit = listOf(ArticleVoter(mockk())).run { val article = getArticle(tesla) mockk { @@ -121,7 +131,7 @@ internal class ArticleVoterTest { } @Test - fun `can not delete article if not owner`() = listOf(ArticleVoter()).run { + fun `can not delete article if not owner`(): Unit = listOf(ArticleVoter(mockk())).run { val article = getArticle(tesla).apply { deletedAt = DateTime.now() } mockk { @@ -132,7 +142,7 @@ internal class ArticleVoterTest { } @Test - fun `can create article if logged`() = listOf(ArticleVoter()).run { + fun `can create article if logged`(): Unit = listOf(ArticleVoter(mockk())).run { val article = getArticle(tesla) mockk { @@ -143,7 +153,7 @@ internal class ArticleVoterTest { } @Test - fun `can not create article if not logged`() = listOf(ArticleVoter()).run { + fun `can not create article if not logged`(): Unit = listOf(ArticleVoter(mockk())).run { val article = getArticle(tesla) mockk { @@ -154,24 +164,28 @@ internal class ArticleVoterTest { } @Test - fun `can update article if yours`() = listOf(ArticleVoter()).run { + fun `can update article if yours`(): Unit { val article = getArticle(tesla) - - mockk { - every { user } returns tesla.user - }.let { - can(ArticleVoter.Action.UPDATE, it, article) `should be` true + listOf(ArticleVoter(getRepo(article))).run { + mockk { + every { user } returns tesla.user + every { citizenOrNull } returns tesla + }.let { + can(ArticleVoter.Action.UPDATE, it, article) `should be` true + } } } @Test - fun `can not update article if not yours`() = listOf(ArticleVoter()).run { + fun `can not update article if not yours`(): Unit { val article = getArticle(tesla) - - mockk { - every { user } returns einstein.user - }.let { - can(ArticleVoter.Action.UPDATE, it, article) `should be` false + listOf(ArticleVoter(getRepo(article))).run { + mockk { + every { user } returns einstein.user + every { citizenOrNull } returns einstein + }.let { + can(ArticleVoter.Action.UPDATE, it, article) `should be` false + } } } diff --git a/src/test/kotlin/security/voter/CitizenVoterTest.kt b/src/test/kotlin/security/voter/CitizenVoterTest.kt index 428b7af..2c71428 100644 --- a/src/test/kotlin/security/voter/CitizenVoterTest.kt +++ b/src/test/kotlin/security/voter/CitizenVoterTest.kt @@ -6,7 +6,9 @@ import fr.dcproject.entity.User import fr.dcproject.entity.UserI import fr.dcproject.user import fr.ktorVoter.ActionI +import fr.ktorVoter.Vote import fr.ktorVoter.can +import fr.ktorVoter.canAll import io.ktor.application.ApplicationCall import io.ktor.locations.KtorExperimentalLocationsAPI import io.mockk.every @@ -21,7 +23,7 @@ import org.junit.jupiter.api.TestInstance @KtorExperimentalLocationsAPI @TestInstance(TestInstance.Lifecycle.PER_CLASS) @Tag("voter") -internal class CitizenVoterTest { +class CitizenVoterTest { private val tesla = CitizenBasic( user = User( username = "nicolas-tesla", @@ -56,18 +58,18 @@ internal class CitizenVoterTest { } @Test - fun `support citizen`() = CitizenVoter().run { + fun `support citizen`(): Unit = CitizenVoter().run { val p = object : ActionI {} mockk { every { user } returns tesla.user }.let { - supports(CitizenVoter.Action.VIEW, it, einstein) `should be` true - supports(p, it, einstein) `should be` false + this(CitizenVoter.Action.VIEW, it, einstein) `should be` Vote.GRANTED + this(p, it, einstein) `should be` Vote.ABSTAIN } } @Test - fun `can be view the citizen`() = listOf(CitizenVoter()).run { + fun `can be view the citizen`(): Unit = listOf(CitizenVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -76,16 +78,16 @@ internal class CitizenVoterTest { } @Test - fun `can be view the citizen list`() = listOf(CitizenVoter()).run { + fun `can be view the citizen list`(): Unit = listOf(CitizenVoter()).run { mockk { every { user } returns einstein.user }.let { - can(CitizenVoter.Action.VIEW, it, listOf(einstein, tesla)) `should be` true + canAll(CitizenVoter.Action.VIEW, it, listOf(einstein, tesla)) `should be` true } } @Test - fun `can not view deleted citizen`() = listOf(CitizenVoter()).run { + fun `can not view deleted citizen`(): Unit = listOf(CitizenVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -94,7 +96,7 @@ internal class CitizenVoterTest { } @Test - fun `can be update itself`() = listOf(CitizenVoter()).run { + fun `can be update itself`(): Unit = listOf(CitizenVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -103,7 +105,7 @@ internal class CitizenVoterTest { } @Test - fun `can not be update other citizen`() = listOf(CitizenVoter()).run { + fun `can not be update other citizen`(): Unit = listOf(CitizenVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -112,7 +114,7 @@ internal class CitizenVoterTest { } @Test - fun `can be change password of itself`() = listOf(CitizenVoter()).run { + fun `can be change password of itself`(): Unit = listOf(CitizenVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -121,7 +123,7 @@ internal class CitizenVoterTest { } @Test - fun `can not be change password of other citizen`() = listOf(CitizenVoter()).run { + fun `can not be change password of other citizen`(): Unit = listOf(CitizenVoter()).run { mockk { every { user } returns einstein.user }.let { diff --git a/src/test/kotlin/security/voter/CommentVoterTest.kt b/src/test/kotlin/security/voter/CommentVoterTest.kt index 43fb89e..c94e9ca 100644 --- a/src/test/kotlin/security/voter/CommentVoterTest.kt +++ b/src/test/kotlin/security/voter/CommentVoterTest.kt @@ -3,7 +3,10 @@ package fr.dcproject.security.voter import fr.dcproject.entity.* import fr.dcproject.user import fr.ktorVoter.ActionI +import fr.ktorVoter.Vote import fr.ktorVoter.can +import fr.ktorVoter.canAll +import fr.postgresjson.connexion.Paginated import io.ktor.application.ApplicationCall import io.ktor.locations.KtorExperimentalLocationsAPI import io.mockk.every @@ -14,6 +17,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.repository.Article as ArticleRepo @KtorExperimentalLocationsAPI @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -51,6 +55,12 @@ internal class CommentVoterTest { target = article1 ) + private val comment2 = Comment( + content = "Hello2", + createdBy = einstein, + target = article1 + ) + private val commentTargetDeleted = Comment( content = "Hello", createdBy = tesla, @@ -69,42 +79,48 @@ internal class CommentVoterTest { target = ArticleRef() ) + private val repoArticle1 = mockk { + every { findVerionsByVersionsId(1, 1, any()) } returns Paginated(listOf(article1), 0, 1, 1) + } + init { mockkStatic("fr.dcproject.ApplicationContextKt") } @Test - fun `support comment`() = CommentVoter().run { + fun `support comment`(): Unit = CommentVoter().run { val p = object : ActionI {} mockk { every { user } returns tesla.user }.let { - supports(CommentVoter.Action.VIEW, it, comment1) `should be` true - supports(CommentVoter.Action.VIEW, it, article1) `should be` false - supports(p, it, comment1) `should be` false + this(CommentVoter.Action.VIEW, it, comment1) `should be` Vote.GRANTED + this(CommentVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN + this(p, it, comment1) `should be` Vote.ABSTAIN } } @Test - fun `can be view the comment`() = listOf(CommentVoter(), ArticleVoter()).run { - mockk { - every { user } returns tesla.user - }.let { - can(CommentVoter.Action.VIEW, it, comment1) `should be` true + fun `can be view the comment`(): Unit { + listOf(CommentVoter(), ArticleVoter(repoArticle1)).run { + mockk { + every { user } returns tesla.user + }.let { + can(CommentVoter.Action.VIEW, it, comment1) `should be` true + } } } @Test - fun `can be view the comment list`() = listOf(CommentVoter()).run { + fun `can be view the comment list`(): Unit = listOf(CommentVoter()).run { mockk { every { user } returns einstein.user }.let { - can(CommentVoter.Action.VIEW, it, listOf(comment1)) `should be` true + canAll(CommentVoter.Action.VIEW, it, listOf(comment1)) `should be` true } } @Test - fun `can be update your comment`() = listOf(CommentVoter()).run { + fun `can be update your comment`(): Unit = listOf(CommentVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -113,7 +129,7 @@ internal class CommentVoterTest { } @Test - fun `can not be update other comment`() = listOf(CommentVoter()).run { + fun `can not be update other comment`(): Unit = listOf(CommentVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -122,7 +138,7 @@ internal class CommentVoterTest { } @Test - fun `can not be delete your comment`() = listOf(CommentVoter()).run { + fun `can not be delete your comment`(): Unit = listOf(CommentVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -131,7 +147,7 @@ internal class CommentVoterTest { } @Test - fun `can be create a comment`() = listOf(CommentVoter(), ArticleVoter()).run { + fun `can be create a comment`(): Unit = listOf(CommentVoter(), ArticleVoter(repoArticle1)).run { mockk { every { user } returns tesla.user }.let { @@ -140,7 +156,7 @@ internal class CommentVoterTest { } @Test - fun `can not be create a comment if target is deleted`() = listOf(CommentVoter(), ArticleVoter()).run { + fun `can not be create a comment if target is deleted`(): Unit = listOf(CommentVoter(), ArticleVoter(repoArticle1)).run { mockk { every { user } returns tesla.user }.let { @@ -149,7 +165,7 @@ internal class CommentVoterTest { } @Test - fun `can not be create a comment if target has no user`() = listOf(CommentVoter(), ArticleVoter()).run { + fun `can not be create a comment if target has no user`(): Unit = listOf(CommentVoter(), ArticleVoter(repoArticle1)).run { mockk { every { user } returns tesla.user }.let { @@ -158,7 +174,7 @@ internal class CommentVoterTest { } @Test - fun `can not be create a comment with other creator`() = listOf(CommentVoter()).run { + fun `can not be create a comment with other creator`(): Unit = listOf(CommentVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -167,7 +183,7 @@ internal class CommentVoterTest { } @Test - fun `can not be create a comment if is null`() = listOf(CommentVoter()).run { + fun `can not be create a comment if is null`(): Unit = listOf(CommentVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -176,7 +192,7 @@ internal class CommentVoterTest { } @Test - fun `can not be create a comment if not connected`() = listOf(CommentVoter()).run { + fun `can not be create a comment if not connected`(): Unit = listOf(CommentVoter()).run { mockk { every { user } returns null }.let { diff --git a/src/test/kotlin/security/voter/FollowVoterTest.kt b/src/test/kotlin/security/voter/FollowVoterTest.kt index 1042144..0226b0a 100644 --- a/src/test/kotlin/security/voter/FollowVoterTest.kt +++ b/src/test/kotlin/security/voter/FollowVoterTest.kt @@ -3,7 +3,9 @@ package fr.dcproject.security.voter import fr.dcproject.entity.* import fr.dcproject.user import fr.ktorVoter.ActionI +import fr.ktorVoter.Vote import fr.ktorVoter.can +import fr.ktorVoter.canAll import io.ktor.application.ApplicationCall import io.ktor.locations.KtorExperimentalLocationsAPI import io.mockk.every @@ -63,19 +65,19 @@ internal class FollowVoterTest { } @Test - fun `support follow`() = FollowVoter().run { + fun `support follow`(): Unit = FollowVoter().run { val p = object : ActionI {} mockk { every { user } returns tesla.user }.let { - supports(FollowVoter.Action.VIEW, it, follow1) `should be` true - supports(FollowVoter.Action.VIEW, it, article1) `should be` false - supports(p, it, follow1) `should be` false + this(FollowVoter.Action.VIEW, it, follow1) `should be` Vote.GRANTED + this(FollowVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN + this(p, it, follow1) `should be` Vote.ABSTAIN } } @Test - fun `can be view the follow`() = listOf(FollowVoter()).run { + fun `can be view the follow`(): Unit = listOf(FollowVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -84,16 +86,16 @@ internal class FollowVoterTest { } @Test - fun `can be view the follow list`() = listOf(FollowVoter()).run { + fun `can be view the follow list`(): Unit = listOf(FollowVoter()).run { mockk { every { user } returns tesla.user }.let { - can(FollowVoter.Action.VIEW, it, listOf(follow1)) `should be` true + canAll(FollowVoter.Action.VIEW, it, listOf(follow1)) `should be` true } } @Test - fun `can be view your anonymous follow`() = listOf(FollowVoter()).run { + fun `can be view your anonymous follow`(): Unit = listOf(FollowVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -102,7 +104,7 @@ internal class FollowVoterTest { } @Test - fun `can not be view the anonymous follow of other`() = listOf(FollowVoter()).run { + fun `can not be view the anonymous follow of other`(): Unit = listOf(FollowVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -111,7 +113,7 @@ internal class FollowVoterTest { } @Test - fun `can be follow article`() = listOf(FollowVoter()).run { + fun `can be follow article`(): Unit = listOf(FollowVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -120,7 +122,7 @@ internal class FollowVoterTest { } @Test - fun `can not be follow article if not connected`() = listOf(FollowVoter()).run { + fun `can not be follow article if not connected`(): Unit = listOf(FollowVoter()).run { mockk { every { user } returns null }.let { @@ -129,7 +131,7 @@ internal class FollowVoterTest { } @Test - fun `can be unfollow article`() = listOf(FollowVoter()).run { + fun `can be unfollow article`(): Unit = listOf(FollowVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -138,7 +140,7 @@ internal class FollowVoterTest { } @Test - fun `can not be unfollow article if not connected`() = listOf(FollowVoter()).run { + fun `can not be unfollow article if not connected`(): Unit = listOf(FollowVoter()).run { mockk { every { user } returns null }.let { diff --git a/src/test/kotlin/security/voter/OpinionChoiceVoterTest.kt b/src/test/kotlin/security/voter/OpinionChoiceVoterTest.kt index a355eb0..9867fea 100644 --- a/src/test/kotlin/security/voter/OpinionChoiceVoterTest.kt +++ b/src/test/kotlin/security/voter/OpinionChoiceVoterTest.kt @@ -3,7 +3,9 @@ package fr.dcproject.security.voter import fr.dcproject.entity.* import fr.dcproject.user import fr.ktorVoter.ActionI +import fr.ktorVoter.Vote import fr.ktorVoter.can +import fr.ktorVoter.canAll import io.ktor.application.ApplicationCall import io.ktor.locations.KtorExperimentalLocationsAPI import io.mockk.every @@ -47,19 +49,19 @@ internal class OpinionChoiceVoterTest { } @Test - fun `support opinion choice`() = OpinionChoiceVoter().run { + fun `support opinion choice`(): Unit = OpinionChoiceVoter().run { val p = object : ActionI {} mockk { every { user } returns tesla.user }.let { - supports(OpinionChoiceVoter.Action.VIEW, it, choice1) `should be` true - supports(OpinionChoiceVoter.Action.VIEW, it, article1) `should be` false - supports(p, it, choice1) `should be` false + this(OpinionChoiceVoter.Action.VIEW, it, choice1) `should be` Vote.GRANTED + this(OpinionChoiceVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN + this(p, it, choice1) `should be` Vote.ABSTAIN } } @Test - fun `can be view the opinion choice`() = listOf(OpinionChoiceVoter()).run { + fun `can be view the opinion choice`(): Unit = listOf(OpinionChoiceVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -68,11 +70,11 @@ internal class OpinionChoiceVoterTest { } @Test - fun `can be view the opinion choice list`() = listOf(OpinionChoiceVoter()).run { + fun `can be view the opinion choice list`(): Unit = listOf(OpinionChoiceVoter()).run { mockk { every { user } returns tesla.user }.let { - can(OpinionChoiceVoter.Action.VIEW, it, listOf(choice1)) `should be` true + canAll(OpinionChoiceVoter.Action.VIEW, it, listOf(choice1)) `should be` true } } } \ No newline at end of file diff --git a/src/test/kotlin/security/voter/OpinionVoterTest.kt b/src/test/kotlin/security/voter/OpinionVoterTest.kt index f8e450d..885eb17 100644 --- a/src/test/kotlin/security/voter/OpinionVoterTest.kt +++ b/src/test/kotlin/security/voter/OpinionVoterTest.kt @@ -3,7 +3,9 @@ package fr.dcproject.security.voter import fr.dcproject.entity.* import fr.dcproject.user import fr.ktorVoter.ActionI +import fr.ktorVoter.Vote import fr.ktorVoter.can +import fr.ktorVoter.canAll import io.ktor.application.ApplicationCall import io.ktor.locations.KtorExperimentalLocationsAPI import io.mockk.every @@ -62,20 +64,20 @@ internal class OpinionVoterTest { } @Test - fun `support opinion`() = OpinionVoter().run { + fun `support opinion`(): Unit = OpinionVoter().run { val p = object : ActionI {} mockk { every { user } returns tesla.user }.let { - supports(OpinionVoter.Action.VIEW, it, opinion1) `should be` true - supports(OpinionVoter.Action.VIEW, it, article1) `should be` true - supports(OpinionVoter.Action.VIEW, it, einstein) `should be` false - supports(p, it, opinion1) `should be` false + this(OpinionVoter.Action.VIEW, it, opinion1) `should be` Vote.GRANTED + this(OpinionVoter.Action.VIEW, it, article1) `should be` Vote.GRANTED + this(OpinionVoter.Action.VIEW, it, einstein) `should be` Vote.ABSTAIN + this(p, it, opinion1) `should be` Vote.ABSTAIN } } @Test - fun `can be view the opinion`() = listOf(OpinionVoter()).run { + fun `can be view the opinion`(): Unit = listOf(OpinionVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -84,7 +86,7 @@ internal class OpinionVoterTest { } @Test - fun `can be not view the opinion if is null`() = listOf(OpinionVoter()).run { + fun `can be not view the opinion if is null`(): Unit = listOf(OpinionVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -93,16 +95,16 @@ internal class OpinionVoterTest { } @Test - fun `can be view the opinion list`() = listOf(OpinionVoter()).run { + fun `can be view the opinion list`(): Unit = listOf(OpinionVoter()).run { mockk { every { user } returns tesla.user }.let { - can(OpinionVoter.Action.VIEW, it, listOf(opinion1)) `should be` true + canAll(OpinionVoter.Action.VIEW, it, listOf(opinion1)) `should be` true } } @Test - fun `can be opinion an article`() = listOf(OpinionVoter()).run { + fun `can be opinion an article`(): Unit = listOf(OpinionVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -120,7 +122,7 @@ internal class OpinionVoterTest { } @Test - fun `can be remove opinion`() = listOf(OpinionVoter()).run { + fun `can be remove opinion`(): Unit = listOf(OpinionVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -129,7 +131,7 @@ internal class OpinionVoterTest { } @Test - fun `can not be remove opinion if not connected`() = listOf(OpinionVoter()).run { + fun `can not be remove opinion if not connected`(): Unit = listOf(OpinionVoter()).run { mockk { every { user } returns null }.let { @@ -138,7 +140,7 @@ internal class OpinionVoterTest { } @Test - fun `can not be remove opinion of other user`() = listOf(OpinionVoter()).run { + fun `can not be remove opinion of other user`(): Unit = listOf(OpinionVoter()).run { mockk { every { user } returns einstein.user }.let { diff --git a/src/test/kotlin/security/voter/VoteVoterTest.kt b/src/test/kotlin/security/voter/VoteVoterTest.kt index 383617b..f39e013 100644 --- a/src/test/kotlin/security/voter/VoteVoterTest.kt +++ b/src/test/kotlin/security/voter/VoteVoterTest.kt @@ -3,7 +3,10 @@ package fr.dcproject.security.voter import fr.dcproject.entity.* import fr.dcproject.user import fr.ktorVoter.ActionI +import fr.ktorVoter.Vote import fr.ktorVoter.can +import fr.ktorVoter.canAll +import fr.postgresjson.connexion.Paginated import io.ktor.application.ApplicationCall import io.ktor.locations.KtorExperimentalLocationsAPI import io.mockk.every @@ -77,19 +80,19 @@ internal class VoteVoterTest { } @Test - fun `support vote`() = VoteVoter().run { + fun `support vote`(): Unit = VoteVoter().run { val p = object : ActionI {} mockk { every { user } returns tesla.user }.let { - supports(VoteVoter.Action.VIEW, it, vote1) `should be` true - supports(VoteVoter.Action.VIEW, it, article1) `should be` false - supports(p, it, vote1) `should be` false + this(VoteVoter.Action.VIEW, it, vote1) `should be` Vote.GRANTED + this(VoteVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN + this(p, it, vote1) `should be` Vote.ABSTAIN } } @Test - fun `can be view your the vote`() = listOf(VoteVoter()).run { + fun `can be view your the vote`(): Unit = listOf(VoteVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -98,7 +101,7 @@ internal class VoteVoterTest { } @Test - fun `can not be view vote of other`() = listOf(VoteVoter()).run { + fun `can not be view vote of other`(): Unit = listOf(VoteVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -107,7 +110,7 @@ internal class VoteVoterTest { } @Test - fun `can be not view the vote if is null`() = listOf(VoteVoter()).run { + fun `can be not view the vote if is null`(): Unit = listOf(VoteVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -116,25 +119,27 @@ internal class VoteVoterTest { } @Test - fun `can be view your votes list`() = listOf(VoteVoter()).run { + fun `can be view your votes list`(): Unit = listOf(VoteVoter()).run { mockk { every { user } returns tesla.user }.let { - can(VoteVoter.Action.VIEW, it, listOf(vote1)) `should be` true + canAll(VoteVoter.Action.VIEW, it, listOf(vote1)) `should be` true } } @Test - fun `can be vote an article`() = listOf(VoteVoter(), ArticleVoter()).run { - mockk { - every { user } returns tesla.user - }.let { - can(VoteVoter.Action.CREATE, it, vote1) `should be` true + fun `can be vote an article`(): Unit { + listOf(VoteVoter(), ArticleVoter(mockk())).run { + mockk { + every { user } returns tesla.user + }.let { + can(VoteVoter.Action.CREATE, it, vote1) `should be` true + } } } @Test - fun `can not be vote if not connected`() = listOf(VoteVoter()).run { + fun `can not be vote if not connected`(): Unit = listOf(VoteVoter()).run { mockk { every { user } returns null }.let { @@ -143,7 +148,7 @@ internal class VoteVoterTest { } @Test - fun `can not be vote an article if article is deleted`() = listOf(VoteVoter(), ArticleVoter()).run { + fun `can not be vote an article if article is deleted`(): Unit = listOf(VoteVoter(), ArticleVoter(mockk())).run { mockk { every { user } returns tesla.user }.let { @@ -152,7 +157,7 @@ internal class VoteVoterTest { } @Test - fun `can not be vote an article if article have no user`() = listOf(VoteVoter(), ArticleVoter()).run { + fun `can not be vote an article if article have no user`(): Unit = listOf(VoteVoter(), ArticleVoter(mockk())).run { mockk { every { user } returns tesla.user }.let { @@ -161,7 +166,7 @@ internal class VoteVoterTest { } @Test - fun `can not be comment an article if article is deleted`() = listOf(VoteVoter(), ArticleVoter()).run { + fun `can not be comment an article if article is deleted`(): Unit = listOf(VoteVoter(), ArticleVoter(mockk())).run { mockk { every { user } returns tesla.user }.let { diff --git a/src/test/kotlin/security/voter/WorkgroupVoterTest.kt b/src/test/kotlin/security/voter/WorkgroupVoterTest.kt index 7ea3edf..2adbffc 100644 --- a/src/test/kotlin/security/voter/WorkgroupVoterTest.kt +++ b/src/test/kotlin/security/voter/WorkgroupVoterTest.kt @@ -3,6 +3,7 @@ package fr.dcproject.security.voter import fr.dcproject.entity.* import fr.dcproject.user import fr.ktorVoter.ActionI +import fr.ktorVoter.Vote import fr.ktorVoter.VoterException import fr.ktorVoter.can import io.ktor.application.ApplicationCall @@ -74,19 +75,19 @@ internal class WorkgroupVoterTest { } @Test - fun `support workgroup`() = WorkgroupVoter().run { + fun `support workgroup`(): Unit = WorkgroupVoter().run { val p = object : ActionI {} mockk { every { user } returns tesla.user }.let { - supports(WorkgroupVoter.Action.VIEW, it, workgroupPublic) `should be` true - supports(WorkgroupVoter.Action.VIEW, it, article1) `should be` false - supports(p, it, workgroupPublic) `should be` false + this(WorkgroupVoter.Action.VIEW, it, workgroupPublic) `should be` Vote.GRANTED + this(WorkgroupVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN + this(p, it, workgroupPublic) `should be` Vote.ABSTAIN } } @Test - fun `can be view your workgroup`() = listOf(WorkgroupVoter()).run { + fun `can be view your workgroup`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -95,7 +96,7 @@ internal class WorkgroupVoterTest { } @Test - fun `can be view your workgroup if is not public`() = listOf(WorkgroupVoter()).run { + fun `can be view your workgroup if is not public`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -104,7 +105,7 @@ internal class WorkgroupVoterTest { } @Test - fun `can be view workgroup of other if is public`() = listOf(WorkgroupVoter()).run { + fun `can be view workgroup of other if is public`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -113,7 +114,7 @@ internal class WorkgroupVoterTest { } @Test - fun `can not be view workgroup of other if is not public`() = listOf(WorkgroupVoter()).run { + fun `can not be view workgroup of other if is not public`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -122,7 +123,7 @@ internal class WorkgroupVoterTest { } @Test - fun `can be not view the workgroup if is null`() = listOf(WorkgroupVoter()).run { + fun `can be not view the workgroup if is null`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -131,16 +132,18 @@ internal class WorkgroupVoterTest { } @Test - fun `can be view your workgroup list`() = listOf(WorkgroupVoter()).run { + fun `can be view your workgroup list`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns tesla.user }.let { - can(WorkgroupVoter.Action.VIEW, it, listOf(workgroupPublic)) `should be` true + listOf(workgroupPublic).map { workgroup -> + can(WorkgroupVoter.Action.VIEW, it, workgroup) + }.all { it } `should be` true } } @Test - fun `can be create workgroup`() = listOf(WorkgroupVoter()).run { + fun `can be create workgroup`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -149,7 +152,7 @@ internal class WorkgroupVoterTest { } @Test - fun `can not be create workgroup if not connected`() = listOf(WorkgroupVoter()).run { + fun `can not be create workgroup if not connected`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns null }.let { @@ -158,7 +161,7 @@ internal class WorkgroupVoterTest { } @Test - fun `can be delete workgroup if owner`() = listOf(WorkgroupVoter()).run { + fun `can be delete workgroup if owner`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -167,7 +170,7 @@ internal class WorkgroupVoterTest { } @Test - fun `can not be delete workgroup if not owner`() = listOf(WorkgroupVoter()).run { + fun `can not be delete workgroup if not owner`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns einstein.user }.let { @@ -176,7 +179,7 @@ internal class WorkgroupVoterTest { } @Test - fun `can be update workgroup if owner`() = listOf(WorkgroupVoter()).run { + fun `can be update workgroup if owner`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns tesla.user }.let { @@ -185,7 +188,7 @@ internal class WorkgroupVoterTest { } @Test - fun `can not be update workgroup if not owner`() = listOf(WorkgroupVoter()).run { + fun `can not be update workgroup if not owner`(): Unit = listOf(WorkgroupVoter()).run { mockk { every { user } returns einstein.user }.let {