Big refactoring #77
@@ -19,7 +19,6 @@ import fr.dcproject.component.vote.entity.VotableImp
|
||||
import fr.dcproject.component.workgroup.WorkgroupCart
|
||||
import fr.dcproject.component.workgroup.WorkgroupCartI
|
||||
import fr.dcproject.component.workgroup.WorkgroupRef
|
||||
import fr.dcproject.component.workgroup.WorkgroupSimple
|
||||
import org.joda.time.DateTime
|
||||
import java.util.UUID
|
||||
|
||||
@@ -33,7 +32,7 @@ data class ArticleForView(
|
||||
override val createdBy: CitizenRef,
|
||||
override val versionNumber: Int = 0,
|
||||
override val versionId: UUID = UUID.randomUUID(),
|
||||
val workgroup: WorkgroupSimple<CitizenRef>? = null,
|
||||
val workgroup: WorkgroupCart? = null,
|
||||
override val opinions: Opinions = emptyMap(),
|
||||
override val draft: Boolean = false,
|
||||
override val deletedAt: DateTime? = null
|
||||
|
||||
@@ -47,7 +47,9 @@ object GetOneArticle {
|
||||
val draft = article.draft
|
||||
val lastVersion = article.lastVersion
|
||||
val createdBy = article.createdBy
|
||||
val workgroup = article.workgroup // TODO change to workgroup DTO
|
||||
val workgroup = article.workgroup?.let { Workgroup(article.workgroup.id, article.workgroup.name) }
|
||||
|
||||
class Workgroup(val id: UUID, val name: String)
|
||||
}
|
||||
|
||||
fun Route.getOneArticle(viewManager: ArticleViewManager<ArticleForView>, ac: ArticleAccessControl, repo: ArticleRepository) {
|
||||
|
||||
@@ -20,10 +20,11 @@ class UserForCreate(
|
||||
|
||||
open class User(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
var username: String,
|
||||
override var username: String,
|
||||
var blockedAt: DateTime? = null,
|
||||
var roles: List<Roles> = emptyList()
|
||||
) : UserRef(id),
|
||||
UserWithUsername,
|
||||
CreatedAt by CreatedAt.Imp(),
|
||||
UpdatedAt by UpdatedAt.Imp()
|
||||
|
||||
@@ -32,12 +33,11 @@ class UserCreator(
|
||||
override val username: String,
|
||||
) : UserRef(id), UserWithUsername
|
||||
|
||||
interface UserWithUsername {
|
||||
interface UserWithUsername : UserI {
|
||||
val username: String
|
||||
}
|
||||
|
||||
interface UserWithPasswordI {
|
||||
val id: UUID
|
||||
interface UserWithPasswordI : UserI {
|
||||
val password: String
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,9 @@ import fr.dcproject.component.auth.UserCreator
|
||||
import fr.dcproject.component.auth.UserForCreate
|
||||
import fr.dcproject.component.auth.UserI
|
||||
import fr.dcproject.component.auth.UserRef
|
||||
import fr.dcproject.component.auth.UserWithUsername
|
||||
import fr.dcproject.component.citizen.CitizenI.Name
|
||||
import fr.dcproject.component.workgroup.WorkgroupSimple
|
||||
import fr.dcproject.component.workgroup.WorkgroupRef
|
||||
import fr.postgresjson.entity.Serializable
|
||||
import org.joda.time.DateTime
|
||||
import java.util.UUID
|
||||
@@ -38,6 +39,7 @@ class Citizen(
|
||||
deletedAt: DateTime? = null
|
||||
) : CitizenFull,
|
||||
CitizenBasicI,
|
||||
CitizenCreatorI,
|
||||
CitizenWithUserI,
|
||||
CitizenRef(id),
|
||||
CitizenCartI,
|
||||
@@ -47,7 +49,7 @@ class Citizen(
|
||||
|
||||
class WorkgroupAndRoles(
|
||||
val roles: List<String>,
|
||||
val workgroup: WorkgroupSimple<CitizenRef>
|
||||
val workgroup: WorkgroupRef
|
||||
)
|
||||
}
|
||||
|
||||
@@ -69,7 +71,7 @@ interface CitizenCreatorI : CitizenWithUserI, CitizenWithEmail, CitizenCartI, De
|
||||
override val email: String
|
||||
val voteAnonymous: Boolean
|
||||
val followAnonymous: Boolean
|
||||
override val user: UserCreator
|
||||
override val user: UserWithUsername
|
||||
override val deletedAt: DateTime?
|
||||
}
|
||||
|
||||
|
||||
@@ -7,47 +7,47 @@ import fr.dcproject.common.entity.Entity
|
||||
import fr.dcproject.common.entity.EntityI
|
||||
import fr.dcproject.common.entity.UpdatedAt
|
||||
import fr.dcproject.component.auth.UserI
|
||||
import fr.dcproject.component.citizen.CitizenBasicI
|
||||
import fr.dcproject.component.citizen.CitizenCreatorI
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.component.citizen.CitizenWithUserI
|
||||
import fr.dcproject.component.workgroup.WorkgroupWithMembersI.Member
|
||||
import fr.dcproject.component.workgroup.WorkgroupWithMembersI.Member.Role
|
||||
import fr.postgresjson.entity.Serializable
|
||||
import org.joda.time.DateTime
|
||||
import java.util.UUID
|
||||
|
||||
@Deprecated("")
|
||||
data class Workgroup <C : CitizenBasicI>(
|
||||
data class WorkgroupForView<C : CitizenCreatorI>(
|
||||
override val id: UUID = UUID.randomUUID(),
|
||||
override var name: String,
|
||||
override var description: String,
|
||||
override var logo: String? = null,
|
||||
val name: String,
|
||||
val description: String,
|
||||
val logo: String? = null,
|
||||
override var anonymous: Boolean = true,
|
||||
override val createdBy: C,
|
||||
override var members: List<Member<C>> = emptyList()
|
||||
) : WorkgroupWithAuthI<C>,
|
||||
WorkgroupSimple<C>(
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
logo,
|
||||
anonymous,
|
||||
createdBy
|
||||
),
|
||||
WorkgroupRef(id),
|
||||
CreatedBy<C> by CreatedBy.Imp(createdBy),
|
||||
CreatedAt by CreatedAt.Imp(),
|
||||
UpdatedAt by UpdatedAt.Imp()
|
||||
|
||||
@Deprecated("")
|
||||
open class WorkgroupSimple<Z : CitizenI>(
|
||||
id: UUID? = null,
|
||||
open var name: String,
|
||||
open var description: String,
|
||||
open var logo: String? = null,
|
||||
open var anonymous: Boolean = true,
|
||||
createdBy: Z
|
||||
) : WorkgroupRef(id),
|
||||
CreatedBy<Z> by CreatedBy.Imp(createdBy),
|
||||
UpdatedAt by UpdatedAt.Imp(),
|
||||
DeletedAt by DeletedAt.Imp()
|
||||
|
||||
data class WorkgroupForUpdate<C : CitizenWithUserI>(
|
||||
override val id: UUID,
|
||||
override val name: String,
|
||||
override val description: String,
|
||||
override val createdBy: C,
|
||||
override val logo: String? = null,
|
||||
override val anonymous: Boolean = true,
|
||||
override val members: List<Member<C>> = listOf(),
|
||||
override val deletedAt: DateTime? = null,
|
||||
) : WorkgroupRef(id),
|
||||
WorkgroupForUpdateI<C>,
|
||||
CreatedBy<C> by CreatedBy.Imp(createdBy)
|
||||
|
||||
interface WorkgroupForUpdateI<C : CitizenWithUserI> : WorkgroupWithAuthI<C>, WorkgroupCartI, CreatedBy<C> {
|
||||
val description: String
|
||||
val logo: String?
|
||||
}
|
||||
|
||||
class WorkgroupCart(
|
||||
override val id: UUID,
|
||||
override val name: String
|
||||
@@ -56,6 +56,7 @@ class WorkgroupCart(
|
||||
interface WorkgroupCartI : EntityI {
|
||||
val name: String
|
||||
}
|
||||
|
||||
open class WorkgroupRef(
|
||||
id: UUID? = null
|
||||
) : Entity(id ?: UUID.randomUUID()), WorkgroupI
|
||||
@@ -74,9 +75,9 @@ interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupWithMembersI<Z>, C
|
||||
}
|
||||
|
||||
interface WorkgroupWithMembersI<Z : CitizenI> : WorkgroupI {
|
||||
var members: List<Member<Z>>
|
||||
val members: List<Member<Z>>
|
||||
|
||||
class Member<C : CitizenI> (
|
||||
class Member<C : CitizenI>(
|
||||
val citizen: C,
|
||||
val roles: List<Role> = emptyList()
|
||||
) : fr.postgresjson.entity.EntityI {
|
||||
@@ -1,7 +1,9 @@
|
||||
package fr.dcproject.component.workgroup
|
||||
|
||||
import fr.dcproject.component.citizen.CitizenBasic
|
||||
import fr.dcproject.component.citizen.CitizenCreator
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.workgroup.WorkgroupWithMembersI.Member
|
||||
import fr.postgresjson.connexion.Paginated
|
||||
import fr.postgresjson.connexion.Requester
|
||||
@@ -11,10 +13,10 @@ import fr.postgresjson.repository.RepositoryI.Direction
|
||||
import fr.postgresjson.serializer.serialize
|
||||
import net.pearx.kasechange.toSnakeCase
|
||||
import java.util.UUID
|
||||
import fr.dcproject.component.workgroup.Workgroup as WorkgroupEntity
|
||||
import fr.dcproject.component.workgroup.WorkgroupForView as WorkgroupEntity
|
||||
|
||||
class WorkgroupRepository(override var requester: Requester) : RepositoryI {
|
||||
fun findById(id: UUID): WorkgroupEntity<CitizenBasic>? {
|
||||
fun findById(id: UUID): WorkgroupEntity<CitizenCreator>? {
|
||||
val function = requester.getFunction("find_workgroup_by_id")
|
||||
return function.selectOne("id" to id)
|
||||
}
|
||||
@@ -26,7 +28,7 @@ class WorkgroupRepository(override var requester: Requester) : RepositoryI {
|
||||
direction: Direction? = null,
|
||||
search: String? = null,
|
||||
filter: Filter = Filter()
|
||||
): Paginated<WorkgroupEntity<CitizenBasic>> {
|
||||
): Paginated<WorkgroupEntity<CitizenCreator>> {
|
||||
return requester
|
||||
.getFunction("find_workgroups")
|
||||
.select(
|
||||
@@ -39,7 +41,7 @@ class WorkgroupRepository(override var requester: Requester) : RepositoryI {
|
||||
)
|
||||
}
|
||||
|
||||
fun <C : CitizenI, W : WorkgroupSimple<C>> upsert(workgroup: W): WorkgroupEntity<CitizenBasic> = requester
|
||||
fun <C : CitizenI, W : WorkgroupForUpdateI<C>> upsert(workgroup: W): WorkgroupEntity<CitizenCreator> = requester
|
||||
.getFunction("upsert_workgroup")
|
||||
.selectOne("resource" to workgroup) ?: error("query 'upsert_workgroup' return null")
|
||||
|
||||
@@ -47,10 +49,10 @@ class WorkgroupRepository(override var requester: Requester) : RepositoryI {
|
||||
.getFunction("delete_workgroup")
|
||||
.perform("id" to workgroup.id)
|
||||
|
||||
fun addMember(workgroup: WorkgroupI, member: Member<CitizenI>): Member<CitizenBasic>? =
|
||||
fun addMember(workgroup: WorkgroupI, member: Member<CitizenI>): Member<CitizenRef>? =
|
||||
addMember(workgroup, member.citizen, member.roles)
|
||||
|
||||
fun addMember(workgroup: WorkgroupI, citizen: CitizenI, roles: List<Member.Role>): Member<CitizenBasic>? = requester
|
||||
fun addMember(workgroup: WorkgroupI, citizen: CitizenI, roles: List<Member.Role>): Member<CitizenRef>? = requester
|
||||
.getFunction("add_workgroup_member")
|
||||
.selectOne(
|
||||
"id" to workgroup.id,
|
||||
@@ -81,14 +83,6 @@ class WorkgroupRepository(override var requester: Requester) : RepositoryI {
|
||||
"members" to members
|
||||
)
|
||||
|
||||
fun <W : WorkgroupWithMembersI<Z>, Z : CitizenI> updateMembers(workgroup: W): W {
|
||||
updateMembers(workgroup, workgroup.members).let {
|
||||
workgroup.members = it as List<Member<Z>>
|
||||
}
|
||||
|
||||
return workgroup
|
||||
}
|
||||
|
||||
class Filter(
|
||||
val createdById: String? = null,
|
||||
val members: List<UUID>? = null
|
||||
|
||||
@@ -5,8 +5,8 @@ import fr.dcproject.common.utils.receiveOrBadRequest
|
||||
import fr.dcproject.component.auth.citizen
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.workgroup.WorkgroupAccessControl
|
||||
import fr.dcproject.component.workgroup.WorkgroupForUpdate
|
||||
import fr.dcproject.component.workgroup.WorkgroupRepository
|
||||
import fr.dcproject.component.workgroup.WorkgroupSimple
|
||||
import fr.dcproject.component.workgroup.routes.CreateWorkgroup.PostWorkgroupRequest.Input
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
@@ -33,13 +33,13 @@ object CreateWorkgroup {
|
||||
fun Route.createWorkgroup(repo: WorkgroupRepository, ac: WorkgroupAccessControl) {
|
||||
post<PostWorkgroupRequest> {
|
||||
call.receiveOrBadRequest<Input>().run {
|
||||
WorkgroupSimple(
|
||||
WorkgroupForUpdate(
|
||||
id ?: UUID.randomUUID(),
|
||||
name,
|
||||
description,
|
||||
citizen,
|
||||
logo,
|
||||
anonymous ?: true,
|
||||
citizen
|
||||
)
|
||||
}.let { workgroup ->
|
||||
ac.assert { canCreate(workgroup, citizenOrNull) }
|
||||
|
||||
@@ -4,6 +4,7 @@ import fr.dcproject.common.security.assert
|
||||
import fr.dcproject.common.utils.receiveOrBadRequest
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.workgroup.WorkgroupAccessControl
|
||||
import fr.dcproject.component.workgroup.WorkgroupForUpdate
|
||||
import fr.dcproject.component.workgroup.WorkgroupRepository
|
||||
import fr.dcproject.component.workgroup.routes.EditWorkgroup.PutWorkgroupRequest.Input
|
||||
import io.ktor.application.call
|
||||
@@ -32,11 +33,15 @@ object EditWorkgroup {
|
||||
put<PutWorkgroupRequest> {
|
||||
repo.findById(it.workgroupId)?.let { old ->
|
||||
call.receiveOrBadRequest<Input>().run {
|
||||
old.copy(
|
||||
WorkgroupForUpdate(
|
||||
id = old.id,
|
||||
name = name ?: old.name,
|
||||
description = description ?: old.description,
|
||||
createdBy = old.createdBy,
|
||||
logo = logo ?: old.logo,
|
||||
anonymous = anonymous ?: old.anonymous
|
||||
anonymous = anonymous ?: old.anonymous,
|
||||
deletedAt = old.deletedAt,
|
||||
members = old.members,
|
||||
).let { workgroup ->
|
||||
ac.assert { canUpdate(workgroup, citizenOrNull) }
|
||||
repo.upsert(workgroup)
|
||||
|
||||
@@ -3,11 +3,12 @@ package integration.steps.given
|
||||
import fr.dcproject.common.utils.toUUID
|
||||
import fr.dcproject.component.auth.UserForCreate
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.citizen.CitizenBasic
|
||||
import fr.dcproject.component.citizen.CitizenCreator
|
||||
import fr.dcproject.component.citizen.CitizenForCreate
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.component.citizen.CitizenRepository
|
||||
import fr.dcproject.component.workgroup.Workgroup
|
||||
import fr.dcproject.component.workgroup.WorkgroupForUpdate
|
||||
import fr.dcproject.component.workgroup.WorkgroupForView
|
||||
import fr.dcproject.component.workgroup.WorkgroupRepository
|
||||
import fr.dcproject.component.workgroup.WorkgroupWithMembersI.Member
|
||||
import fr.dcproject.component.workgroup.WorkgroupWithMembersI.Member.Role.MASTER
|
||||
@@ -22,18 +23,18 @@ fun TestApplicationEngine.`Given I have workgroup`(
|
||||
description: String? = null,
|
||||
anonymous: Boolean? = null,
|
||||
createdBy: CitizenI.Name? = null,
|
||||
callback: Workgroup<CitizenBasic>.() -> Unit = {},
|
||||
callback: WorkgroupForView<CitizenCreator>.() -> Unit = {},
|
||||
) {
|
||||
val workgroup: Workgroup<CitizenBasic> = createWorkgroup(id?.toUUID(), name, description, anonymous, createdBy)
|
||||
val workgroup: WorkgroupForView<CitizenCreator> = createWorkgroup(id?.toUUID(), name, description, anonymous, createdBy)
|
||||
callback(workgroup)
|
||||
}
|
||||
fun Workgroup<CitizenBasic>.`With members`(
|
||||
fun WorkgroupForView<CitizenCreator>.`With members`(
|
||||
vararg member: CitizenI.Name
|
||||
) {
|
||||
addMemberToWorkgroup(this, *member)
|
||||
}
|
||||
|
||||
fun addMemberToWorkgroup(workgroup: Workgroup<CitizenBasic>, vararg membersNames: CitizenI.Name) {
|
||||
fun addMemberToWorkgroup(workgroup: WorkgroupForView<CitizenCreator>, vararg membersNames: CitizenI.Name) {
|
||||
val citizenRepository: CitizenRepository by lazy { GlobalContext.get().koin.get() }
|
||||
val workgroupRepository: WorkgroupRepository by lazy { GlobalContext.get().koin.get() }
|
||||
|
||||
@@ -53,7 +54,7 @@ private fun createWorkgroup(
|
||||
description: String? = null,
|
||||
anonymous: Boolean? = null,
|
||||
createdBy: CitizenI.Name? = null,
|
||||
): Workgroup<CitizenBasic> {
|
||||
): WorkgroupForView<CitizenCreator> {
|
||||
val citizenRepository: CitizenRepository by lazy { GlobalContext.get().koin.get() }
|
||||
val workgroupRepository: WorkgroupRepository by lazy { GlobalContext.get().koin.get() }
|
||||
|
||||
@@ -75,12 +76,12 @@ private fun createWorkgroup(
|
||||
}
|
||||
}
|
||||
|
||||
val workgroup = Workgroup(
|
||||
val workgroup = WorkgroupForUpdate(
|
||||
id = id ?: UUID.randomUUID(),
|
||||
name = name ?: "Les Incoruptible",
|
||||
description = description ?: "La vie est notre jeux",
|
||||
createdBy = creator,
|
||||
anonymous = (anonymous ?: false) == true,
|
||||
anonymous = anonymous ?: false,
|
||||
members = listOf(Member(creator, listOf(MASTER)))
|
||||
)
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ package unit.security
|
||||
import fr.dcproject.common.security.AccessDecision.DENIED
|
||||
import fr.dcproject.common.security.AccessDecision.GRANTED
|
||||
import fr.dcproject.component.auth.User
|
||||
import fr.dcproject.component.auth.UserCreator
|
||||
import fr.dcproject.component.auth.UserI
|
||||
import fr.dcproject.component.citizen.CitizenBasic
|
||||
import fr.dcproject.component.citizen.CitizenCart
|
||||
import fr.dcproject.component.citizen.CitizenCreator
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.component.workgroup.WorkgroupAccessControl
|
||||
import fr.dcproject.component.workgroup.WorkgroupWithMembersI
|
||||
@@ -18,18 +20,16 @@ import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.parallel.Execution
|
||||
import org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT
|
||||
import java.util.UUID
|
||||
import fr.dcproject.component.workgroup.Workgroup as WorkgroupEntity
|
||||
import fr.dcproject.component.workgroup.WorkgroupForView as WorkgroupEntity
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@Execution(CONCURRENT)
|
||||
@Tags(Tag("security"), Tag("unit"))
|
||||
internal class `Workgroup Access Control` {
|
||||
private val tesla = CitizenBasic(
|
||||
user = User(
|
||||
private val tesla = CitizenCreator(
|
||||
user = UserCreator(
|
||||
username = "nicolas-tesla",
|
||||
roles = listOf(UserI.Roles.ROLE_USER)
|
||||
),
|
||||
birthday = DateTime.now(),
|
||||
email = "tesla@best.com",
|
||||
name = CitizenI.Name("Nicolas", "Tesla"),
|
||||
followAnonymous = false
|
||||
|
||||
Reference in New Issue
Block a user