Big refactoring #77

Merged
flecomte merged 166 commits from refactoring-component-and-immutable into master 2021-03-24 19:06:07 +01:00
6 changed files with 48 additions and 22 deletions
Showing only changes of commit 74923891d0 - Show all commits

View File

@@ -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
View File

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

View File

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

View File

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

View File

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

View File

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