Update ktor-voter to version 2.2.0

This commit is contained in:
2020-10-05 15:00:34 +02:00
parent 74923891d0
commit 03401f711e
38 changed files with 403 additions and 384 deletions

View File

@@ -1,6 +1,6 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.owasp.dependencycheck.reporting.ReportGenerator import org.owasp.dependencycheck.reporting.ReportGenerator
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
val ktor_version: String by project val ktor_version: String by project
@@ -139,7 +139,7 @@ dependencies {
implementation("com.auth0:java-jwt:3.8.2") implementation("com.auth0:java-jwt:3.8.2")
implementation("com.github.jasync-sql:jasync-postgresql:1.0.7") implementation("com.github.jasync-sql:jasync-postgresql:1.0.7")
implementation("com.github.flecomte:postgres-json:1.2.1") 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("com.sendgrid:sendgrid-java:4.4.1")
implementation("io.lettuce:lettuce-core:5.2.2.RELEASE") implementation("io.lettuce:lettuce-core:5.2.2.RELEASE")
implementation("com.rabbitmq:amqp-client:5.8.0") implementation("com.rabbitmq:amqp-client:5.8.0")
@@ -152,7 +152,7 @@ dependencies {
testImplementation("org.koin:koin-test:$koinVersion") testImplementation("org.koin:koin-test:$koinVersion")
testImplementation("io.mockk:mockk:1.9.3") testImplementation("io.mockk:mockk:1.9.3")
testImplementation("org.junit.jupiter:junit-jupiter:5.5.0") 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-java8:$cucumber_version")
testImplementation("io.cucumber:cucumber-junit:$cucumber_version") testImplementation("io.cucumber:cucumber-junit:$cucumber_version")
} }

View File

@@ -38,6 +38,7 @@ import io.ktor.response.respond
import io.ktor.routing.Routing import io.ktor.routing.Routing
import io.ktor.util.KtorExperimentalAPI import io.ktor.util.KtorExperimentalAPI
import io.ktor.websocket.WebSockets import io.ktor.websocket.WebSockets
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.eclipse.jetty.util.log.Slf4jLog import org.eclipse.jetty.util.log.Slf4jLog
import org.koin.core.qualifier.named import org.koin.core.qualifier.named
import org.koin.ktor.ext.Koin import org.koin.ktor.ext.Koin
@@ -58,6 +59,7 @@ fun main(args: Array<String>): Unit = io.ktor.server.jetty.EngineMain.main(args)
enum class Env { PROD, TEST, CUCUMBER } enum class Env { PROD, TEST, CUCUMBER }
@ExperimentalCoroutinesApi
@KtorExperimentalAPI @KtorExperimentalAPI
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@Suppress("unused") // Referenced in application.conf @Suppress("unused") // Referenced in application.conf
@@ -173,8 +175,8 @@ fun Application.module(env: Env = PROD) {
} }
install(AuthorizationVoter) { install(AuthorizationVoter) {
voters = mutableListOf( voters = listOf(
ArticleVoter(), ArticleVoter(get()),
ConstitutionVoter(), ConstitutionVoter(),
CitizenVoter(), CitizenVoter(),
CommentVoter(), CommentVoter(),

View File

@@ -16,9 +16,9 @@ import fr.dcproject.views.ArticleViewManager
import fr.postgresjson.connexion.Connection import fr.postgresjson.connexion.Connection
import fr.postgresjson.connexion.Requester import fr.postgresjson.connexion.Requester
import fr.postgresjson.migration.Migrations import fr.postgresjson.migration.Migrations
import io.ktor.client.HttpClient import io.ktor.client.*
import io.ktor.client.features.websocket.WebSockets import io.ktor.client.features.websocket.*
import io.ktor.util.KtorExperimentalAPI import io.ktor.util.*
import io.lettuce.core.RedisClient import io.lettuce.core.RedisClient
import io.lettuce.core.api.async.RedisAsyncCommands import io.lettuce.core.api.async.RedisAsyncCommands
import org.apache.http.HttpHost import org.apache.http.HttpHost
@@ -123,7 +123,7 @@ val Module = module {
single { ArticleViewManager(get()) } single { ArticleViewManager(get()) }
// Mailler // Mailer
single { Mailer(Config.sendGridKey) } single { Mailer(Config.sendGridKey) }
// SSO Manager for connection // SSO Manager for connection

View File

@@ -19,6 +19,7 @@ class Article(
override val createdBy: CitizenBasic, override val createdBy: CitizenBasic,
workgroup: WorkgroupSimple<CitizenRef>? = null workgroup: WorkgroupSimple<CitizenRef>? = null
) : ArticleFull, ) : ArticleFull,
ArticleForUpdateI,
ArticleAuthI<CitizenBasicI>, ArticleAuthI<CitizenBasicI>,
ArticleSimple(id, title, createdBy, draft, workgroup), ArticleSimple(id, title, createdBy, draft, workgroup),
Viewable by ViewableImp() { Viewable by ViewableImp() {
@@ -26,19 +27,28 @@ class Article(
tags = tags.distinct() tags = tags.distinct()
} }
} }
interface ArticleForUpdateI: ArticleI, EntityVersioning<UUID, Int>, TargetI {
val title: String
val anonymous: Boolean
val content: String
val description: String
val draft: Boolean
val createdBy: CitizenRef
val workgroup: WorkgroupRef?
}
class ArticleForUpdate( class ArticleForUpdate(
id: UUID?, id: UUID?,
val title: String, override val title: String,
val anonymous: Boolean = true, override val anonymous: Boolean = true,
val content: String, override val content: String,
val description: String, override val description: String,
tags: List<String> = emptyList(), tags: List<String> = emptyList(),
val draft: Boolean = false, override val draft: Boolean = false,
val createdBy: CitizenRef, override val createdBy: CitizenRef,
val workgroup: WorkgroupRef? = null, override val workgroup: WorkgroupRef? = null,
versionId: UUID? versionId: UUID?
) : ArticleRefVersioning(id, versionId = versionId ?: UUID.randomUUID()) { ) : ArticleForUpdateI,
ArticleRefVersioning(id, versionId = versionId ?: UUID.randomUUID()) {
val tags: List<String> = tags.distinct() val tags: List<String> = tags.distinct()
val isNew = versionId == null val isNew = versionId == null
} }

View File

@@ -3,34 +3,29 @@ package fr.dcproject.routes
import fr.dcproject.citizen import fr.dcproject.citizen
import fr.dcproject.citizenOrNull import fr.dcproject.citizenOrNull
import fr.dcproject.entity.ArticleForUpdate import fr.dcproject.entity.ArticleForUpdate
import fr.dcproject.entity.CitizenRef
import fr.dcproject.entity.WorkgroupRef import fr.dcproject.entity.WorkgroupRef
import fr.dcproject.entity.WorkgroupSimple
import fr.dcproject.event.ArticleUpdate import fr.dcproject.event.ArticleUpdate
import fr.dcproject.event.raiseEvent import fr.dcproject.event.raiseEvent
import fr.dcproject.repository.Article.Filter 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.CREATE
import fr.dcproject.security.voter.ArticleVoter.Action.UPDATE import fr.dcproject.security.voter.ArticleVoter.Action.UPDATE
import fr.dcproject.security.voter.ArticleVoter.Action.VIEW import fr.dcproject.security.voter.ArticleVoter.Action.VIEW
import fr.dcproject.views.ArticleViewManager import fr.dcproject.views.ArticleViewManager
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import fr.ktorVoter.assertCanAll
import fr.postgresjson.repository.RepositoryI import fr.postgresjson.repository.RepositoryI
import io.ktor.application.ApplicationCall import io.ktor.application.*
import io.ktor.application.call import io.ktor.locations.*
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.request.*
import io.ktor.locations.Location import io.ktor.response.*
import io.ktor.locations.get import io.ktor.routing.*
import io.ktor.locations.post
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.routing.Route
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.inject import org.koin.core.inject
import java.util.* import java.util.*
import fr.dcproject.entity.Article as ArticleEntity import fr.dcproject.entity.Article as ArticleEntity
import fr.dcproject.repository.Article as ArticleRepository import fr.dcproject.repository.Article as ArticleRepository
import fr.dcproject.repository.Workgroup as WorkgroupRepository
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
object ArticlesPaths { object ArticlesPaths {
@@ -90,7 +85,7 @@ object ArticlesPaths {
tags = tags, tags = tags,
draft = draft, draft = draft,
createdBy = call.citizen, createdBy = call.citizen,
workgroup = if (workgroup != null) workgroupRepository.findById(workgroup.id) as WorkgroupSimple<CitizenRef> else null, workgroup = if (workgroup != null) workgroupRepository.findById(workgroup.id) else null,
versionId = versionId versionId = versionId
) )
} }
@@ -108,7 +103,7 @@ fun Route.article(repo: ArticleRepository, viewManager: ArticleViewManager) {
it.search, it.search,
Filter(createdById = it.createdBy, workgroupId = it.workgroup) Filter(createdById = it.createdBy, workgroupId = it.workgroup)
) )
assertCan(VIEW, articles.result) assertCanAll(VIEW, articles.result)
call.respond(articles) call.respond(articles)
} }

View File

@@ -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.CHANGE_PASSWORD
import fr.dcproject.security.voter.CitizenVoter.Action.VIEW import fr.dcproject.security.voter.CitizenVoter.Action.VIEW
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import fr.ktorVoter.assertCanAll
import fr.postgresjson.repository.RepositoryI.Direction import fr.postgresjson.repository.RepositoryI.Direction
import io.ktor.application.call import io.ktor.application.*
import io.ktor.auth.UserPasswordCredential import io.ktor.auth.*
import io.ktor.http.HttpStatusCode import io.ktor.http.*
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.*
import io.ktor.locations.Location import io.ktor.request.*
import io.ktor.locations.get import io.ktor.response.*
import io.ktor.locations.put import io.ktor.routing.*
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.routing.Route
import fr.dcproject.repository.Citizen as CitizenRepository import fr.dcproject.repository.Citizen as CitizenRepository
import fr.dcproject.repository.User as UserRepository import fr.dcproject.repository.User as UserRepository
@@ -58,7 +56,7 @@ fun Route.citizen(
) { ) {
get<CitizensRequest> { get<CitizensRequest> {
val citizens = repo.find(it.page, it.limit, it.sort, it.direction, it.search) 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) call.respond(citizens)
} }

View File

@@ -4,17 +4,19 @@ import fr.dcproject.citizen
import fr.dcproject.entity.Comment import fr.dcproject.entity.Comment
import fr.dcproject.entity.CommentRef import fr.dcproject.entity.CommentRef
import fr.dcproject.routes.CommentPaths.CreateCommentRequest.Content 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 fr.ktorVoter.assertCan
import io.ktor.application.call import fr.ktorVoter.assertCanAll
import io.ktor.features.NotFoundException import io.ktor.application.*
import io.ktor.http.HttpStatusCode import io.ktor.features.*
import io.ktor.http.*
import io.ktor.locations.* import io.ktor.locations.*
import io.ktor.request.receive import io.ktor.request.*
import io.ktor.request.receiveText import io.ktor.response.*
import io.ktor.response.respond import io.ktor.routing.*
import io.ktor.routing.Route import io.ktor.util.*
import io.ktor.util.KtorExperimentalAPI
import java.util.* import java.util.*
import fr.dcproject.repository.CommentGeneric as CommentRepository import fr.dcproject.repository.CommentGeneric as CommentRepository
@@ -58,7 +60,7 @@ fun Route.comment(repo: CommentRepository) {
it.limit it.limit
) )
assertCan(VIEW, comments.result) assertCanAll(VIEW, comments.result)
call.respond(HttpStatusCode.OK, comments) call.respond(HttpStatusCode.OK, comments)
} }

View File

@@ -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.CREATE
import fr.dcproject.security.voter.CommentVoter.Action.VIEW import fr.dcproject.security.voter.CommentVoter.Action.VIEW
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import io.ktor.application.ApplicationCall import fr.ktorVoter.assertCanAll
import io.ktor.application.call import io.ktor.application.*
import io.ktor.http.HttpStatusCode import io.ktor.http.*
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.*
import io.ktor.locations.Location import io.ktor.request.*
import io.ktor.locations.get import io.ktor.response.*
import io.ktor.locations.post import io.ktor.routing.*
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.routing.Route
import fr.dcproject.entity.Comment as CommentEntity import fr.dcproject.entity.Comment as CommentEntity
import fr.dcproject.repository.CommentArticle as CommentArticleRepository import fr.dcproject.repository.CommentArticle as CommentArticleRepository
@@ -61,7 +58,7 @@ fun Route.commentArticle(repo: CommentArticleRepository) {
get<CommentArticlePaths.ArticleCommentRequest> { get<CommentArticlePaths.ArticleCommentRequest> {
val comment = repo.findByTarget(it.article, it.page, it.limit, it.sort) val comment = repo.findByTarget(it.article, it.page, it.limit, it.sort)
if (comment.result.isNotEmpty()) { if (comment.result.isNotEmpty()) {
assertCan(VIEW, comment.result) assertCanAll(VIEW, comment.result)
} }
call.respond(HttpStatusCode.OK, comment) call.respond(HttpStatusCode.OK, comment)
} }
@@ -76,7 +73,7 @@ fun Route.commentArticle(repo: CommentArticleRepository) {
get<CommentArticlePaths.CitizenCommentArticleRequest> { get<CommentArticlePaths.CitizenCommentArticleRequest> {
repo.findByCitizen(it.citizen).let { comments -> repo.findByCitizen(it.citizen).let { comments ->
assertCan(VIEW, comments.result) assertCanAll(VIEW, comments.result)
call.respond(comments) call.respond(comments)
} }
} }

View File

@@ -6,15 +6,13 @@ import fr.dcproject.entity.ConstitutionRef
import fr.dcproject.security.voter.CommentVoter.Action.CREATE import fr.dcproject.security.voter.CommentVoter.Action.CREATE
import fr.dcproject.security.voter.CommentVoter.Action.VIEW import fr.dcproject.security.voter.CommentVoter.Action.VIEW
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import io.ktor.application.call import fr.ktorVoter.assertCanAll
import io.ktor.http.HttpStatusCode import io.ktor.application.*
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.http.*
import io.ktor.locations.Location import io.ktor.locations.*
import io.ktor.locations.get import io.ktor.request.*
import io.ktor.locations.post import io.ktor.response.*
import io.ktor.request.receiveText import io.ktor.routing.*
import io.ktor.response.respond
import io.ktor.routing.Route
import fr.dcproject.entity.Comment as CommentEntity import fr.dcproject.entity.Comment as CommentEntity
import fr.dcproject.repository.CommentConstitution as CommentConstitutionRepository import fr.dcproject.repository.CommentConstitution as CommentConstitutionRepository
@@ -31,7 +29,7 @@ object CommentConstitutionPaths {
fun Route.commentConstitution(repo: CommentConstitutionRepository) { fun Route.commentConstitution(repo: CommentConstitutionRepository) {
get<CommentConstitutionPaths.ConstitutionCommentRequest> { get<CommentConstitutionPaths.ConstitutionCommentRequest> {
val comments = repo.findByTarget(it.constitution) val comments = repo.findByTarget(it.constitution)
assertCan(VIEW, comments.result) assertCanAll(VIEW, comments.result)
call.respond(HttpStatusCode.OK, comments) call.respond(HttpStatusCode.OK, comments)
} }
@@ -50,7 +48,7 @@ fun Route.commentConstitution(repo: CommentConstitutionRepository) {
get<CommentConstitutionPaths.CitizenCommentConstitutionRequest> { get<CommentConstitutionPaths.CitizenCommentConstitutionRequest> {
val comments = repo.findByCitizen(it.citizen) val comments = repo.findByCitizen(it.citizen)
assertCan(VIEW, comments.result) assertCanAll(VIEW, comments.result)
call.respond(comments) call.respond(comments)
} }
} }

View File

@@ -7,17 +7,14 @@ import fr.dcproject.entity.ConstitutionSimple
import fr.dcproject.security.voter.ConstitutionVoter.Action.CREATE import fr.dcproject.security.voter.ConstitutionVoter.Action.CREATE
import fr.dcproject.security.voter.ConstitutionVoter.Action.VIEW import fr.dcproject.security.voter.ConstitutionVoter.Action.VIEW
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import fr.ktorVoter.assertCanAll
import fr.postgresjson.entity.immutable.UuidEntity import fr.postgresjson.entity.immutable.UuidEntity
import fr.postgresjson.repository.RepositoryI import fr.postgresjson.repository.RepositoryI
import io.ktor.application.ApplicationCall import io.ktor.application.*
import io.ktor.application.call import io.ktor.locations.*
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.request.*
import io.ktor.locations.Location import io.ktor.response.*
import io.ktor.locations.get import io.ktor.routing.*
import io.ktor.locations.post
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.routing.Route
import java.util.* import java.util.*
import fr.dcproject.entity.Constitution as ConstitutionEntity import fr.dcproject.entity.Constitution as ConstitutionEntity
import fr.dcproject.repository.Constitution as ConstitutionRepository import fr.dcproject.repository.Constitution as ConstitutionRepository
@@ -86,7 +83,7 @@ object ConstitutionPaths {
fun Route.constitution(repo: ConstitutionRepository) { fun Route.constitution(repo: ConstitutionRepository) {
get<ConstitutionPaths.ConstitutionsRequest> { get<ConstitutionPaths.ConstitutionsRequest> {
val constitutions = repo.find(it.page, it.limit, it.sort, it.direction, it.search) 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) call.respond(constitutions)
} }

View File

@@ -3,13 +3,16 @@ package fr.dcproject.routes
import fr.dcproject.citizen import fr.dcproject.citizen
import fr.dcproject.entity.ArticleRef import fr.dcproject.entity.ArticleRef
import fr.dcproject.entity.Citizen 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 fr.ktorVoter.assertCan
import io.ktor.application.call import fr.ktorVoter.assertCanAll
import io.ktor.http.HttpStatusCode import io.ktor.application.*
import io.ktor.http.*
import io.ktor.locations.* import io.ktor.locations.*
import io.ktor.response.respond import io.ktor.response.*
import io.ktor.routing.Route import io.ktor.routing.*
import fr.dcproject.entity.Follow as FollowEntity import fr.dcproject.entity.Follow as FollowEntity
import fr.dcproject.repository.FollowArticle as FollowArticleRepository import fr.dcproject.repository.FollowArticle as FollowArticleRepository
@@ -48,7 +51,7 @@ fun Route.followArticle(repo: FollowArticleRepository) {
get<FollowArticlePaths.CitizenFollowArticleRequest> { get<FollowArticlePaths.CitizenFollowArticleRequest> {
val follows = repo.findByCitizen(it.citizen) val follows = repo.findByCitizen(it.citizen)
if (follows.result.isNotEmpty()) { if (follows.result.isNotEmpty()) {
assertCan(VIEW, follows.result) assertCanAll(VIEW, follows.result)
} }
call.respond(follows) call.respond(follows)
} }

View File

@@ -3,13 +3,16 @@ package fr.dcproject.routes
import fr.dcproject.citizen import fr.dcproject.citizen
import fr.dcproject.entity.CitizenRef import fr.dcproject.entity.CitizenRef
import fr.dcproject.entity.ConstitutionRef 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 fr.ktorVoter.assertCan
import io.ktor.application.call import fr.ktorVoter.assertCanAll
import io.ktor.http.HttpStatusCode import io.ktor.application.*
import io.ktor.http.*
import io.ktor.locations.* import io.ktor.locations.*
import io.ktor.response.respond import io.ktor.response.*
import io.ktor.routing.Route import io.ktor.routing.*
import fr.dcproject.entity.Follow as FollowEntity import fr.dcproject.entity.Follow as FollowEntity
import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository
@@ -47,7 +50,7 @@ fun Route.followConstitution(repo: FollowConstitutionRepository) {
get<FollowConstitutionPaths.CitizenFollowConstitutionRequest> { get<FollowConstitutionPaths.CitizenFollowConstitutionRequest> {
val follows = repo.findByCitizen(it.citizen) val follows = repo.findByCitizen(it.citizen)
assertCan(VIEW, follows.result) assertCanAll(VIEW, follows.result)
call.respond(follows) call.respond(follows)
} }
} }

View File

@@ -5,18 +5,16 @@ import fr.dcproject.entity.CitizenRef
import fr.dcproject.entity.OpinionChoiceRef import fr.dcproject.entity.OpinionChoiceRef
import fr.dcproject.security.voter.OpinionVoter.Action.CREATE import fr.dcproject.security.voter.OpinionVoter.Action.CREATE
import fr.dcproject.security.voter.OpinionVoter.Action.VIEW import fr.dcproject.security.voter.OpinionVoter.Action.VIEW
import fr.ktorVoter.assertCan
import fr.dcproject.utils.toUUID import fr.dcproject.utils.toUUID
import io.ktor.application.call import fr.ktorVoter.assertCan
import io.ktor.http.HttpStatusCode import fr.ktorVoter.assertCanAll
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.application.*
import io.ktor.locations.Location import io.ktor.http.*
import io.ktor.locations.get import io.ktor.locations.*
import io.ktor.locations.put import io.ktor.request.*
import io.ktor.request.receive import io.ktor.response.*
import io.ktor.response.respond import io.ktor.routing.*
import io.ktor.routing.Route import io.ktor.util.*
import io.ktor.util.KtorExperimentalAPI
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.get import org.koin.core.get
import java.util.* import java.util.*
@@ -67,7 +65,7 @@ fun Route.opinionArticle(repo: OpinionArticleRepository) {
} }
get<OpinionArticlePaths.CitizenOpinions> { get<OpinionArticlePaths.CitizenOpinions> {
assertCan(VIEW, it.opinionsEntities) assertCanAll(VIEW, it.opinionsEntities)
call.respond(it.opinionsEntities) call.respond(it.opinionsEntities)
} }

View File

@@ -3,12 +3,11 @@ package fr.dcproject.routes
import fr.dcproject.entity.OpinionChoice import fr.dcproject.entity.OpinionChoice
import fr.dcproject.security.voter.OpinionChoiceVoter.Action.VIEW import fr.dcproject.security.voter.OpinionChoiceVoter.Action.VIEW
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import io.ktor.application.call import fr.ktorVoter.assertCanAll
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.application.*
import io.ktor.locations.Location import io.ktor.locations.*
import io.ktor.locations.get import io.ktor.response.*
import io.ktor.response.respond import io.ktor.routing.*
import io.ktor.routing.Route
import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@@ -30,7 +29,7 @@ fun Route.opinionChoice(repo: OpinionChoiceRepository) {
get<OpinionChoicePaths.OpinionChoicesRequest> { get<OpinionChoicePaths.OpinionChoicesRequest> {
val opinions = repo.findOpinionsChoices(it.targets) val opinions = repo.findOpinionsChoices(it.targets)
assertCan(VIEW, opinions) assertCanAll(VIEW, opinions)
call.respond(opinions) call.respond(opinions)
} }

View File

@@ -8,17 +8,15 @@ import fr.dcproject.routes.VoteArticlePaths.ArticleVoteRequest
import fr.dcproject.routes.VoteArticlePaths.CommentVoteRequest import fr.dcproject.routes.VoteArticlePaths.CommentVoteRequest
import fr.dcproject.security.voter.VoteVoter.Action.CREATE import fr.dcproject.security.voter.VoteVoter.Action.CREATE
import fr.dcproject.security.voter.VoteVoter.Action.VIEW import fr.dcproject.security.voter.VoteVoter.Action.VIEW
import fr.ktorVoter.assertCan
import fr.dcproject.utils.toUUID import fr.dcproject.utils.toUUID
import io.ktor.application.call import fr.ktorVoter.assertCan
import io.ktor.http.HttpStatusCode import fr.ktorVoter.assertCanAll
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.application.*
import io.ktor.locations.Location import io.ktor.http.*
import io.ktor.locations.get import io.ktor.locations.*
import io.ktor.locations.put import io.ktor.request.*
import io.ktor.request.receive import io.ktor.response.*
import io.ktor.response.respond import io.ktor.routing.*
import io.ktor.routing.Route
import java.util.* import java.util.*
import fr.dcproject.entity.Article as ArticleEntity import fr.dcproject.entity.Article as ArticleEntity
import fr.dcproject.entity.Vote as VoteEntity import fr.dcproject.entity.Vote as VoteEntity
@@ -79,7 +77,7 @@ fun Route.voteArticle(repo: VoteArticleRepository, voteCommentRepo: VoteComment,
get<VoteArticlePaths.CitizenVoteArticleRequest> { get<VoteArticlePaths.CitizenVoteArticleRequest> {
val votes = repo.findByCitizen(it.citizen, it.page, it.limit) val votes = repo.findByCitizen(it.citizen, it.page, it.limit)
assertCan(VIEW, votes.result) assertCanAll(VIEW, votes.result)
call.respond(votes) call.respond(votes)
} }
@@ -87,7 +85,7 @@ fun Route.voteArticle(repo: VoteArticleRepository, voteCommentRepo: VoteComment,
get<VoteArticlePaths.CitizenVotesByIdsRequest> { get<VoteArticlePaths.CitizenVotesByIdsRequest> {
val votes = repo.findCitizenVotesByTargets(it.citizen, it.id) val votes = repo.findCitizenVotesByTargets(it.citizen, it.id)
if (votes.isNotEmpty()) { if (votes.isNotEmpty()) {
assertCan(VIEW, votes) assertCanAll(VIEW, votes)
} }
call.respond(votes) call.respond(votes)
} }

View File

@@ -11,14 +11,14 @@ import fr.dcproject.security.voter.WorkgroupVoter.Action.UPDATE
import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW
import fr.dcproject.utils.toUUID import fr.dcproject.utils.toUUID
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import fr.ktorVoter.assertCanAll
import fr.postgresjson.repository.RepositoryI import fr.postgresjson.repository.RepositoryI
import io.ktor.application.ApplicationCall import io.ktor.application.*
import io.ktor.application.call import io.ktor.http.*
import io.ktor.http.HttpStatusCode
import io.ktor.locations.* import io.ktor.locations.*
import io.ktor.request.receive import io.ktor.request.*
import io.ktor.response.respond import io.ktor.response.*
import io.ktor.routing.Route import io.ktor.routing.*
import java.util.* import java.util.*
import fr.dcproject.entity.Workgroup as WorkgroupEntity import fr.dcproject.entity.Workgroup as WorkgroupEntity
import fr.dcproject.repository.Workgroup as WorkgroupRepository import fr.dcproject.repository.Workgroup as WorkgroupRepository
@@ -115,7 +115,7 @@ fun Route.workgroup(repo: WorkgroupRepository) {
get<WorkgroupsPaths.WorkgroupsRequest> { get<WorkgroupsPaths.WorkgroupsRequest> {
val workgroups = val workgroups =
repo.find(it.page, it.limit, it.sort, it.direction, it.search, Filter(createdById = it.createdBy, members = it.members)) 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) call.respond(workgroups)
} }

View File

@@ -2,7 +2,7 @@ package fr.dcproject.security.voter
import fr.dcproject.citizenOrNull import fr.dcproject.citizenOrNull
import fr.dcproject.entity.ArticleAuthI import fr.dcproject.entity.ArticleAuthI
import fr.dcproject.entity.ArticleForUpdate import fr.dcproject.entity.ArticleForUpdateI
import fr.dcproject.entity.ArticleI import fr.dcproject.entity.ArticleI
import fr.dcproject.entity.Citizen as CitizenEntity import fr.dcproject.entity.Citizen as CitizenEntity
import fr.dcproject.entity.CitizenI import fr.dcproject.entity.CitizenI
@@ -11,16 +11,15 @@ import fr.dcproject.repository.Article as ArticleRepo
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote import fr.ktorVoter.Vote
import fr.ktorVoter.Vote.Companion.toVote
import fr.ktorVoter.Voter import fr.ktorVoter.Voter
import fr.ktorVoter.checkClass
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.inject import org.koin.core.inject
import fr.dcproject.entity.Comment as CommentEntity import fr.dcproject.entity.Comment as CommentEntity
import fr.dcproject.entity.Vote as VoteEntity import fr.dcproject.entity.Vote as VoteEntity
class ArticleVoter : Voter, KoinComponent { class ArticleVoter(private val articleRepo: ArticleRepo) : Voter<ApplicationCall> {
private val articleRepo: ArticleRepo by inject()
enum class Action : ActionI { enum class Action : ActionI {
CREATE, CREATE,
UPDATE, UPDATE,
@@ -28,17 +27,16 @@ class ArticleVoter : Voter, KoinComponent {
DELETE DELETE
} }
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote {
return (action is Action || action is CommentVoter.Action || action is VoteVoter.Action) if (!((action is Action || action is CommentVoter.Action || action is VoteVoter.Action)
.and(subject is ArticleI? || subject is VoteEntity<*> || subject is CommentEntity<*>) && (subject is ArticleI? || subject is VoteEntity<*> || subject is CommentEntity<*>))
} ) return Vote.ABSTAIN
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { val user = context.user
val user = call.user
if (action == Action.CREATE && user is UserI) return Vote.GRANTED if (action == Action.CREATE && user is UserI) return Vote.GRANTED
if (action == Action.VIEW) return view(subject, user) if (action == Action.VIEW) return view(subject, user)
if (action == Action.DELETE) return delete(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 CommentVoter.Action) return voteForComment(action, subject)
if (action is VoteVoter.Action) return voteForVote(action, subject) if (action is VoteVoter.Action) return voteForVote(action, subject)
if (action is Action) return Vote.DENIED if (action is Action) return Vote.DENIED
@@ -47,7 +45,6 @@ class ArticleVoter : Voter, KoinComponent {
} }
private fun view(subject: Any?, user: UserI?): Vote { private fun view(subject: Any?, user: UserI?): Vote {
checkClass(ArticleAuthI::class, subject)
if (subject is ArticleAuthI<*>) { if (subject is ArticleAuthI<*>) {
return if (subject.isDeleted()) Vote.DENIED return if (subject.isDeleted()) Vote.DENIED
else if (subject.draft && (user == null || subject.createdBy.user.id != user.id)) 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 { private fun delete(subject: Any?, user: UserI?): Vote {
checkClass(ArticleAuthI::class, subject)
if (subject is ArticleAuthI<*>) { if (subject is ArticleAuthI<*>) {
if (user is UserI && subject.createdBy.user.id == user.id) { if (user is UserI && subject.createdBy.user.id == user.id) {
return Vote.GRANTED return Vote.GRANTED
@@ -67,15 +63,14 @@ class ArticleVoter : Voter, KoinComponent {
} }
private fun update(subject: Any?, citizen: CitizenEntity?): Vote { private fun update(subject: Any?, citizen: CitizenEntity?): Vote {
checkClass(ArticleForUpdate::class, subject) /* The new Article must by created by the same citizen of the connected citizen */
if (subject is ArticleForUpdate) { if (subject is ArticleForUpdateI && citizen is CitizenI && subject.createdBy.id == citizen.id) {
/* The new Article must by created by the same citizen of the connected citizen */ /* The creator must be the same of the creator of preview version of article */
if (citizen is CitizenI && subject.createdBy.id == citizen.id) { return toVote {
/* The creator must be the same of the creator of preview version of article */ articleRepo
if(articleRepo.findVerionsByVersionsId(1, 1, subject.versionId).result.first().createdBy.id == citizen.id) { .findVerionsByVersionsId(1, 1, subject.versionId)
return Vote.GRANTED .result.first()
} .createdBy.id == citizen.id
return Vote.DENIED
} }
} }
return Vote.DENIED return Vote.DENIED

View File

@@ -10,7 +10,7 @@ import io.ktor.application.ApplicationCall
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
class CitizenVoter : Voter { class CitizenVoter : Voter<ApplicationCall> {
enum class Action : ActionI { enum class Action : ActionI {
CREATE, CREATE,
UPDATE, UPDATE,
@@ -19,13 +19,11 @@ class CitizenVoter : Voter {
CHANGE_PASSWORD CHANGE_PASSWORD
} }
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote {
return (action is Action) if (!((action is Action)
.and(subject is CitizenBasicI?) && (subject is CitizenBasicI?))) return Vote.ABSTAIN
}
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { val user = context.user
val user = call.user
if (action == Action.CREATE && user != null) { if (action == Action.CREATE && user != null) {
return Vote.GRANTED return Vote.GRANTED
} }
@@ -56,14 +54,10 @@ class CitizenVoter : Voter {
return if (user.id == userToChange.id) { return if (user.id == userToChange.id) {
Vote.GRANTED Vote.GRANTED
} else { } else {
Vote.ABSTAIN Vote.DENIED
} }
} }
if (action is Action) { return Vote.DENIED
return Vote.DENIED
}
return Vote.ABSTAIN
} }
} }

View File

@@ -7,7 +7,7 @@ import fr.ktorVoter.Vote
import fr.ktorVoter.Voter import fr.ktorVoter.Voter
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
class CommentVoter : Voter { class CommentVoter : Voter<ApplicationCall> {
enum class Action : ActionI { enum class Action : ActionI {
CREATE, CREATE,
UPDATE, UPDATE,
@@ -15,15 +15,12 @@ class CommentVoter : Voter {
DELETE DELETE
} }
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote {
return (action is Action) if (!(action is Action && subject is Comment<*>?)) return Vote.ABSTAIN
.and(subject is Comment<*>?)
}
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { val user = context.user
val user = call.user
if (subject !is Comment<*>) { if (subject == null) {
return Vote.DENIED return Vote.DENIED
} }
@@ -50,10 +47,6 @@ class CommentVoter : Voter {
return Vote.DENIED return Vote.DENIED
} }
if (action is Action) { return Vote.DENIED
return Vote.DENIED
}
return Vote.ABSTAIN
} }
} }

View File

@@ -10,7 +10,7 @@ import fr.ktorVoter.Voter
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import fr.dcproject.entity.Vote as VoteEntity import fr.dcproject.entity.Vote as VoteEntity
class ConstitutionVoter : Voter { class ConstitutionVoter : Voter<ApplicationCall> {
enum class Action : ActionI { enum class Action : ActionI {
CREATE, CREATE,
UPDATE, UPDATE,
@@ -18,13 +18,11 @@ class ConstitutionVoter : Voter {
DELETE DELETE
} }
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote {
return (action is Action || action is CommentVoter.Action || action is VoteVoter.Action) if(!((action is Action || action is CommentVoter.Action || action is VoteVoter.Action)
.and(subject is ConstitutionSimple<*, *>? || subject is VoteEntity<*> || subject is Comment<*>) && (subject is ConstitutionSimple<*, *>? || subject is VoteEntity<*> || subject is Comment<*>))) return Vote.ABSTAIN
}
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { val user = context.user
val user = call.user
if (action == Action.CREATE && user != null) { if (action == Action.CREATE && user != null) {
return Vote.GRANTED return Vote.GRANTED
} }

View File

@@ -8,20 +8,18 @@ import io.ktor.application.ApplicationCall
import fr.dcproject.entity.Follow as FollowEntity import fr.dcproject.entity.Follow as FollowEntity
import fr.dcproject.entity.User as UserEntity import fr.dcproject.entity.User as UserEntity
class FollowVoter : Voter { class FollowVoter : Voter<ApplicationCall> {
enum class Action : ActionI { enum class Action : ActionI {
CREATE, CREATE,
DELETE, DELETE,
VIEW VIEW
} }
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote {
return (action is Action) if (!((action is Action)
.and(subject is FollowEntity<*>?) && (subject is FollowEntity<*>?))) return Vote.ABSTAIN
}
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { val user = context.user
val user = call.user
if (action == Action.CREATE) { if (action == Action.CREATE) {
return if (user != null) Vote.GRANTED return if (user != null) Vote.GRANTED
else Vote.DENIED else Vote.DENIED

View File

@@ -6,17 +6,15 @@ import fr.ktorVoter.Vote
import fr.ktorVoter.Voter import fr.ktorVoter.Voter
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
class OpinionChoiceVoter : Voter { class OpinionChoiceVoter : Voter<ApplicationCall> {
enum class Action : ActionI { enum class Action : ActionI {
VIEW VIEW
} }
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote {
return (action is Action) if (!((action is Action)
.and(subject is OpinionChoice?) && (subject is OpinionChoice?))) return Vote.ABSTAIN
}
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote {
if (action == Action.VIEW) { if (action == Action.VIEW) {
if (subject is OpinionChoice) { if (subject is OpinionChoice) {
return Vote.GRANTED return Vote.GRANTED

View File

@@ -1,49 +1,46 @@
package fr.dcproject.security.voter package fr.dcproject.security.voter
import fr.dcproject.entity.Article
import fr.dcproject.entity.ArticleAuthI import fr.dcproject.entity.ArticleAuthI
import fr.dcproject.entity.Opinion import fr.dcproject.entity.Opinion
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote import fr.ktorVoter.Vote
import fr.ktorVoter.Vote.Companion.toVote
import fr.ktorVoter.Voter import fr.ktorVoter.Voter
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
class OpinionVoter : Voter { class OpinionVoter : Voter<ApplicationCall> {
enum class Action : ActionI { enum class Action : ActionI {
CREATE, CREATE,
VIEW, VIEW,
DELETE DELETE
} }
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote {
return (action is Action) if (!((action is Action)
.and(subject is Opinion<*>? || subject is ArticleAuthI<*>) && (subject is Opinion<*>? || subject is ArticleAuthI<*>))) return Vote.ABSTAIN
}
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { val user = context.user
val user = call.user
if (action == Action.CREATE) { if (action == Action.CREATE) {
return if (user != null && ( return toVote {
(subject is ArticleAuthI<*> && !subject.isDeleted()) || user != null && (
(subject is Opinion<*> && subject.createdBy.user.id == user.id) (subject is ArticleAuthI<*> && !subject.isDeleted()) ||
)) Vote.GRANTED (subject is Opinion<*> && subject.createdBy.user.id == user.id)
else Vote.DENIED )
}
} }
if (action == Action.VIEW) { if (action == Action.VIEW) {
if (subject is Opinion<*>) { return toVote { subject is Opinion<*> || subject is Article }
return Vote.GRANTED
}
return Vote.DENIED
} }
if (action == Action.DELETE) { if (action == Action.DELETE) {
return if (subject is Opinion<*> && return toVote {
subject is Opinion<*> &&
user != null && user != null &&
subject.createdBy.user.id == user.id subject.createdBy.user.id == user.id
) }
Vote.GRANTED
else Vote.DENIED
} }
return Vote.ABSTAIN return Vote.ABSTAIN

View File

@@ -7,23 +7,22 @@ import fr.ktorVoter.Voter
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import fr.dcproject.entity.Vote as VoteEntity import fr.dcproject.entity.Vote as VoteEntity
class VoteVoter : Voter { class VoteVoter : Voter<ApplicationCall> {
enum class Action : ActionI { enum class Action : ActionI {
CREATE, CREATE,
VIEW VIEW
} }
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote {
return action is Action && subject is VoteEntity<*>? if (!(action is Action && subject is VoteEntity<*>?)) return Vote.ABSTAIN
}
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote { val user = context.user ?: return Vote.DENIED
val user = call.user
if (action == Action.CREATE && user != null) { if (action == Action.CREATE) {
return Vote.GRANTED return Vote.GRANTED
} }
if (action == Action.VIEW && user != null) { if (action == Action.VIEW) {
if (subject is VoteEntity<*>) { if (subject is VoteEntity<*>) {
return if (subject.createdBy.user.id != user.id) { return if (subject.createdBy.user.id != user.id) {
Vote.DENIED Vote.DENIED

View File

@@ -9,7 +9,7 @@ import fr.ktorVoter.Voter
import fr.ktorVoter.VoterException import fr.ktorVoter.VoterException
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
class WorkgroupVoter : Voter { class WorkgroupVoter : Voter<ApplicationCall> {
enum class Action : ActionI { enum class Action : ActionI {
CREATE, CREATE,
UPDATE, UPDATE,
@@ -24,13 +24,11 @@ class WorkgroupVoter : Voter {
REMOVE, REMOVE,
} }
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean { override fun invoke(action: Any, context: ApplicationCall, subject: Any?): Vote {
return (action is Action || action is ActionMembers) if (!((action is Action || action is ActionMembers)
.and(subject is WorkgroupI?) && (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 = context.user
val user = call.user
if (subject is WorkgroupI && action == Action.CREATE && user is UserI) { if (subject is WorkgroupI && action == Action.CREATE && user is UserI) {
return Vote.GRANTED return Vote.GRANTED
} }
@@ -62,7 +60,7 @@ class WorkgroupVoter : Voter {
if (action == ActionMembers.ADD) { if (action == ActionMembers.ADD) {
// TODO create ROLES // TODO create ROLES
return Vote.isGranted { return Vote.toVote {
user is UserI && user is UserI &&
subject is WorkgroupWithAuthI<*> && subject is WorkgroupWithAuthI<*> &&
subject.hasRole(Role.MASTER, user) subject.hasRole(Role.MASTER, user)
@@ -71,7 +69,7 @@ class WorkgroupVoter : Voter {
if (action == ActionMembers.UPDATE) { if (action == ActionMembers.UPDATE) {
// TODO create ROLES // TODO create ROLES
return Vote.isGranted { return Vote.toVote {
user is UserI && user is UserI &&
subject is WorkgroupWithAuthI<*> && subject is WorkgroupWithAuthI<*> &&
subject.hasRole(Role.MASTER, user) subject.hasRole(Role.MASTER, user)
@@ -80,7 +78,7 @@ class WorkgroupVoter : Voter {
if (action == ActionMembers.REMOVE) { if (action == ActionMembers.REMOVE) {
// TODO create ROLES // TODO create ROLES
return Vote.isGranted { return Vote.toVote {
user is UserI && user is UserI &&
subject is WorkgroupWithAuthI<*> && subject is WorkgroupWithAuthI<*> &&
subject.hasRole(Role.MASTER, user) subject.hasRole(Role.MASTER, user)

View File

@@ -6,7 +6,7 @@ import fr.postgresjson.serializer.deserialize
import fr.postgresjson.serializer.serialize import fr.postgresjson.serializer.serialize
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.util.KtorExperimentalAPI 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.amshove.kluent.shouldBe
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
import org.joda.time.DateTime import org.joda.time.DateTime
@@ -96,6 +96,6 @@ class ArticleTest {
@Test @Test
fun `test Article Deserialize`() { fun `test Article Deserialize`() {
val article2: Article = articleJson.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"
} }
} }

View File

@@ -6,6 +6,7 @@ import fr.postgresjson.serializer.deserialize
import fr.postgresjson.serializer.serialize import fr.postgresjson.serializer.serialize
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.util.KtorExperimentalAPI import io.ktor.util.KtorExperimentalAPI
import org.amshove.kluent.`should be equal to`
import org.amshove.kluent.`should equal` import org.amshove.kluent.`should equal`
import org.amshove.kluent.shouldBe import org.amshove.kluent.shouldBe
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
@@ -101,6 +102,6 @@ class ConstitutionTest {
@Test @Test
fun `test Constitution Deserialize`() { fun `test Constitution Deserialize`() {
val constitution2: Constitution = constitutionJson.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"
} }
} }

View File

@@ -3,6 +3,7 @@ import fr.postgresjson.serializer.deserialize
import fr.postgresjson.serializer.serialize import fr.postgresjson.serializer.serialize
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.util.KtorExperimentalAPI import io.ktor.util.KtorExperimentalAPI
import org.amshove.kluent.`should be equal to`
import org.amshove.kluent.`should equal` import org.amshove.kluent.`should equal`
import org.amshove.kluent.shouldBe import org.amshove.kluent.shouldBe
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
@@ -103,6 +104,6 @@ class FollowTest {
@Test @Test
fun `test Follow Article Deserialize`() { fun `test Follow Article Deserialize`() {
val follow: Follow<ArticleSimple> = followJson.deserialize()!! val follow: Follow<ArticleSimple> = followJson.deserialize()!!
follow.id.toString() `should equal` "bae81585-d985-4d7a-9b58-3a13e911688a" follow.id.toString() `should be equal to` "bae81585-d985-4d7a-9b58-3a13e911688a"
} }
} }

View File

@@ -6,7 +6,7 @@ import fr.dcproject.views.ArticleViewManager
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.server.testing.withTestApplication import io.ktor.server.testing.withTestApplication
import io.ktor.util.KtorExperimentalAPI 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.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
@@ -61,8 +61,8 @@ class ViewTest {
val afterView = viewManager.getViewsCount(article) val afterView = viewManager.getViewsCount(article)
/* Check if view has increment */ /* Check if view has increment */
afterView.total `should equal` startView.total + 4 afterView.total `should be equal to` startView.total + 4
afterView.unique `should equal` startView.unique + 3 afterView.unique `should be equal to` startView.unique + 3
} }
} }
} }

View File

@@ -3,6 +3,7 @@ import fr.postgresjson.serializer.deserialize
import fr.postgresjson.serializer.serialize import fr.postgresjson.serializer.serialize
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.util.KtorExperimentalAPI import io.ktor.util.KtorExperimentalAPI
import org.amshove.kluent.`should be equal to`
import org.amshove.kluent.`should equal` import org.amshove.kluent.`should equal`
import org.amshove.kluent.shouldBe import org.amshove.kluent.shouldBe
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
@@ -125,7 +126,7 @@ class VoteTest {
@Test @Test
fun `test Vote Article Deserialize`() { fun `test Vote Article Deserialize`() {
val vote: Vote<Article> = voteJson.deserialize()!! val vote: Vote<Article> = voteJson.deserialize()!!
vote.id.toString() `should equal` "032acc3d-e8c5-4cb2-9297-bec913ff8d9b" vote.id.toString() `should be equal to` "032acc3d-e8c5-4cb2-9297-bec913ff8d9b"
vote.note.toString() `should equal` "-1" vote.note.toString() `should be equal to` "-1"
} }
} }

View File

@@ -1,9 +1,12 @@
package fr.dcproject.security.voter package fr.dcproject.security.voter
import fr.dcproject.citizenOrNull
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.Vote import fr.ktorVoter.Vote
import fr.ktorVoter.can import fr.ktorVoter.can
import fr.ktorVoter.canAll
import fr.postgresjson.connexion.Paginated
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
@@ -13,11 +16,12 @@ import org.joda.time.DateTime
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import fr.dcproject.repository.Article as ArticleRepo
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Tag("voter") @Tag("voter")
internal class ArticleVoterTest { class ArticleVoterTest {
val tesla = CitizenBasic( private val tesla = Citizen(
user = User( user = User(
username = "nicolas-tesla", username = "nicolas-tesla",
roles = listOf(UserI.Roles.ROLE_USER) roles = listOf(UserI.Roles.ROLE_USER)
@@ -26,7 +30,7 @@ internal class ArticleVoterTest {
email = "tesla@best.com", email = "tesla@best.com",
name = CitizenI.Name("Nicolas", "Tesla") name = CitizenI.Name("Nicolas", "Tesla")
) )
val einstein = CitizenBasic( private val einstein = Citizen(
user = User( user = User(
username = "albert-einstein", username = "albert-einstein",
roles = listOf(UserI.Roles.ROLE_USER) roles = listOf(UserI.Roles.ROLE_USER)
@@ -36,24 +40,30 @@ internal class ArticleVoterTest {
name = CitizenI.Name("Albert", "Einstein") 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 { init {
mockkStatic("fr.dcproject.ApplicationContextKt") mockkStatic("fr.dcproject.ApplicationContextKt")
} }
@Test @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 } val article = getArticle(tesla).apply { draft = true }
ArticleVoter(getRepo(article)).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
supports(ArticleVoter.Action.VIEW, it, article) `should be` true this(ArticleVoter.Action.VIEW, it, article) `should be` Vote.GRANTED
vote(ArticleVoter.Action.VIEW, it, article) `should be` Vote.GRANTED }
} }
} }
@Test @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) val article = getArticle(tesla)
mockk<ApplicationCall> { mockk<ApplicationCall> {
@@ -64,19 +74,19 @@ internal class ArticleVoterTest {
} }
@Test @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 article = getArticle(tesla)
val article2 = getArticle(tesla) val article2 = getArticle(tesla)
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
can(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` true canAll(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` true
} }
} }
@Test @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 } val article = getArticle(tesla).apply { draft = true }
mockk<ApplicationCall> { mockk<ApplicationCall> {
@@ -87,19 +97,19 @@ internal class ArticleVoterTest {
} }
@Test @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 article = getArticle(tesla)
val article2 = getArticle(tesla).apply { draft = true } val article2 = getArticle(tesla).apply { draft = true }
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
can(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` false canAll(ArticleVoter.Action.VIEW, it, listOf(article, article2)) `should be` false
} }
} }
@Test @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() } val article = getArticle(tesla).apply { deletedAt = DateTime.now() }
mockk<ApplicationCall> { mockk<ApplicationCall> {
@@ -110,7 +120,7 @@ internal class ArticleVoterTest {
} }
@Test @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) val article = getArticle(tesla)
mockk<ApplicationCall> { mockk<ApplicationCall> {
@@ -121,7 +131,7 @@ internal class ArticleVoterTest {
} }
@Test @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() } val article = getArticle(tesla).apply { deletedAt = DateTime.now() }
mockk<ApplicationCall> { mockk<ApplicationCall> {
@@ -132,7 +142,7 @@ internal class ArticleVoterTest {
} }
@Test @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) val article = getArticle(tesla)
mockk<ApplicationCall> { mockk<ApplicationCall> {
@@ -143,7 +153,7 @@ internal class ArticleVoterTest {
} }
@Test @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) val article = getArticle(tesla)
mockk<ApplicationCall> { mockk<ApplicationCall> {
@@ -154,24 +164,28 @@ internal class ArticleVoterTest {
} }
@Test @Test
fun `can update article if yours`() = listOf(ArticleVoter()).run { fun `can update article if yours`(): Unit {
val article = getArticle(tesla) val article = getArticle(tesla)
listOf(ArticleVoter(getRepo(article))).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { every { citizenOrNull } returns tesla
can(ArticleVoter.Action.UPDATE, it, article) `should be` true }.let {
can(ArticleVoter.Action.UPDATE, it, article) `should be` true
}
} }
} }
@Test @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) val article = getArticle(tesla)
listOf(ArticleVoter(getRepo(article))).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { every { citizenOrNull } returns einstein
can(ArticleVoter.Action.UPDATE, it, article) `should be` false }.let {
can(ArticleVoter.Action.UPDATE, it, article) `should be` false
}
} }
} }

View File

@@ -6,7 +6,9 @@ import fr.dcproject.entity.User
import fr.dcproject.entity.UserI import fr.dcproject.entity.UserI
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote
import fr.ktorVoter.can import fr.ktorVoter.can
import fr.ktorVoter.canAll
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.mockk.every import io.mockk.every
@@ -21,7 +23,7 @@ import org.junit.jupiter.api.TestInstance
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Tag("voter") @Tag("voter")
internal class CitizenVoterTest { class CitizenVoterTest {
private val tesla = CitizenBasic( private val tesla = CitizenBasic(
user = User( user = User(
username = "nicolas-tesla", username = "nicolas-tesla",
@@ -56,18 +58,18 @@ internal class CitizenVoterTest {
} }
@Test @Test
fun `support citizen`() = CitizenVoter().run { fun `support citizen`(): Unit = CitizenVoter().run {
val p = object : ActionI {} val p = object : ActionI {}
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
supports(CitizenVoter.Action.VIEW, it, einstein) `should be` true this(CitizenVoter.Action.VIEW, it, einstein) `should be` Vote.GRANTED
supports(p, it, einstein) `should be` false this(p, it, einstein) `should be` Vote.ABSTAIN
} }
} }
@Test @Test
fun `can be view the citizen`() = listOf(CitizenVoter()).run { fun `can be view the citizen`(): Unit = listOf(CitizenVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -76,16 +78,16 @@ internal class CitizenVoterTest {
} }
@Test @Test
fun `can be view the citizen list`() = listOf(CitizenVoter()).run { fun `can be view the citizen list`(): Unit = listOf(CitizenVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
can(CitizenVoter.Action.VIEW, it, listOf(einstein, tesla)) `should be` true canAll(CitizenVoter.Action.VIEW, it, listOf(einstein, tesla)) `should be` true
} }
} }
@Test @Test
fun `can not view deleted citizen`() = listOf(CitizenVoter()).run { fun `can not view deleted citizen`(): Unit = listOf(CitizenVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -94,7 +96,7 @@ internal class CitizenVoterTest {
} }
@Test @Test
fun `can be update itself`() = listOf(CitizenVoter()).run { fun `can be update itself`(): Unit = listOf(CitizenVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -103,7 +105,7 @@ internal class CitizenVoterTest {
} }
@Test @Test
fun `can not be update other citizen`() = listOf(CitizenVoter()).run { fun `can not be update other citizen`(): Unit = listOf(CitizenVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -112,7 +114,7 @@ internal class CitizenVoterTest {
} }
@Test @Test
fun `can be change password of itself`() = listOf(CitizenVoter()).run { fun `can be change password of itself`(): Unit = listOf(CitizenVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -121,7 +123,7 @@ internal class CitizenVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {

View File

@@ -3,7 +3,10 @@ package fr.dcproject.security.voter
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote
import fr.ktorVoter.can import fr.ktorVoter.can
import fr.ktorVoter.canAll
import fr.postgresjson.connexion.Paginated
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.mockk.every import io.mockk.every
@@ -14,6 +17,7 @@ import org.joda.time.DateTime
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import fr.dcproject.repository.Article as ArticleRepo
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
@@ -51,6 +55,12 @@ internal class CommentVoterTest {
target = article1 target = article1
) )
private val comment2 = Comment(
content = "Hello2",
createdBy = einstein,
target = article1
)
private val commentTargetDeleted = Comment( private val commentTargetDeleted = Comment(
content = "Hello", content = "Hello",
createdBy = tesla, createdBy = tesla,
@@ -69,42 +79,48 @@ internal class CommentVoterTest {
target = ArticleRef() target = ArticleRef()
) )
private val repoArticle1 = mockk<ArticleRepo> {
every { findVerionsByVersionsId(1, 1, any()) } returns Paginated(listOf(article1), 0, 1, 1)
}
init { init {
mockkStatic("fr.dcproject.ApplicationContextKt") mockkStatic("fr.dcproject.ApplicationContextKt")
} }
@Test @Test
fun `support comment`() = CommentVoter().run { fun `support comment`(): Unit = CommentVoter().run {
val p = object : ActionI {} val p = object : ActionI {}
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
supports(CommentVoter.Action.VIEW, it, comment1) `should be` true this(CommentVoter.Action.VIEW, it, comment1) `should be` Vote.GRANTED
supports(CommentVoter.Action.VIEW, it, article1) `should be` false this(CommentVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
supports(p, it, comment1) `should be` false this(p, it, comment1) `should be` Vote.ABSTAIN
} }
} }
@Test @Test
fun `can be view the comment`() = listOf(CommentVoter(), ArticleVoter()).run { fun `can be view the comment`(): Unit {
mockk<ApplicationCall> { listOf(CommentVoter(), ArticleVoter(repoArticle1)).run {
every { user } returns tesla.user mockk<ApplicationCall> {
}.let { every { user } returns tesla.user
can(CommentVoter.Action.VIEW, it, comment1) `should be` true }.let {
can(CommentVoter.Action.VIEW, it, comment1) `should be` true
}
} }
} }
@Test @Test
fun `can be view the comment list`() = listOf(CommentVoter()).run { fun `can be view the comment list`(): Unit = listOf(CommentVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
can(CommentVoter.Action.VIEW, it, listOf(comment1)) `should be` true canAll(CommentVoter.Action.VIEW, it, listOf(comment1)) `should be` true
} }
} }
@Test @Test
fun `can be update your comment`() = listOf(CommentVoter()).run { fun `can be update your comment`(): Unit = listOf(CommentVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -113,7 +129,7 @@ internal class CommentVoterTest {
} }
@Test @Test
fun `can not be update other comment`() = listOf(CommentVoter()).run { fun `can not be update other comment`(): Unit = listOf(CommentVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -122,7 +138,7 @@ internal class CommentVoterTest {
} }
@Test @Test
fun `can not be delete your comment`() = listOf(CommentVoter()).run { fun `can not be delete your comment`(): Unit = listOf(CommentVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -131,7 +147,7 @@ internal class CommentVoterTest {
} }
@Test @Test
fun `can be create a comment`() = listOf(CommentVoter(), ArticleVoter()).run { fun `can be create a comment`(): Unit = listOf(CommentVoter(), ArticleVoter(repoArticle1)).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -140,7 +156,7 @@ internal class CommentVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -149,7 +165,7 @@ internal class CommentVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -158,7 +174,7 @@ internal class CommentVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -167,7 +183,7 @@ internal class CommentVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -176,7 +192,7 @@ internal class CommentVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns null every { user } returns null
}.let { }.let {

View File

@@ -3,7 +3,9 @@ package fr.dcproject.security.voter
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote
import fr.ktorVoter.can import fr.ktorVoter.can
import fr.ktorVoter.canAll
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.mockk.every import io.mockk.every
@@ -63,19 +65,19 @@ internal class FollowVoterTest {
} }
@Test @Test
fun `support follow`() = FollowVoter().run { fun `support follow`(): Unit = FollowVoter().run {
val p = object : ActionI {} val p = object : ActionI {}
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
supports(FollowVoter.Action.VIEW, it, follow1) `should be` true this(FollowVoter.Action.VIEW, it, follow1) `should be` Vote.GRANTED
supports(FollowVoter.Action.VIEW, it, article1) `should be` false this(FollowVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
supports(p, it, follow1) `should be` false this(p, it, follow1) `should be` Vote.ABSTAIN
} }
} }
@Test @Test
fun `can be view the follow`() = listOf(FollowVoter()).run { fun `can be view the follow`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -84,16 +86,16 @@ internal class FollowVoterTest {
} }
@Test @Test
fun `can be view the follow list`() = listOf(FollowVoter()).run { fun `can be view the follow list`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
can(FollowVoter.Action.VIEW, it, listOf(follow1)) `should be` true canAll(FollowVoter.Action.VIEW, it, listOf(follow1)) `should be` true
} }
} }
@Test @Test
fun `can be view your anonymous follow`() = listOf(FollowVoter()).run { fun `can be view your anonymous follow`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -102,7 +104,7 @@ internal class FollowVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -111,7 +113,7 @@ internal class FollowVoterTest {
} }
@Test @Test
fun `can be follow article`() = listOf(FollowVoter()).run { fun `can be follow article`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -120,7 +122,7 @@ internal class FollowVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns null every { user } returns null
}.let { }.let {
@@ -129,7 +131,7 @@ internal class FollowVoterTest {
} }
@Test @Test
fun `can be unfollow article`() = listOf(FollowVoter()).run { fun `can be unfollow article`(): Unit = listOf(FollowVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -138,7 +140,7 @@ internal class FollowVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns null every { user } returns null
}.let { }.let {

View File

@@ -3,7 +3,9 @@ package fr.dcproject.security.voter
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote
import fr.ktorVoter.can import fr.ktorVoter.can
import fr.ktorVoter.canAll
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.mockk.every import io.mockk.every
@@ -47,19 +49,19 @@ internal class OpinionChoiceVoterTest {
} }
@Test @Test
fun `support opinion choice`() = OpinionChoiceVoter().run { fun `support opinion choice`(): Unit = OpinionChoiceVoter().run {
val p = object : ActionI {} val p = object : ActionI {}
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
supports(OpinionChoiceVoter.Action.VIEW, it, choice1) `should be` true this(OpinionChoiceVoter.Action.VIEW, it, choice1) `should be` Vote.GRANTED
supports(OpinionChoiceVoter.Action.VIEW, it, article1) `should be` false this(OpinionChoiceVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
supports(p, it, choice1) `should be` false this(p, it, choice1) `should be` Vote.ABSTAIN
} }
} }
@Test @Test
fun `can be view the opinion choice`() = listOf(OpinionChoiceVoter()).run { fun `can be view the opinion choice`(): Unit = listOf(OpinionChoiceVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -68,11 +70,11 @@ internal class OpinionChoiceVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
can(OpinionChoiceVoter.Action.VIEW, it, listOf(choice1)) `should be` true canAll(OpinionChoiceVoter.Action.VIEW, it, listOf(choice1)) `should be` true
} }
} }
} }

View File

@@ -3,7 +3,9 @@ package fr.dcproject.security.voter
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote
import fr.ktorVoter.can import fr.ktorVoter.can
import fr.ktorVoter.canAll
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.mockk.every import io.mockk.every
@@ -62,20 +64,20 @@ internal class OpinionVoterTest {
} }
@Test @Test
fun `support opinion`() = OpinionVoter().run { fun `support opinion`(): Unit = OpinionVoter().run {
val p = object : ActionI {} val p = object : ActionI {}
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
supports(OpinionVoter.Action.VIEW, it, opinion1) `should be` true this(OpinionVoter.Action.VIEW, it, opinion1) `should be` Vote.GRANTED
supports(OpinionVoter.Action.VIEW, it, article1) `should be` true this(OpinionVoter.Action.VIEW, it, article1) `should be` Vote.GRANTED
supports(OpinionVoter.Action.VIEW, it, einstein) `should be` false this(OpinionVoter.Action.VIEW, it, einstein) `should be` Vote.ABSTAIN
supports(p, it, opinion1) `should be` false this(p, it, opinion1) `should be` Vote.ABSTAIN
} }
} }
@Test @Test
fun `can be view the opinion`() = listOf(OpinionVoter()).run { fun `can be view the opinion`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -84,7 +86,7 @@ internal class OpinionVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -93,16 +95,16 @@ internal class OpinionVoterTest {
} }
@Test @Test
fun `can be view the opinion list`() = listOf(OpinionVoter()).run { fun `can be view the opinion list`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
can(OpinionVoter.Action.VIEW, it, listOf(opinion1)) `should be` true canAll(OpinionVoter.Action.VIEW, it, listOf(opinion1)) `should be` true
} }
} }
@Test @Test
fun `can be opinion an article`() = listOf(OpinionVoter()).run { fun `can be opinion an article`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -120,7 +122,7 @@ internal class OpinionVoterTest {
} }
@Test @Test
fun `can be remove opinion`() = listOf(OpinionVoter()).run { fun `can be remove opinion`(): Unit = listOf(OpinionVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -129,7 +131,7 @@ internal class OpinionVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns null every { user } returns null
}.let { }.let {
@@ -138,7 +140,7 @@ internal class OpinionVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {

View File

@@ -3,7 +3,10 @@ package fr.dcproject.security.voter
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote
import fr.ktorVoter.can import fr.ktorVoter.can
import fr.ktorVoter.canAll
import fr.postgresjson.connexion.Paginated
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.mockk.every import io.mockk.every
@@ -77,19 +80,19 @@ internal class VoteVoterTest {
} }
@Test @Test
fun `support vote`() = VoteVoter().run { fun `support vote`(): Unit = VoteVoter().run {
val p = object : ActionI {} val p = object : ActionI {}
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
supports(VoteVoter.Action.VIEW, it, vote1) `should be` true this(VoteVoter.Action.VIEW, it, vote1) `should be` Vote.GRANTED
supports(VoteVoter.Action.VIEW, it, article1) `should be` false this(VoteVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
supports(p, it, vote1) `should be` false this(p, it, vote1) `should be` Vote.ABSTAIN
} }
} }
@Test @Test
fun `can be view your the vote`() = listOf(VoteVoter()).run { fun `can be view your the vote`(): Unit = listOf(VoteVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -98,7 +101,7 @@ internal class VoteVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -107,7 +110,7 @@ internal class VoteVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -116,25 +119,27 @@ internal class VoteVoterTest {
} }
@Test @Test
fun `can be view your votes list`() = listOf(VoteVoter()).run { fun `can be view your votes list`(): Unit = listOf(VoteVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
can(VoteVoter.Action.VIEW, it, listOf(vote1)) `should be` true canAll(VoteVoter.Action.VIEW, it, listOf(vote1)) `should be` true
} }
} }
@Test @Test
fun `can be vote an article`() = listOf(VoteVoter(), ArticleVoter()).run { fun `can be vote an article`(): Unit {
mockk<ApplicationCall> { listOf(VoteVoter(), ArticleVoter(mockk())).run {
every { user } returns tesla.user mockk<ApplicationCall> {
}.let { every { user } returns tesla.user
can(VoteVoter.Action.CREATE, it, vote1) `should be` true }.let {
can(VoteVoter.Action.CREATE, it, vote1) `should be` true
}
} }
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns null every { user } returns null
}.let { }.let {
@@ -143,7 +148,7 @@ internal class VoteVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -152,7 +157,7 @@ internal class VoteVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -161,7 +166,7 @@ internal class VoteVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {

View File

@@ -3,6 +3,7 @@ package fr.dcproject.security.voter
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote
import fr.ktorVoter.VoterException import fr.ktorVoter.VoterException
import fr.ktorVoter.can import fr.ktorVoter.can
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
@@ -74,19 +75,19 @@ internal class WorkgroupVoterTest {
} }
@Test @Test
fun `support workgroup`() = WorkgroupVoter().run { fun `support workgroup`(): Unit = WorkgroupVoter().run {
val p = object : ActionI {} val p = object : ActionI {}
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
supports(WorkgroupVoter.Action.VIEW, it, workgroupPublic) `should be` true this(WorkgroupVoter.Action.VIEW, it, workgroupPublic) `should be` Vote.GRANTED
supports(WorkgroupVoter.Action.VIEW, it, article1) `should be` false this(WorkgroupVoter.Action.VIEW, it, article1) `should be` Vote.ABSTAIN
supports(p, it, workgroupPublic) `should be` false this(p, it, workgroupPublic) `should be` Vote.ABSTAIN
} }
} }
@Test @Test
fun `can be view your workgroup`() = listOf(WorkgroupVoter()).run { fun `can be view your workgroup`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -95,7 +96,7 @@ internal class WorkgroupVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -104,7 +105,7 @@ internal class WorkgroupVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -113,7 +114,7 @@ internal class WorkgroupVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -122,7 +123,7 @@ internal class WorkgroupVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -131,16 +132,18 @@ internal class WorkgroupVoterTest {
} }
@Test @Test
fun `can be view your workgroup list`() = listOf(WorkgroupVoter()).run { fun `can be view your workgroup list`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.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 @Test
fun `can be create workgroup`() = listOf(WorkgroupVoter()).run { fun `can be create workgroup`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -149,7 +152,7 @@ internal class WorkgroupVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns null every { user } returns null
}.let { }.let {
@@ -158,7 +161,7 @@ internal class WorkgroupVoterTest {
} }
@Test @Test
fun `can be delete workgroup if owner`() = listOf(WorkgroupVoter()).run { fun `can be delete workgroup if owner`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -167,7 +170,7 @@ internal class WorkgroupVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {
@@ -176,7 +179,7 @@ internal class WorkgroupVoterTest {
} }
@Test @Test
fun `can be update workgroup if owner`() = listOf(WorkgroupVoter()).run { fun `can be update workgroup if owner`(): Unit = listOf(WorkgroupVoter()).run {
mockk<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns tesla.user every { user } returns tesla.user
}.let { }.let {
@@ -185,7 +188,7 @@ internal class WorkgroupVoterTest {
} }
@Test @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<ApplicationCall> { mockk<ApplicationCall> {
every { user } returns einstein.user every { user } returns einstein.user
}.let { }.let {