Big refactoring #77
3
.idea/codeStyles/Project.xml
generated
3
.idea/codeStyles/Project.xml
generated
@@ -18,6 +18,8 @@
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<PostgresCodeStyleSettings version="2">
|
||||
@@ -25,6 +27,7 @@
|
||||
<option name="KEYWORD_CASE" value="1" />
|
||||
<option name="IDENTIFIER_CASE" value="1" />
|
||||
<option name="TYPE_CASE" value="1" />
|
||||
<option name="CUSTOM_TYPE_CASE" value="1" />
|
||||
<option name="ALIAS_CASE" value="1" />
|
||||
</PostgresCodeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
|
||||
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@@ -10,4 +10,7 @@
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="corretto-11" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="TaskProjectConfiguration">
|
||||
<server type="GitHub" url="https://github.com" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -36,9 +36,11 @@ class ArticleForUpdate(
|
||||
tags: List<String> = emptyList(),
|
||||
val draft: Boolean = false,
|
||||
val createdBy: CitizenRef,
|
||||
val workgroup: WorkgroupRef? = null
|
||||
) : ArticleRefVersioning(id) {
|
||||
val workgroup: WorkgroupRef? = null,
|
||||
versionId: UUID?
|
||||
) : ArticleRefVersioning(id, versionId = versionId ?: UUID.randomUUID()) {
|
||||
val tags: List<String> = tags.distinct()
|
||||
val isNew = versionId == null
|
||||
}
|
||||
|
||||
open class ArticleSimple(
|
||||
|
||||
@@ -11,6 +11,7 @@ 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
|
||||
@@ -81,18 +82,17 @@ object ArticlesPaths {
|
||||
|
||||
suspend fun getNewArticle(call: ApplicationCall): ArticleForUpdate = call.receive<Article>().run {
|
||||
ArticleForUpdate(
|
||||
id ?: UUID.randomUUID(),
|
||||
title,
|
||||
anonymous,
|
||||
content,
|
||||
description,
|
||||
tags,
|
||||
draft,
|
||||
id = id ?: UUID.randomUUID(),
|
||||
title = title,
|
||||
anonymous = anonymous,
|
||||
content = content,
|
||||
description = description,
|
||||
tags = tags,
|
||||
draft = draft,
|
||||
createdBy = call.citizen,
|
||||
workgroup = if (workgroup != null) workgroupRepository.findById(workgroup.id) as WorkgroupSimple<CitizenRef> else null
|
||||
).also {
|
||||
it.versionId = versionId ?: UUID.randomUUID()
|
||||
}
|
||||
workgroup = if (workgroup != null) workgroupRepository.findById(workgroup.id) as WorkgroupSimple<CitizenRef> else null,
|
||||
versionId = versionId
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,11 @@ fun Route.article(repo: ArticleRepository, viewManager: ArticleViewManager) {
|
||||
|
||||
post<ArticlesPaths.PostArticleRequest> {
|
||||
it.getNewArticle(call).also { article ->
|
||||
assertCan(CREATE, article)
|
||||
if(article.isNew) {
|
||||
assertCan(CREATE, article)
|
||||
} else {
|
||||
assertCan(UPDATE, article)
|
||||
}
|
||||
val newArticle = repo.upsert(article) ?: error("Article not updated")
|
||||
call.respond(article)
|
||||
raiseEvent(ArticleUpdate.event, ArticleUpdate(newArticle))
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
package fr.dcproject.security.voter
|
||||
|
||||
import fr.dcproject.citizenOrNull
|
||||
import fr.dcproject.entity.ArticleAuthI
|
||||
import fr.dcproject.entity.ArticleForUpdate
|
||||
import fr.dcproject.entity.ArticleI
|
||||
import fr.dcproject.entity.Citizen as CitizenEntity
|
||||
import fr.dcproject.entity.CitizenI
|
||||
import fr.dcproject.entity.UserI
|
||||
import fr.dcproject.repository.Article as ArticleRepo
|
||||
import fr.dcproject.user
|
||||
import fr.ktorVoter.ActionI
|
||||
import fr.ktorVoter.Vote
|
||||
import fr.ktorVoter.Voter
|
||||
import fr.ktorVoter.checkClass
|
||||
import io.ktor.application.ApplicationCall
|
||||
import 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 {
|
||||
class ArticleVoter : Voter, KoinComponent {
|
||||
private val articleRepo: ArticleRepo by inject()
|
||||
enum class Action : ActionI {
|
||||
CREATE,
|
||||
UPDATE,
|
||||
@@ -30,7 +38,7 @@ class ArticleVoter : Voter {
|
||||
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, user)
|
||||
if (action == Action.UPDATE) return update(subject, call.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
|
||||
@@ -58,11 +66,16 @@ class ArticleVoter : Voter {
|
||||
return Vote.DENIED
|
||||
}
|
||||
|
||||
private fun update(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
|
||||
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
|
||||
}
|
||||
}
|
||||
return Vote.DENIED
|
||||
|
||||
@@ -73,7 +73,8 @@ class ArticleSteps : En, KoinTest {
|
||||
content = "bla bla bla",
|
||||
description = "A super article",
|
||||
createdBy = createdBy,
|
||||
workgroup = workgroup
|
||||
workgroup = workgroup,
|
||||
versionId = UUID.randomUUID()
|
||||
)
|
||||
get<ArticleRepository>().upsert(article)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user